• RabbitQueue相关


    private static IConnection Connection = null;
            /// <summary>
            /// 发送消息到指定队列
            /// </summary>
            /// <param name="queueName">队列名称, 如果没有则自动创建</param>
            /// <param name="obj">消息主体,建议使用Json</param>
            /// <param name="TTL">过期时间,到时会转换到不带.TTL的队列中,在那个队列中消费处理</param>
            public static void Send(RabbitQueue queueName, string Suffix, object obj, int TTL = 0)
            {
                try
                {
                    Task.Run(delegate
                    {
                        Config config = new Rabbit.Config();
                        //从队列枚举的描述中获取队列名,并附加队列子名称
                        string QueueName_Receive = config.Rabbit_QueueNameFixed + queueName.GetDesc() + (string.IsNullOrEmpty(Suffix) ? string.Empty : "." + Suffix);
    
                        //判断当前消息是否要延时,如果延时则附加.TTL作为暂存队列
                        string QueueName = QueueName_Receive + (TTL == 0 ? string.Empty : ".TTL");
                        try
                        {
                            //将客户端和连接对象作为全局变量,只有在关闭了之后再重新连接,能有效的提高入站效率
                            if (Connection == null || !Connection.IsOpen) { Connection = Config.InitFactory().CreateConnection(); }
    
                            using (var channel = Connection.CreateModel())
                            {
    
                                //创建一个队列  队列名称
                                bool durable = true;      //设置队列持久化 服务器重启时,该队列依然能够存活 如果使用Exchange转发器,则需要转发器也是支持本地化的
                                bool exclusive = false;   //是否为当前连接的专用队列,在连接断开后,会自动删除该队列,生产环境中应该不会用到
                                bool autodelete = false;  //当没有任何消费者使用时,自动删除该队列, 否,其实无所谓,因为一般下次添加队列或者处理队列的时候都会先创建队列
    
                                #region //设置消息的基本参数 持久化等
                                //设置性能
                                var properties = channel.CreateBasicProperties();
                                //设置消息持久化
                                //需要注意的是,将消息设置为持久化并不能完全保证消息不丢失。
                                //虽然他告诉RabbitMQ将消息保存到磁盘上,但是在RabbitMQ接收到消息和将其保存到磁盘上这之间仍然有一个小的时间窗口。 
                                //RabbitMQ 可能只是将消息保存到了缓存中,并没有将其写入到磁盘上。持久化是不能够一定保证的,但是对于一个简单任务队列来说已经足够。
                                //如果需要消息队列持久化的强保证,可以使用publisher confirms
                                properties.Persistent = true;
                                //1:不持久化 2:持久化 这里指的是消息的持久化,配合channel(durable=true),queue(durable)可以实现,即使服务器宕机,消息仍然保留
                                properties.DeliveryMode = 2;
                                #endregion
    
                                if (TTL == 0)  //如果不需要设置过期 则直接加入队列
                                {
                                    channel.QueueDeclare(QueueName_Receive, durable, exclusive, autodelete, null);
                                }
                                else
                                {
                                    string ExchangeName = QueueName + ".Exchange"; //转发器名称
                                    string RouteKey = QueueName + ".RouteKey"; //转向路由名称
    
                                    //如果要实现过期.. 实现原理是将消息设置过期时间之后放在队列中..而此队列一直没有消费者会去消费.. 让消息过期..变成死信(Dead Letter)
                                    //消息会根据队列上配置的转发器Exchange 来转发消息.. 消息会被推送到其他绑定了此转发器的队列上.. 那个队列有实时消费者..这样就形成了消息的延时处理..延时的时长是灵活设置的
    
    
                                    //需要设置过期..要创建对应的过期结构.
                                    //将消息加入到一个会过期的队列中..本方法中将原队列名后缀加上.TTL.. 实际转发消息队列为枚举获取到的队列名,方便后期消费处理
                                    //可以在队列上设置过期时间,参数名:x-message-ttl 单位毫秒 在下方的键值对Dic中设置
                                    //也可以在消息上设置过期时间..更下方的properties 的 Expiration 属性..单位也是毫秒 在消息上设置过期时间更加灵活.. 消息会比较多个过期时间取最小值
    
    
                                    //此处需要注意的是
                                    Dictionary<string, object> dic = new Dictionary<string, object>();
                                    dic.Add("x-dead-letter-exchange", ExchangeName);//过期消息转发器
                                    dic.Add("x-dead-letter-routing-key", RouteKey);//过期消息转向路由相匹配routingkey
    
                                    //创建ExChange转发器
                                    //设置转发器也是可以本地化  不自动删除的
                                    channel.ExchangeDeclare(exchange: ExchangeName, type: "direct", durable: true, autoDelete: false, arguments: null);
                                    //声明虚假队列 此队列没有消费端 会按消息上设置的时间过期
                                    channel.QueueDeclare(QueueName, durable, exclusive, autodelete, dic);
                                    //通过当前 Channel 绑定QueryName Exchange  和 routingKey
                                    channel.QueueBind(QueueName, ExchangeName, RouteKey);
    
                                    //声明真实的队列
                                    channel.QueueDeclare(QueueName_Receive, durable, exclusive, autodelete, null);
                                    channel.QueueBind(QueueName_Receive, ExchangeName, RouteKey);
    
    
                                    //设置消息的过期时间
                                    properties.Expiration = TTL.ToString();
                                }
                                //内容
                                channel.BasicPublish("", QueueName, false, properties, obj.ToJson().ToBytes(Encoding.UTF8));
                            }
                        }
                        catch (System.Exception ex)
                        {
                            Console.WriteLine(ex);
                            Console.WriteLine("{0} - {1} - {2} - {3}", DateTime.Now.Format_yyyyMMddHHmmssfff(), QueueName, ex.Message, obj.ToJson());
                        }
                    });
                }
                catch (System.Exception ex)
                {
                    System.Console.WriteLine(ex);
                }
    
            }
  • 相关阅读:
    数据结构-图
    web.xml的运行顺序
    如何把自己打造成技术圈的 papi 酱
    也谈http中get和post
    手机充电速度及电池使用
    web项目Log4j日志输出路径配置问题
    JAVA模块化
    关于web安全
    Struts2中通配符
    2016第14周一
  • 原文地址:https://www.cnblogs.com/dujian123/p/11763405.html
Copyright © 2020-2023  润新知