一、简介

我用过RabbirMQ的发布订阅模式,以及一对一的延迟队列。

1、RabbitMQ的有消息确认机制,消费一条则队列中少一条,也有对应的消费到消息及认为是消费成功这样的模式,一般使用前者。

发布订阅我是在处理大量数据的更新及与其他系统有数据来往时使用的。在本地程序处理一条则发送一条到队列,保证本地处理成功并发送到其他系统。

延迟队列这种模式也是在与其他系统有交互并且在我这边系统接到成功后必须不马上发给其他的系统,如果在多少时间内本地没有接到说不发的指令才有延迟队列转发到其他系统。

安装部署简介及可视化页面:

https://www.cnblogs.com/Leo_wl/p/5402125.html

2、在c#中的使用

NuGet引用:RabbitMQ.Client

2.1 发布消息

2.1 .1发布订阅

public static void PublishMsgString(IConnection conn, string message, PublishMsgModel model, IDictionary<string, object> headerDict)

{

try

{

using (var channel = conn.CreateModel())

{

channel.ExchangeDeclare(exchange: model.ExchangeName, type: model.ExchangeType, durable: model.Durable);

channel.QueueDeclare(queue: model.QueueName, durable: model.Durable, exclusive: false, autoDelete: false, arguments: null);

channel.QueueBind(queue: model.QueueName, exchange: model.ExchangeName, routingKey: model.RouteKey);

var properties = channel.CreateBasicProperties();

properties.DeliveryMode = 2;

if (headerDict != null)

{

properties.Headers = headerDict;

properties.ContentType = "text/plain";

properties.ContentEncoding = "UTF-8";

}

//string messageString = JsonConvert.SerializeObject(message);

byte[] body = Encoding.UTF8.GetBytes(message);

channel.ConfirmSelect();

channel.BasicPublish(model.ExchangeName, model.RouteKey, properties, body);

if (channel.WaitForConfirms())

{

Common.WriteLog($"【Success】【发布消息】[MsgType]{model.MsgType}[messsage]{message}成功", "publish", model.QueueName);

}

else

{

Common.WriteLog($"【Error】【发布消息】[MsgType]{model.MsgType}[messsage]{message}失败", "publish", model.QueueName);

}

}

}

catch (Exception ex)

{

Common.WriteLog($"【Error_Ex】【发布消息】[MsgType]{model.MsgType}发布消息异常:{ex.Message}[message]{message}", "publish", model.QueueName);

}

}

2.1.2、延迟队列

public static void PublishExpirationMsgString(string message, PublishMsgModel model, PublishMsgModel modelExpiration, Dictionary<string, object> headerDict, bool isTest)

{

try

{

ConnectionFactory connFactory = new ConnectionFactory()

{

HostName = isTest ? ConfigurationManager.AppSettings["MQ.HostName.Test"] : ConfigurationManager.AppSettings["MQ.HostName"],

UserName = isTest ? ConfigurationManager.AppSettings["MQ.UserName.Test"] : ConfigurationManager.AppSettings["MQ.UserName"],

Password = isTest ? ConfigurationManager.AppSettings["MQ.Password.Test"] : ConfigurationManager.AppSettings["MQ.Password"],

VirtualHost = isTest ? ConfigurationManager.AppSettings["MQ.VirtualHostLog.Test"] : ConfigurationManager.AppSettings["MQ.VirtualHostLog"],

Port = int.Parse(isTest ? ConfigurationManager.AppSettings["MQ.Port.Test"] : ConfigurationManager.AppSettings["MQ.Port"]),

AutomaticRecoveryEnabled = true,

RequestedHeartbeat = 30

};

using (IConnection conn = connFactory.CreateConnection())

{

using (var channel = conn.CreateModel())

{

Dictionary<string, object> dic = new Dictionary<string, object>();

dic.Add("x-expires", 4 * 1000 * 60);

dic.Add("x-message-ttl", 3 * 1000 * 60);//队列上消息过期时间,应小于队列过期时间

dic.Add("x-dead-letter-exchange", model.ExchangeName);//过期消息转向路由

dic.Add("x-dead-letter-routing-key", model.RouteKey);//过期消息转向路由相匹配routingkey

channel.QueueDeclare(queue: modelExpiration.QueueName, durable: modelExpiration.Durable, exclusive: false, autoDelete: false, arguments: dic);

channel.ExchangeDeclare(exchange: modelExpiration.ExchangeName, type: modelExpiration.ExchangeType, durable: modelExpiration.Durable);

channel.QueueBind(queue: modelExpiration.QueueName, exchange: modelExpiration.ExchangeName, routingKey: modelExpiration.RouteKey);

var properties = channel.CreateBasicProperties();

properties.DeliveryMode = 2;

if (headerDict != null)

{

properties.Headers = headerDict;

properties.ContentType = "text/plain";

properties.ContentEncoding = "UTF-8";

}

//string messageString = JsonConvert.SerializeObject(message);

byte[] body = Encoding.UTF8.GetBytes(message);

channel.ConfirmSelect();

// properties.Expiration = (2 * 1000 * 60).ToString();

channel.BasicPublish(modelExpiration.ExchangeName, modelExpiration.RouteKey, properties, body);

if (channel.WaitForConfirms())

{

Common.WriteLog($"【Success】【发布消息】[MsgType]{modelExpiration.MsgType}[messsage]{message}", "publish", modelExpiration.QueueName);

}

else

{

Common.WriteLog($"【Error】【发布消息】[MsgType]{modelExpiration.MsgType}[messsage]{message}失败", "publish", modelExpiration.QueueName);

}

}

}

}

catch (Exception ex)

{

Common.WriteLog($"【Error_Ex】【发布消息】[MsgType]{modelExpiration.MsgType}发布消息异常:{ex.Message}[message]{message}", "publish", modelExpiration.QueueName);

}

}

