c# rabbitmq 实现

381 阅读2分钟

rabbitmq配置文件

rabbitmq集群配置如下:

<!--rabbitmq 测试-->
    <add key="wms_rabbitmq_address" value="amqp://10.0.0.1:5672/,amqp://10.0.0.2:5672/,amqp://10.0.0.3:5672/"/>
    <add key="wms_rabbitmq_username" value="admin"/>
    <add key="wms_rabbitmq_password" value="admin"/>
    <add key="wms_rabbitmq_virtualhost" value="/"/>
    <add key="wms_consumer_queue" value="test_queue" />
    <add key="wms_push_exchange" value="test_exchange" />
    <add key="wms_push_routingKey" value=""/>

rabbitmq生产端

   private static IConnection rabbitmqConnection;
        private static IModel channel;

        /// <summary>
        /// 推送mq
        /// </summary>
        /// <param name="req"></param>
        /// <returns></returns>
        public int PushWmsRabbitMq(PurchaseCollectReq req)
        {
            Logger.Info("开始推送发货通知单到WMS,billno="+req.billno);
            var jSetting = new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore };
            string json = Newtonsoft.Json.JsonConvert.SerializeObject(req, jSetting);
            PurchaseCollectLog log = new PurchaseCollectLog();
            log.billno=(req.billno);
            log.content = json;            
            log.logtype = (int)PurchaseMqLogEnum.PushWms;
            log.billstate = req.billstate;
            new PurchaseServices().SavePurchaseCollectLog(log);
            
            channel = getChannel();
            var properties = channel.CreateBasicProperties();
            //队列持久化
            properties.Persistent = true;
            byte[] body = Encoding.UTF8.GetBytes(json);
            //发送信息
            channel.BasicPublish(RabbitmqConfig.wms_push_exchange, RabbitmqConfig.wms_push_routingKey, properties, body);            
            Logger.Info("结束推送发货通知单到WMS,billno=" + req.billno);            
            return 1;
        }
        
       private IModel getChannel()
        {
            if (rabbitmqConnection==null|| channel==null||!rabbitmqConnection.IsOpen|| !channel.IsOpen)
            {
                var uri = new Uri(RabbitmqConfig.wms_rabbitmq_address);
                var factory = new ConnectionFactory
                {
                    UserName = RabbitmqConfig.wms_rabbitmq_username,
                    Password = RabbitmqConfig.wms_rabbitmq_password,
                    VirtualHost = RabbitmqConfig.wms_rabbitmq_virtualhost,
                    RequestedHeartbeat = 0,
                    Endpoint = new AmqpTcpEndpoint(uri)
                };
                rabbitmqConnection = factory.CreateConnection();
                channel = rabbitmqConnection.CreateModel();
            }
            return channel;
        }

        private void disposeChannel()
        {
            if (rabbitmqConnection == null || channel == null || !rabbitmqConnection.IsOpen || !channel.IsOpen)
            {
                rabbitmqConnection.Dispose();
                channel.Dispose();
            }
        }

rabbitmq消费端

1.用控制台程序运行,挂载在windows服务上

关键参数

AutomaticRecoveryEnabled 开启connection端开重连
channel.BasicQos(0, 10, false); 设置prefetchCount 一次预取10个消息,处理完后,再次取消息
channel.BasicConsume(RabbitmqConfig.wms_consumer_queue, false, consumer: consumer); //false为手动应答,true为自动应答
consumer.Received += (model, ea) =>{} 消费端接收数据事件委托


using SCM.Core.Services.mq;
using SCM.Core.Services.purchase;
using RabbitMQ.Client;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Topshelf;
using RabbitMQ.Client.Events;
using System.Threading.Tasks;
using SCM.Core.Domain.purchase;
using SCM.Core.Domain.enums;
using Utilities;

namespace SCM.Consumer
{
    public class Program
    {
        private static log4net.ILog Logger = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);

