首先需要安装Erlang和Rabbitmq
Erlang下载地址:https://www.erlang.org/downloads
rabbitmq下载地址:https://www.rabbitmq.com/install-windows.html
安装成功后需要切换到Rabbitmq目录下执行如下命令配置Rabbitmq:
rabbitmq-plugins.bat enable rabbitmq_management
然后可在浏览器中输入地址http://localhost:15672/进行服务端配置;
操作代码如下:
/// <summary> /// 消费者(消息) /// </summary> public class CustmerMq { /// <summary> /// 最大的队列数目 根据cpu 来 /// </summary> private static int Maximum_number_queues = 2; private static int number = 0; /// <summary> /// 消费者(单个) /// </summary> /// <param name="url">RabbitMQ地址</param> /// <param name="userName">登录名</param> /// <param name="passWord">密码</param> /// <param name="virtualHost">虚拟主机</param> /// <param name="requestedHeartbeat">请求心跳,默认0</param> /// <param name="queueName">队列名称</param> /// <returns></returns> public static string InitCustmerMqStr(string url, string userName, string passWord, string virtualHost, ushort requestedHeartbeat, string queueName) { var strMQ = string.Empty; try { Uri uri = new Uri(url);//"amqp://172.16.11.148:5672/" //使用ConnectionFactory创建连接,虽然创建时指定了多个server address,但每个connection只与一个物理的server进行连接 ConnectionFactory cf = new ConnectionFactory(); cf.Endpoint = new AmqpTcpEndpoint(uri); cf.UserName = userName; //"rollen"; cf.Password = passWord; //"root"; cf.VirtualHost = virtualHost; //"/"; cf.RequestedHeartbeat = requestedHeartbeat; //0; using (IConnection conn = cf.CreateConnection()) { using (IModel ch = conn.CreateModel()) { //普通使用方式BasicGet //noAck = true,不需要回复,接收到消息后,queue上的消息就会清除 //noAck = false,需要回复,接收到消息后,queue上的消息不会被清除,直到调用channel.basicAck(deliveryTag, false); queue上的消息才会被清除 而且,在当前连接断开以前,其它客户端将不能收到此queue上的消息 BasicGetResult res = ch.BasicGet(queueName, false/*noAck*/); if (res != null) { bool t = res.Redelivered; t = true; strMQ = System.Text.UTF8Encoding.UTF8.GetString(res.Body); ch.BasicAck(res.DeliveryTag, false); } } } } catch (Exception ex) { Logger.Debug("RabbitMQ消费异常:" + ex.Message); } return strMQ; } /// <summary> /// 消费者(遍历) /// </summary> /// <returns></returns> public static object InitCustmerMqListT() { var url = ConfigurationManager.AppSettings["MQ_url_loan"]; var userName = ConfigurationManager.AppSettings["MQ_userName_loan"]; var passWord = ConfigurationManager.AppSettings["MQ_passWord_loan"]; var virtualHost = ConfigurationManager.AppSettings["MQ_virtualHost_loan"]; var requestedHeartbeat = ushort.Parse(ConfigurationManager.AppSettings["MQ_requestedHeartbeat_loan"] ?? "0"); var queueName = ConfigurationManager.AppSettings["MQ_queueName_loan"]; return InitCustmerMqLists(url, userName, passWord, virtualHost, requestedHeartbeat, queueName); } private static List<string> InitCustmerMqLists(string url, string userName, string passWord, string virtualHost, ushort requestedHeartbeat, string queueName) { var DeliveryTagList = new List<ulong>(); var list = new List<string>(); try { Uri uri = new Uri(url);//使用ConnectionFactory创建连接,虽然创建时指定了多个server address,但每个connection只与一个物理的server进行连接 ConnectionFactory cf = new ConnectionFactory(); cf.Endpoint = new AmqpTcpEndpoint(uri); cf.UserName = userName; //"rollen"; cf.Password = passWord; //"root"; cf.VirtualHost = virtualHost; //"/"; cf.RequestedHeartbeat = requestedHeartbeat; //0; int ErrorSum = 0; using (IConnection conn = cf.CreateConnection()) { using (IModel ch = conn.CreateModel()) { #region 清除队列消息 //var consumer = new QueueingBasicConsumer(ch); //ch.BasicConsume(queueName, noAck: true, consumer: consumer); //var msgResponse = consumer.Queue.Dequeue(); //blocking //ch.BasicAck(msgResponse.DeliveryTag, false); #endregion //ch.BasicQos(0, 1, false);//这样RabbitMQ就会使得每个Consumer在同一个时间点最多处理一个Message。换句话说,在接收到该Consumer的ack前,他它不会将新的Message分发给它。 #region 遍历消息队列获取消息 int k = 0; while (k < 20000) { BasicGetResult res = ch.BasicGet(queueName, false/*noAck*/); if (res != null) { try { var body = System.Text.UTF8Encoding.UTF8.GetString(res.Body); list.Add(body); DeliveryTagList.Add(res.DeliveryTag); } catch (Exception ex) { Logger.Debug("RabbitMQ消费异常:" + ex.Message); if (ErrorSum >= 3) { break; } ErrorSum++; } } else { break; } k++; } #endregion #region 消费完成,删除队列 try { if (DeliveryTagList != null && DeliveryTagList.Count > 0 ) { for (int i = 0; i < DeliveryTagList.Count; i++) { ch.BasicAck(DeliveryTagList[i], false); } } } catch (Exception ex) { Logger.Debug("RabbitMQ消费异常:" + ex.Message); } #endregion ch.Close(); } conn.Close(); } } catch (Exception ex) { Logger.Debug("RabbitMQ消费异常:" + ex.Message); } return list; } }
/// <summary> /// 产生消息 /// </summary> public class ProducerMQ { /// <summary> /// 消息添加入队列 /// </summary> /// <param name="str">消息内容</param> /// <param name="url">消息队列服务器地址</param> /// <param name="exchange">交换方式名称</param> /// <param name="exchangeType">方式类型</param> /// <param name="routingKey">方式Key</param> /// <param name="userName">登录名称</param> /// <param name="passWord">密码</param> /// <param name="virtualHost">虚拟主机名</param> /// <param name="requestedHeartbeat">请求心跳,默认0</param> /// <param name="queueName">队列名称</param> public static void InitProducerMQ(string str, string url, string exchange, string exchangeType, string routingKey, string userName, string passWord, string virtualHost, ushort requestedHeartbeat, string queueName) { //定义要链接的rabbitmq-server地址(基于amqp协议) //Uri uri = new Uri("amqp://172.16.11.148:5672/"); Uri uri = new Uri(url); //定义交换方式
//是否对消息队列持久化保存 bool persistMode = true; //使用ConnectionFactory创建连接,虽然创建时指定了多个server address,但每个connection只与一个物理的server进行连接 ConnectionFactory cf = new ConnectionFactory(); cf.UserName = userName; cf.Password = passWord; //cf.VirtualHost = "/"; cf.VirtualHost = virtualHost; cf.RequestedHeartbeat = requestedHeartbeat; cf.Endpoint = new AmqpTcpEndpoint(uri); //实例化IConnection对象,并设置交换方式 using (IConnection conn = cf.CreateConnection()) { using (IModel ch = conn.CreateModel()) { if (exchangeType != null) { //交换机持久化 ch.ExchangeDeclare(exchange, exchangeType, true);//,true,true,false,false, true,null); ////队列持久化 ch.QueueDeclare(queueName, true, false, false, null); //ch.QueueBind("q2", "ex2", "m1"); ch.QueueBind(queueName, exchange, routingKey); } //构造消息实体对象并发布到消息队列上 IMapMessageBuilder b = new MapMessageBuilder(ch); if (persistMode) { //数据持久化 ((IBasicProperties)b.GetContentHeader()).DeliveryMode = 2; } ////简单发布方式 ch.BasicPublish(exchange, routingKey, (IBasicProperties)b.GetContentHeader(), Encoding.UTF8.GetBytes(str)); ch.Close(); } conn.Close(); } } /// <summary> /// 消息添加入队列 /// </summary> /// <param name="model">消息内容</param> public static void InitProducerMQ(object model) { try { var Is_RabbitMQ = ConfigurationManager.AppSettings["Is_RabbitMQ"] == null ? 0 : Convert.ToInt32(ConfigurationManager.AppSettings["Is_RabbitMQ"].ToString());//是否开启队列 if (Is_RabbitMQ == 1) { var url = ConfigurationManager.AppSettings["RabbitMQ_url"] == null ? "amqp://172.16.5.180:5672/" : ConfigurationManager.AppSettings["RabbitMQ_url"].ToString();//消息队列服务器地址 var exchange = ConfigurationManager.AppSettings["RabbitMQ_exchange"] == null ? "WebApi" : ConfigurationManager.AppSettings["RabbitMQ_exchange"].ToString();//交换方式名称 var exchangeType = ConfigurationManager.AppSettings["RabbitMQ_exchangeType"] == null ? "direct" : ConfigurationManager.AppSettings["RabbitMQ_exchangeType"].ToString();//方式类型 var routingKey = ConfigurationManager.AppSettings["RabbitMQ_routingKey"] == null ? "XYJAPP" : ConfigurationManager.AppSettings["RabbitMQ_routingKey"].ToString();//方式Key var userName = ConfigurationManager.AppSettings["RabbitMQ_userName"] == null ? "rollen" : ConfigurationManager.AppSettings["RabbitMQ_userName"].ToString();//登录名称 var passWord = ConfigurationManager.AppSettings["RabbitMQ_passWord"] == null ? "123456" : ConfigurationManager.AppSettings["RabbitMQ_passWord"].ToString();//密码 var virtualHost = ConfigurationManager.AppSettings["RabbitMQ_virtualHost"] == null ? "/" : ConfigurationManager.AppSettings["RabbitMQ_virtualHost"].ToString();//虚拟主机名 ushort requestedHeartbeat = ConfigurationManager.AppSettings["RabbitMQ_requestedHeartbeat"] == null ? ushort.Parse("0") : Convert.ToUInt16(ConfigurationManager.AppSettings["RabbitMQ_requestedHeartbeat"].ToString());//请求心跳,默认0 var queueName = ConfigurationManager.AppSettings["RabbitMQ_queueName"] == null ? "APP" : ConfigurationManager.AppSettings["RabbitMQ_queueName"].ToString();//队列名称 var str = JsonConvert.SerializeObject(model); if (!string.IsNullOrWhiteSpace(str)) { InitProducerMQ(str, url, exchange, exchangeType, routingKey, userName, passWord, virtualHost, requestedHeartbeat, queueName); } } } catch (Exception ex) { //Logger.Error("ProducerMQ", ex); } } /// <summary> /// 消息添加入队列 /// </summary> /// <param name="str">消息内容</param> public static void InitProducerMQ(string str) { try { var Is_RabbitMQ = ConfigurationManager.AppSettings["Is_RabbitMQ"] == null ? 0 : Convert.ToInt32(ConfigurationManager.AppSettings["Is_RabbitMQ"].ToString());//是否开启队列 if (Is_RabbitMQ == 1) { var url = ConfigurationManager.AppSettings["RabbitMQ_url"] == null ? "amqp://172.16.5.180:5672/" : ConfigurationManager.AppSettings["RabbitMQ_url"].ToString();//消息队列服务器地址 var exchange = ConfigurationManager.AppSettings["RabbitMQ_exchange"] == null ? "WebApi" : ConfigurationManager.AppSettings["RabbitMQ_exchange"].ToString();//交换方式名称 var exchangeType = ConfigurationManager.AppSettings["RabbitMQ_exchangeType"] == null ? "direct" : ConfigurationManager.AppSettings["RabbitMQ_exchangeType"].ToString();//方式类型 var routingKey = ConfigurationManager.AppSettings["RabbitMQ_routingKey"] == null ? "XYJAPP" : ConfigurationManager.AppSettings["RabbitMQ_routingKey"].ToString();//方式Key var userName = ConfigurationManager.AppSettings["RabbitMQ_userName"] == null ? "rollen" : ConfigurationManager.AppSettings["RabbitMQ_userName"].ToString();//登录名称 var passWord = ConfigurationManager.AppSettings["RabbitMQ_passWord"] == null ? "123456" : ConfigurationManager.AppSettings["RabbitMQ_passWord"].ToString();//密码 var virtualHost = ConfigurationManager.AppSettings["RabbitMQ_virtualHost"] == null ? "/" : ConfigurationManager.AppSettings["RabbitMQ_virtualHost"].ToString();//虚拟主机名 ushort requestedHeartbeat = ConfigurationManager.AppSettings["RabbitMQ_requestedHeartbeat"] == null ? ushort.Parse("0") : Convert.ToUInt16(ConfigurationManager.AppSettings["RabbitMQ_requestedHeartbeat"].ToString());//请求心跳,默认0 var queueName = ConfigurationManager.AppSettings["RabbitMQ_queueName"] == null ? "APP" : ConfigurationManager.AppSettings["RabbitMQ_queueName"].ToString();//队列名称 if (!string.IsNullOrWhiteSpace(str)) { InitProducerMQ(str, url, exchange, exchangeType, routingKey, userName, passWord, virtualHost, requestedHeartbeat, queueName); } } } catch (Exception ex) { //Logger.Error("ProducerMQ", ex); } } /// <summary> /// 添加入账内容进入队列 /// </summary> /// <param name="model">消息内容</param> public static void InitProducerLoanMQ(object model) { try { var Is_MQ = ConfigurationManager.AppSettings["Is_MQ_loan"] == null ? 0 : Convert.ToInt32(ConfigurationManager.AppSettings["Is_MQ_loan"].ToString());//是否开启队列 if (Is_MQ == 1) { var url = ConfigurationManager.AppSettings["MQ_url_loan"] == null ? "amqp://172.16.5.180:5672/" : ConfigurationManager.AppSettings["MQ_url_loan"].ToString();//消息队列服务器地址 var exchange = ConfigurationManager.AppSettings["MQ_exchange_loan"] == null ? "WebApi" : ConfigurationManager.AppSettings["MQ_exchange_loan"].ToString();//交换方式名称 var exchangeType = ConfigurationManager.AppSettings["MQ_exchangeType_loan"] == null ? "direct" : ConfigurationManager.AppSettings["MQ_exchangeType_loan"].ToString();//方式类型 var routingKey = ConfigurationManager.AppSettings["MQ_routingKey_loan"] == null ? "XYJAPP" : ConfigurationManager.AppSettings["MQ_routingKey_loan"].ToString();//方式Key var userName = ConfigurationManager.AppSettings["MQ_userName_loan"] == null ? "rollen" : ConfigurationManager.AppSettings["MQ_userName_loan"].ToString();//登录名称 var passWord = ConfigurationManager.AppSettings["MQ_passWord_loan"] == null ? "123456" : ConfigurationManager.AppSettings["MQ_passWord_loan"].ToString();//密码 var virtualHost = ConfigurationManager.AppSettings["MQ_virtualHost_loan"] == null ? "/" : ConfigurationManager.AppSettings["MQ_virtualHost_loan"].ToString();//虚拟主机名 ushort requestedHeartbeat = ConfigurationManager.AppSettings["MQ_requestedHeartbeat_loan"] == null ? ushort.Parse("0") : Convert.ToUInt16(ConfigurationManager.AppSettings["MQ_requestedHeartbeat_loan"].ToString());//请求心跳,默认0 var queueName = ConfigurationManager.AppSettings["MQ_queueName_loan"] == null ? "APP" : ConfigurationManager.AppSettings["MQ_queueName_loan"].ToString();//队列名称 var str = JsonConvert.SerializeObject(model); if (!string.IsNullOrWhiteSpace(str)) { InitProducerMQ(str, url, exchange, exchangeType, routingKey, userName, passWord, virtualHost, requestedHeartbeat, queueName); } } } catch (Exception ex) { //Logger.Error("ProducerMQ", ex); } } }
以上为MQ生产者和消费者代码,引用以上代码必须添加引用RabbitMQ.Client.dll