十年河东,十年河西,莫欺少年穷
学无止境,精益求精
先盗用一张图,介绍下RabbitMQ的架构图
简介Producer : 生产者
channel : 通信信道,节约Tcp链接资源
Broker : MQ Server接点,做集群用的
VirtualHost : 虚拟机,一个RabbitMQ中可以有多个虚拟机,我们可以通过RabbitMQ提供的可视化网站中创建,虚拟机中可以有多个队列,可以将虚拟机分配不同的用户角色
Exchange : 交换机 ,代码中可以不指定交换机,不指定交换机时,交换机名称要和队列名称一致。
Queue : 消息队列
Consumer : 消费者
生产者
关于RabbitMQ的安装请参考:windows环境下,RabbitMQ 安装教程
1、新建一个控制台程序,Nuget引入RabbitMQ.Client
2、创建如下生产者程序
using RabbitMQ.Client; using System; using System.Collections.Generic; using System.Text; namespace RabbitMqProducer { class Program { static void Main(string[] args) { ConnectionFactory factory = new ConnectionFactory(); factory.HostName = "127.0.0.1"; //主机名 factory.UserName = "guest";//使用的用户 factory.Password = "guest";//用户密码 factory.Port = 15672;//端口号 factory.VirtualHost = "/"; //虚拟主机 factory.MaxMessageSize = 1024; //消息最大字节数 using (var connection = factory.CreateConnection())//连接服务器,即正在创建终结点。 { //rabbitMQ 基于信道进行通信,因此,我们需要实例化信道Channel using (var channel = connection.CreateModel()) { //queue : 队列名称 //durable : 是否持久化消息,如果设置为true 则会将详细存储在磁盘中 //exclusive : 是否设置为独占队列,意思是指只能有一个消费者,设置为false,可以有多个消费者同时消费 //autoDelete : 是否是临时队列,临时队列会随着消费者断开连接时自动删除 //arguments : arguments 里面有很多属性可以设置,例如队列过期时间等 //QueueDeclareOk QueueDeclare(string queue, bool durable, bool exclusive, bool autoDelete, IDictionary<string, object> arguments); Dictionary<string, object> arguments = new Dictionary<string, object>(); arguments.Add("x-expires", 45 * 1000); // 队列在一定时间内没被使用,则删除 arguments.Add("x-message-ttl", 45 * 1000);//队列中消息的存活1时间 channel.QueueDeclare("RabbitMQ", false, false, false, arguments);//创建一个名称为kibaqueue的消息队列 var properties = channel.CreateBasicProperties(); properties.DeliveryMode = 1; //deliveryMode: 1(nopersistent)非持久化,2(persistent)持久化 properties.Priority = 9;//消息的优先级 值越大 优先级越高 properties.ContentType = "text/plain";//消息的内输出格式 properties.Expiration = (60 * 1000).ToString(); //消息的过期时间为60秒 var messages = "I am RabbitMQ"; //传递的消息内容 //exchange 交换机,如果使用默认的交换机,那么routingKey要和队列的名称一致 //routingKey:路由 //basicProperties : 用于基础属性设置 ///BasicPublish(this IModel model, string exchange, string routingKey, IBasicProperties basicProperties, ReadOnlyMemory<byte> body); channel.BasicPublish("", "RabbitMQ", properties, Encoding.UTF8.GetBytes(messages)); //生产消息 } } Console.Read(); } } }
上述代码中需要重点介绍如下注释:QueueDeclareOk QueueDeclare(string queue, bool durable, bool exclusive, bool autoDelete, IDictionary<string, object> arguments);
//queue : 队列名称 //durable : 是否持久化消息,如果设置为true 则会将详细存储在磁盘中 //exclusive : 是否设置为独占队列,意思是指只能有一个消费者,设置为false,可以有多个消费者同时消费 //autoDelete : 是否是临时队列,临时队列会随着消费者断开连接时自动删除 //arguments : arguments 里面有很多属性可以设置,例如队列过期时间等 //QueueDeclareOk QueueDeclare(string queue, bool durable, bool exclusive, bool autoDelete, IDictionary<string, object> arguments);
autoDelete 设置为true后,队列就变成了临时队列,也就是自动删除的队列
自动删除队列和普通队列在使用上没有什么区别,唯一的区别是,当消费者断开连接时,队列将会被删除。自动删除队列允许的消费者没有限制,也就是说当这个队列上最后一个消费者断开连接才会执行删除。
自动删除队列只需要在声明队列时,设置属性auto-delete标识为true即可。系统声明的随机队列,缺省就是自动删除的。
exclusive 设置为TRUE时,队列就成了单消费者队列
普通队列允许的消费者没有限制,多个消费者绑定到多个队列时,RabbitMQ会采用轮询进行投递。如果需要消费者独占队列,在队列创建的时候,设定属性exclusive为true。
durable 设置为true 代表永久队列,消息会被存储到磁盘中
持久化队列和非持久化队列的区别是,持久化队列会被保存在磁盘中,固定并持久的存储,当Rabbit服务重启后,该队列会保持原来的状态在RabbitMQ中被管理,而非持久化队列不会被保存在磁盘中,Rabbit服务重启后队列就会消失。
非持久化比持久化的优势就是,由于非持久化不需要保存在磁盘中,所以使用速度就比持久化队列快。即是非持久化的性能要高于持久化。而持久化的优点就是会一直存在,不会随服务的重启或服务器的宕机而消失。
在声明队列时,将属性durable设置为“false”,则该队列为非持久化队列,设置成“true”时,该队列就为持久化队列
自动过期队列
指队列在超过一定时间没使用,会被从RabbitMQ中被删除。什么是没使用?
一定时间内没有Get操作发生
没有Consumer连接在队列上
特别的:就算一直有消息进入队列,也不算队列在被使用。
通过声明队列时,设定x-expires参数即可,单位毫秒。
关于arguments中的参数,我们可以通过RabbitMQ提供的工具中查看,如下图:
含义如下
信道的基础属性,代码部分如下: var properties = channel.CreateBasicProperties();
属性如下
contentType:消息的内容类型,如:text/plain contentEncoding:消息内容编码 headers:设置消息的header,类型为Map<String,Object> deliveryMode:1(nopersistent)非持久化,2(persistent)持久化 priority:消息的优先级 correlationId:关联ID replyTo:用于指定回复的队列的名称 expiration:消息的失效时间 messageId:消息ID timestamp:消息的时间戳 type:类型 userId:用户ID appId:应用程序ID custerId:集群ID
以上就是兔子MQ生产者代码构建过程中的详细细节
@天才卧龙的博客
只爱少妇