2.2消费消息

public static string GetConfig(string key)

{

return ConfigurationManager.AppSettings[key];

}

public static bool IsTest

{

get { return (ConfigurationManager.AppSettings["IsTest"] ?? "") == "1"; }

}

private static ConnectionFactory connFactory = new ConnectionFactory()

{

HostName = IsTest ? GetConfig("MQ.HostName.Test") : GetConfig("MQ.HostName"),

UserName = IsTest ? GetConfig("MQ.UserName.Test") : GetConfig("MQ.UserName"),

Password = IsTest ? GetConfig("MQ.Password.Test") : GetConfig("MQ.Password"),

VirtualHost = IsTest ? GetConfig("MQ.VirtualHost.Test") : GetConfig("MQ.VirtualHost"),

Port = int.Parse(IsTest ? GetConfig("MQ.Port.Test") : GetConfig("MQ.Port")),

AutomaticRecoveryEnabled = true,

RequestedHeartbeat = 30

};

private static IConnection conn = connFactory.CreateConnection();

private static IModel channel = conn.CreateModel();

private const string queueAllOrder = "user_order_idex_to_log";

private static EventingBasicConsumer consumerOrder,;

private static void ListenMQ(object queue)

{

string[] queueInfo = (string[])queue;

string queueName = queueInfo[0];

string nowThread = queueInfo[1];

PublishMsgModel model = new PublishMsgModel() { Durable = true, ExchangeName = queueName, ExchangeType = ExchangeType.Direct, QueueName = queueName, RouteKey = queueName, MsgType = "" };

channel.BasicQos(0, 1, false);

channel.QueueDeclare(queue: model.QueueName, durable: model.Durable, exclusive: false, autoDelete: false, arguments: null);

switch (queueName)

{

case queueOrder:

model.MsgType = "test";

consumerOrder = new EventingBasicConsumer(channel);

consumerOrder.Received += ConsumOrderMsg;

channel.BasicConsume(model.QueueName, false, consumerOrder);//消费确认,逐条

break;

}

}

private static void ConsumOrderMsg(object sender, BasicDeliverEventArgs eventArgs)