        static void Main(string[] args)
        {
            Logger.Info("启动 SCM.Consumer服务");
            try
            {
                // 配置和运行宿主服务
                HostFactory.Run(x =>
                {
                    x.Service<Service>(s =>
                    {
                        // 指定服务类型。这里设置为 Service
                        s.ConstructUsing(name => new Service());
                        // 当服务启动后执行什么
                        s.WhenStarted(tc => tc.Start());                        
                        s.WhenStopped(tc => tc.Stop());
                    });

                    // 服务用本地系统账号来运行
                    x.RunAsLocalSystem();
                    x.StartAutomatically();
                    // 服务描述信息
                    x.SetDescription("SCM.rabbitmq消费端");
                    // 服务显示名称
                    x.SetDisplayName("SCM.Consumer");
                    // 服务名称
                    x.SetServiceName("SCM.Consumer");
                });
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex);
            }
            /*
             * window服务安装
             * 1.管理员权限打开cmd命令窗口,在项目所在的Debug目录下,输入命令:SCM.Consumer.exe install
             * 
             * window服务卸载
             * SCM.Consumer.exe uninstall 
             * 
             * 
             */

        }

        public class Service
        {
            public void Start()
            {
                Logger.Info("启动 SCM.Consumer 消息接收");
                ReceiveWms();                
            }
            public void Stop()
            {
                Logger.Info("停止 SCM.Consumer服务");
                Console.WriteLine("服务已停止!");
            }


            PurchaseServices purchaseServices = new PurchaseServices();
            //系统告警通知邮件
            private string systemAlertEmails = System.Configuration.ConfigurationManager.AppSettings["systemAlertEmails"];

            public void ReceiveWms()
            {
                try
                {
                    var uri = new Uri(RabbitmqConfig.wms_rabbitmq_address);
                    var factory = new ConnectionFactory
                    {
                        UserName = RabbitmqConfig.wms_rabbitmq_username,
                        Password = RabbitmqConfig.wms_rabbitmq_password,
                        VirtualHost = RabbitmqConfig.wms_rabbitmq_virtualhost,
                        RequestedHeartbeat = 0,
                        Endpoint = new AmqpTcpEndpoint(uri),
                        AutomaticRecoveryEnabled=true                        

                    };
                    var connection = factory.CreateConnection("SCM.Consumer");
                    var channel = connection.CreateModel();
                    //一次预取10个消息,处理完后,再次取消息
                    channel.BasicQos(0, 10, false);
                    var consumer = new EventingBasicConsumer(channel);
                    //false为手动应答,true为自动应答
                    channel.BasicConsume(RabbitmqConfig.wms_consumer_queue, false, consumer: consumer);
                    consumer.Received += (model, ea) =>
                    {
                        try
                        {
                            var msgBody = Encoding.UTF8.GetString(ea.Body);
                            Console.WriteLine(string.Format("{0},消息内容:{1}", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), msgBody));
                            Logger.Info(msgBody);
                            PurchaseCollectLog log = Newtonsoft.Json.JsonConvert.DeserializeObject<PurchaseCollectLog>(msgBody);
                            log.content = msgBody;
                            log.logtype = (int)PurchaseMqLogEnum.WmsValidResult;
                            //插入日志
                            new PurchaseServices().SavePurchaseCollectLog(log);
                            if (log.checktype < 0)
                            {
                                string title = "推送WMS返回的校验结果失败,billno:" + log.billno + ",checktype:" + log.checktype;
                                Logger.Info(title);
                                ComUtility.SendEmail(title, systemAlertEmails, msgBody, null);
                            }
                            else
                            {
                                if (log.billstate == 0)
                                {
                                    purchaseServices.UpdateWmsMqFlag(log.billno, "F");
                                }
                                else if (log.billstate == 1)
                                {
                                    purchaseServices.UpdateWmsMqFlag(log.billno, "B");
                                }
                            }
                            channel.BasicAck(ea.DeliveryTag, false);
                        }
                        catch (Exception ex)
                        {
                            Console.WriteLine("WMS校验结果消费异常," + ex.Message + " " + ex.Source + " " + ex.TargetSite);
                            Logger.Error("WMS校验结果消费异常", ex);
                        }
                    };
                    Console.WriteLine("按任意值,退出程序");

                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.Message);
                    Logger.Error("WMS校验结果消费异常", ex);
                    string msg = "SCM.Consumer消费程序挂了,请到服务器上查看!"+ex.Message;
                    ComUtility.SendEmail("SCM.Consumer消费程序挂了", systemAlertEmails, "SCM.Consumer消费程序挂了,请到服务器上查看!", null);
                }
            }
        }
    }
}