Rabbit使用CorrelationId进行可靠性消息回调
先放一张使用CorrelationId相关ID进行消息回调处理的流程图

- 客户端启动时,它将创建一个匿名回调队列
- 对于 RPC 请求,客户端发送一条消息,该消息具有两个属性: reply_to(设置为回调队列)和 correlation_id(设置为每个请求的唯一值)
- 该请求被发送到 rpc_queue 队列
- RPC 工作程序等待该队列上的请求,出现请求时,它将使用 reply_to 字段中的队列来完成工作,并将消息和结果发送回客户端
- 客户端等待回调队列上的数据,出现消息时,它将检查 correlation_id 属性。 如果它与请求中的值匹配,则将响应返回给应用程序(TODO)
发送回调
public void SendCallback<T>(string topic, T value, Action<byte[]> callback, byte priority = 1)
{
EnsureDeclare(topic);
var replyQueue = _model.QueueDeclare().QueueName;
var props = _model.CreateBasicProperties();
props.Priority = priority;
props.ReplyTo = replyQueue;
var correlationId = Guid.NewGuid().ToString("N");
props.CorrelationId = correlationId; //发布消息
_model.BasicPublish(_exchange, topic, props, value.GetBuf()); //创建消费者用于消息回调
var callbackConsumer = new EventingBasicConsumer(_model);
_model.BasicConsume(queue: replyQueue, autoAck: true, consumer: callbackConsumer); callbackConsumer.Received += (model, ea) =>
{
if (ea.BasicProperties.CorrelationId == correlationId)
callback(ea.Body);
};
}
消息接收,在接受消息后,通过ReplyTo来进行消息回执
public void SetReceiveCallback(string topic, Action<byte[], IBasicProperties> received)
{
EnsureDeclare(topic);
var consumer = new EventingBasicConsumer(_model);
consumer.Received += (model, ea) =>
{
var properties = ea.BasicProperties;
var replyProerties = _model.CreateBasicProperties();
replyProerties.CorrelationId = properties.CorrelationId;
replyProerties.ReplyTo = properties.ReplyTo;
received(ea.Body, replyProerties);
_model.BasicAck(ea.DeliveryTag, false);
};
_model.BasicConsume(topic, false, consumer);
}
单元测试代码
[Order(1)]
public class RabbitCallbackTest
{
[Fact, Order(1)]
public void ServerCallback()
{
_rabbitSvr = new Aster.Itms.Core.Data.Provider.Rabbit(new Connection()
{
Ip = "localhost",
Port = 5672,
User = "guest",
Password = "guest"
}, ""); _rabbitSvr.SetReceiveCallback("topic", ServerReceiveCommand);
} private static volatile Aster.Itms.Core.Data.Provider.Rabbit _rabbitSvr;
[Fact, Order(2)]
public void ClientCallback()
{
var _rabbitSvr = new Aster.Itms.Core.Data.Provider.Rabbit(new Connection()
{
Ip = "localhost",
Port = 5672,
User = "guest",
Password = "guest"
}, ""); string val = $"发送消息{Guid.NewGuid().ToString("N")}"; _rabbitSvr.SendCallback<string>("topic", val, ClientReceiveCommand, 1);
} private static void ClientReceiveCommand(byte[] body)
{
var result = body.To<string>(); //拿到结果再发送回去 Console.WriteLine($"接收服务端返回消息:{result}"); Assert.NotEmpty(result);
} private static void ServerReceiveCommand(byte[] body, IBasicProperties replyProps)
{
var result = body.To<string>(); Assert.NotEmpty(result); Console.WriteLine($"服务端接收:{result},CorrelationId:{replyProps.CorrelationId}"); int.TryParse(result, out int newResult); if (!string.IsNullOrEmpty(replyProps.ReplyTo))
_rabbitSvr.Send(replyProps.ReplyTo, $"{Convert.ToInt32(newResult) + 1000}", replyProps);
}
}
Rabbit使用CorrelationId进行可靠性消息回调的更多相关文章
- 2.RabbitMQ 的可靠性消息的发送
本篇包含 1. RabbitMQ 的可靠性消息的发送 2. RabbitMQ 集群的原理与高可用架构的搭建 3. RabbitMQ 的实践经验 上篇包含 1.MQ 的本质,MQ 的作用 2.R ...
- 终于懂了:Delphi消息的Result域出现的原因——要代替回调函数的返回值!(MakeObjectInstance不会帮助处理(接收)消息回调函数的返回值)
MakeObjectInstance应该不会帮助处理(接收)消息回调函数的返回值,可是有时候又确实需要这个返回值,这可怎么办呢?我是看到这段文字的时候,想到这个问题的: 当WM_PAINT不是由Inv ...
- Rabbit MQ 怎么保证可靠性、幂等性、消费顺序?
RabbitMQ如何保证消息的可靠性 RabbitMQ消息丢失的三种情况 生产者弄丢消息时的解决方法 方法一:生产者在发送数据之前开启RabbitMQ的事务(采用该种方法由于事务机制,会导致吞吐量下降 ...
- Rabbit mq订阅方式获取消息并可设置持久化
Rabbit 通过方式获取消息:订阅方式事实上是向queue注冊consumer,通过rpc向queue server发送注冊consumer的消息.rabbitMQ Server在收到消息后,依据消 ...
- 【mq读书笔记】客户端处理消息(回调提交到异步业务线程池,pullRequest重新入队)
看一下客户端收到消息后的处理: MQClientAPIImpl#processPullResponse private PullResult processPullResponse( final Re ...
- 理解Storm可靠性消息
看过一些别人写的, 感觉有些东西没太说清楚,个人主要以源代码跟踪,参考个人理解讲述,有错误请指正. 1基本名词 1.1 Tuple: 消息传递的基本单位.很多文章中介绍都是这么说的, 个人觉得应该更详 ...
- Spring Boot and Rabbit MQ 异常的时候消息的状态
我们有一个处理消息的方法. 在处理消息的时候出现了异常,那出现异常后这个消息会怎么处理呢. 根据我们的实际情况的观察,如果出现了异常. 但是你没有捕获或者处理异常,这个消息会一直存在,并且你的系统会持 ...
- 专门用于消息回调窗口的窗口标识HWND_MESSAGE(创建一个非可视、没有z-order的窗口)
HWND_MESSAGE Message-Only Windows A message-only window enables you to send and receive messages. It ...
- Rabbit MQ 消息确认和持久化机制
一:确认种类 RabbitMQ的消息确认有两种.一种是消息发送确认,用来确认生产者将消息发送给交换器,交换器传递给队列的过程中消息是否成功投递.发送确认分为两步,一是确认是否到达交换器,二是确认是否到 ...
- RabbitMQ消息可靠性分析
消息中间件的可靠性是指对消息不丢失的保障程度:而消息中间件的可用性是指无故障运行的时间百分比,通常用几个 9 来衡量.不存在绝对的可靠性只能尽量趋向完美.并且通常可靠性也意味着影响性能和付出更大的成本 ...
随机推荐
- 如何写RN样式 如何写RN组件 如何满屏 如何使用变量
app.js 文本水平居中了哈 控制文本的大小 字体颜色等 只有在文本元素上去控制哈 import React from 'react'; import {View, Text, StyleSheet ...
- 【发现一个问题】extjs-gpl-7.0: 当修改 store 对象的字段后,再次 loadPage() 后字段映射错误。
作者:张富春(ahfuzhang),转载时请注明作者和引用链接,谢谢! cnblogs博客 zhihu Github 公众号:一本正经的瞎扯 因为查询中需要每次返回数目不确定的 fields ,这就需 ...
- Mysql 8.0前后,实现创建用户,指定用户只能访问指定的数据库中的表
最近在做公司项目的过程中,出现了这样的需求.第三方系统需要将数据写到我们的业务系统中,由于目前这些数据没有实际的使用场景,在讨论下,为简单快捷,选择第二种方案,即不书写接口,第三方系统通过数据库直接将 ...
- 强化学习从基础到进阶-案例与实践[4.1]:深度Q网络-DQN项目实战CartPole-v0
强化学习从基础到进阶-案例与实践[4.1]:深度Q网络-DQN项目实战CartPole-v0 1.定义算法 相比于Q learning,DQN本质上是为了适应更为复杂的环境,并且经过不断的改良迭代,到 ...
- python实现GUI自动化(控制鼠标)|屏幕快照&图像识别基础
1.GUI自动化 ●GUI自动化就是写程序直接控制键盘和鼠标.这些程序可以控制其他应用,向它们发送虚拟的击键和鼠标点击,就像你自己坐在计算机前与应用交互-样.这种技术被称为"图形用户界面自动 ...
- 【二】AI Studio 项目详解【VisualDL工具、(二)环境使用说明、(二)脚本任务、图形化任务、在线部署及预测】PARL
相关文章 [一]-环境配置+python入门教学 [二]-Parl基础命令 [三]-Notebook.&pdb.ipdb 调试 [四]-强化学习入门简介 [五]-Sarsa&Qlear ...
- 【6】opencv采用映射技术实现鱼眼镜头校正和鱼眼镜头还原全景图。
相关文章: [1]windows下安装OpenCV(4.3)+VS2017安装+opencv_contrib4.3.0配置 [2]Visual Studio 2017同时配置OpenCV2.4 以及O ...
- 将Windows系统设置为NTP服务器
环境 Windows 10,本机IP地址为:192.168.6.133 步骤 一.编辑注册表 win+r快捷键打开运行窗口,输入regedit打开注册表编辑器,找到以下几项并修改其值: 1.将type ...
- .net 工具箱不可用/怎样初始化vs环境 解决方案
在开始菜单里面执行的.开始菜单->Microsoft Visual Studio 2005->Visual Studio Tools->Visual Studio 2005 命令提示 ...
- P4145 上帝造题的七分钟 2 / 花神游历各国 题解
题目链接:上帝造题的七分钟2/花神游历各国 差不多的题:[Ynoi Easy Round 2023] TEST_69 注意到对某个点来说暴力单点即为反复的:\(x=\sqrt{x}\),最终为 \(1 ...