{

string logName = "order_idex_to_devcenter";

try

{

byte[] body = eventArgs.Body;

if (body != null && body.Length > 0)

{

string message = Encoding.UTF8.GetString(body);

++consumOrderMessageTotalOrder;

string msgType = Encoding.UTF8.GetString((byte[])eventArgs.BasicProperties.Headers["messageType"]),

msgId = Encoding.UTF8.GetString((byte[])eventArgs.BasicProperties.Headers["messageId"]), userId = Encoding.UTF8.GetString((byte[])eventArgs.BasicProperties.Headers["userId"]);

}catch{}

}

RabbitMQ及延时队列的更多相关文章

  1. 基于rabbitMQ 消息延时队列方案 模拟电商超时未支付订单处理场景

    前言 传统处理超时订单 采取定时任务轮训数据库订单,并且批量处理.其弊端也是显而易见的:对服务器.数据库性会有很大的要求,并且当处理大量订单起来会很力不从心,而且实时性也不是特别好 当然传统的手法还可 ...

  2. rabbitMq实现延时队列

    原文:https://my.oschina.net/u/3266761/blog/1926588 rabbitMq是受欢迎的消息中间件之一,相比其他的消息中间件,具有高并发的特性(天生具备高并发高可用 ...

  3. RabbitMq 实现延时队列-Springboot版本

    rabbitmq本身没有实现延时队列,但是可以通过死信队列机制,自己实现延时队列: 原理:当队列中的消息超时成为死信后,会把消息死信重新发送到配置好的交换机中,然后分发到真实的消费队列: 步骤: 1. ...

  4. 【日常摘要】- RabbitMq实现延时队列

    简介 什么是延时队列? 一种带有延迟功能的消息队列 过程: 使用场景 比如存在某个业务场景 发起一个订单,但是处于未支付的状态?如何及时的关闭订单并退还库存? 如何定期检查处于退款订单是否已经成功退款 ...

  5. rabbitmq实现延时队列(死信队列)

    基于队列和基于消息的TTL TTL是time to live 的简称,顾名思义指的是消息的存活时间.rabbitMq可以从两种维度设置消息过期时间,分别是队列和消息本身. 队列消息过期时间-Per-Q ...

  6. Rabbitmq的延时队列的使用

    配置: spring: rabbitmq: addresses: connection-timeout: username: guest password: guest publisher-confi ...

  7. rabbitmq 安装延时队列插件rabbitmq-delayed-message-exchange

    1.下载rabbitmq-delayed-message-exchange(注意版本对应) 链接:https://github.com/rabbitmq/rabbitmq-delayed-messag ...

  8. IOS IAP 自动续订 之 利用rabbitmq延时队列自动轮询检查是否续订成功

    启用针对自动续期订阅的服务器通知: - 官方地址: - https://help.apple.com/app-store-connect/#/dev0067a330b - 相关字段, 相关类型地址:  ...

  9. 面试官:RabbitMQ过期时间设置、死信队列、延时队列怎么设计?

    哈喽!大家好,我是小奇,一位不靠谱的程序员 小奇打算以轻松幽默的对话方式来分享一些技术,如果你觉得通过小奇的文章学到了东西,那就给小奇一个赞吧 文章持续更新 一.前言 RabbitMQ我们经常的使用, ...

随机推荐

  1. python之实现图像的手绘效果

    https://blog.csdn.net/riba2534/article/details/74152285 原图: b: c: d: 最终图:

  2. mysql闪回工具--binlog2sql实践

    DBA或开发人员,有时会误删或者误更新数据,如果是线上环境并且影响较大,就需要能快速回滚.传统恢复方法是利用备份重搭实例,再应用去除错误sql后的binlog来恢复数据.此法费时费力,甚至需要停机维护 ...

  3. Cannot find libcrypto in Ubuntu

    https://stackoverflow.com/questions/13811889/cannot-find-libcrypto-in-ubuntu sudo apt-get install li ...

  4. 解决 docker.io 上拉取 images Get https://registry-1.docker.io/v2/: net/http: TLS handshake timeout

    处理方式 使用如下命令获取 registry-1.docker.io 可用的 ip dig @114.114.114.114 registry-1.docker.io 看到如下输出结果 ; <& ...

  5. SVN签出,回退

    2019独角兽企业重金招聘Python工程师标准>>> yum install -y subversion 安装SVN 签出代码 : [root@test svn]# svn che ...

  6. 通用权限管理系统组件 (GPM - General Permissions Manager)

    有的公司开发人员只那么几个,一个人支撑整个公司所有的IT系统实在有点累,不想自己写权限系统了,自己琢磨不也是要花时间和精力,要为此付出多少时间和汗水阿,细细的皱纹不知要多多少呢,重复建设不是白白浪费生 ...

  7. centos监控web目录www下的文件是否被黑、挂马的脚本

    .检查是否有安装inotify rpm -qa inotify-tools 2.没有先安装epol源 wget -O /etc/yum.repos.d/epel.repo http://mirrors ...

  8. 关于SQL语言,这些你不得不了解!

    一.SQL概述 关系数据库标准语言SQL(结构化查询语言). 结构化查询语言(Structured Query Language)简称SQL,是一种特殊目的的编程语言,是一种数据库查询和程序设计语言, ...

  9. 洛谷2014 选课(树形DP)树形背包问题

    题目描述 在大学里每个学生,为了达到一定的学分,必须从很多课程里选择一些课程来学习,在课程里有些课程必须在某些课程之前学习,如高等数学总是在其它课程之前学习.现在有N门功课,每门课有个学分,每门课有一 ...

  10. [Linux] Hexo 搭建个人博客

    不做笔记出了bug就得重新再看一遍视频 视频来源: https://www.bilibili.com/video/BV1Yb411a7ty?t=75 安装 先安装 nodejs,npm, git 安装 ...