RabbitMQ延时机制
延迟队列
延迟队列——消息进入到队列之后,延迟指定的时间才能被消费者消费
AMQP协议和RabbitMQ队列本身是不支持延迟队列功能的,但是可以通过TTL(Time To Live)特性模拟延迟队列的功能
TTL就是消息的存活时间。RabbitMQ可以分别对队列和消息设置存活时间

-
-
创建消息队列没有设置TTL,但是消息设置了TTL,那么当消息的存活时间结束,也会被移除;
-
实现流程图:

下面介绍下如何配置创建交换机和队列:
创建路由交换机:

创建普通队列:

创建死信队列:

最后队列绑定:

上代码:
//延时队列 public static void direct_delay() { string exchangeName = "delay_exchange";//交换机名称 string qName = "delay_queue1"; ConnectionFactory factory = new ConnectionFactory(); factory.HostName = "localhost";//主机名,Rabbit会拿这个IP生成一个endpoint,这个很熟悉吧,就是socket绑定的那个终结点。 factory.VirtualHost = "host1"; factory.UserName = "guest";//默认用户名,用户可以在服务端自定义创建,有相关命令行 factory.Password = "guest";//默认密码 //建立连接 using (var connection = factory.CreateConnection()) { //创建通道 using (var channel = connection.CreateModel()) { Dictionary<string, object> dic = new Dictionary<string, object>(); //dic.Add("x-expires", 30000); dic.Add("x-message-ttl", 10000);//队列上消息过期时间,应小于队列过期时间 dic.Add("x-dead-letter-exchange", "delay_exchange");//过期消息转向路由 dic.Add("x-dead-letter-routing-key", "k2");//过期消息转向路由相匹配routingkey while (true) { //channel.ExchangeDeclare(exchange: exchangeName, type: "direct", durable: true, autoDelete: false, arguments: null); channel.QueueDeclare(queue: qName, durable: true, exclusive: false, autoDelete: false, arguments: dic); //channel.QueueBind(qName, exchangeName, "k2", null); var properties = channel.CreateBasicProperties(); properties.Persistent = true; DateTime dateTime = DateTime.Now; byte[] body = Encoding.UTF8.GetBytes($"当前时间:{dateTime}"); channel.BasicPublish(exchange: "", routingKey: qName, basicProperties: properties, body: body); Console.WriteLine(dateTime); Thread.Sleep(1000); } } } }
public static void Reception_Delay() { var factory = new ConnectionFactory(); factory.HostName = "localhost";//主机名,Rabbit会拿这个IP生成一个endpoint,这个很熟悉吧,就是socket绑定的那个终结点。 factory.VirtualHost = "host1"; factory.UserName = "guest";//默认用户名,用户可以在服务端自定义创建,有相关命令行 factory.Password = "guest";//默认密码 //建立连接 using (var connection = factory.CreateConnection()) { //创建通道 using (var channel = connection.CreateModel()) { while (true) { string qName = "delay_queue2"; channel.QueueDeclare(qName, true, false, false, null); //定义这个队列的消费者 var consumer = new EventingBasicConsumer(channel); //false为手动应答,true为自动应答 channel.BasicConsume(qName, false, consumer); consumer.Received += (model, ea) => { string message = Encoding.UTF8.GetString(ea.Body.ToArray()); Console.WriteLine("接收:" + message); if (!string.IsNullOrEmpty(message)) { //如果是自动应答,下下面这句代码不用写啦。 channel.BasicAck(deliveryTag: ea.DeliveryTag, multiple: false); } }; } } } }

浙公网安备 33010602011771号