RabbitMQ延时机制

延迟队列

延迟队列——消息进入到队列之后,延迟指定的时间才能被消费者消费

AMQP协议和RabbitMQ队列本身是不支持延迟队列功能的,但是可以通过TTL(Time To Live)特性模拟延迟队列的功能

TTL就是消息的存活时间。RabbitMQ可以分别对队列和消息设置存活时间

  • 在创建队列的时候可以设置队列的存活时间,当消息进入到队列并且在存活时间内没有消费者消费,则此消息就会从当前队列被移除;

  • 创建消息队列没有设置TTL,但是消息设置了TTL,那么当消息的存活时间结束,也会被移除;

  • 当TTL结束之后,我们可以指定将当前队列的消息转存到其他指定的队列

使用延迟队列实现订单支付监控(电商系统下订单后如果超过15分钟未支付就取消订单)

实现流程图:

 

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

创建路由交换机:

 

 

 创建普通队列

 

 

 创建死信队列:

 

 

最后队列绑定:

 

 上代码:

        //延时队列
        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);
                    }
                }
            }
        }
生产者C#代码
        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);
                            }
                        };
                    }
                }
            }
        }
消费者C#代码

 

 

 

posted @ 2020-10-28 16:34  初来乍到的菜鸟  阅读(289)  评论(0)    收藏  举报