简介:
RabbitMQ是由erlang语言开发的一个基于AMQP(Advanced Message Queuing Protocol)协议的企业级消息队列中间件。可实现队列,订阅/发布,路由,通配符等工作模式。
MQ的优点:
.异步处理:比如发送邮件,发送短信等不需要等待处理结果的操作
应用解耦:比如下单成功后,通知仓库发货,不需要等待仓库回应,通过消息队列去通知仓库,降低应用间耦合程序,可并行开发两个功能模块
流量削锋:在抢购或者其他的活动页,服务处于爆发式请求状态,如果直连数据库,数据库容易被拖垮。抢购商品也容易出现库存超卖的情况。通过队列可有效解决该问题。
日志处理:在单机中,日志直接写入到文件目录中,但是在分布式应用中,日志需要有统一的处理机制,可通过消息队列统一由某个消费端做处理。
消息通信:如生产端和消费端可通过队列进行异步通信
环境搭建:
安装erlang语言运行环境。下载地址:https://erlang.org/download/otp_win64_23.2.exe
安装RabbitMQ。下载地址:https://www.rabbitmq.com/install-windows.html
安装RabbitMQ的Web管理平台,RabbitMQ的管理平台是通过插件的形式使用,需要手动启用管理平台
RabbitMQ默认被安装到C:\Program Files\RabbitMQ Server\rabbitmq_server-3.8.14 下
进入到sbin目录下,打开cmd
rabbitmq-plugins.bat enable rabbitmq_management
安装完成后,浏览器打开 http://localhost:15672/ 即可看到RabbitMQ的管理界面。输入默认账号密码 guest 成功登录。
默认登陆为:guest/guest
添加用户,用户名:xdm 密码:xdm123
rabbitmqctl add_userxdm 密码:xdm123
添加权限
rabbitmqctl set_permissions -p "/" xdm".*" ".*" ".*"
修改用户角色
rabbitmqctl set_user_tags xdm administrator
就可以远程访问了
Producer与Exchange
Producer
消息的生产者,也就是创建消息的对象
Exchange
消息的接受者,也就是用来接收消息的对象,Exchange接收到消息后将消息按照规则发送到与他绑定的Queue中。下面我们来定义一个Producer与Exchange。
安装Nuget包 RabbitMQ.Client
看代码效果
class Program
{
private static readonly ConnectionFactory rabbitMqFactory = new ConnectionFactory()
{
//这里写自己电脑的hostname,可以通过命令提示符,输入hostname查询
HostName= "",
Port=5672,
UserName= "xdm",
Password= "",
VirtualHost="/"
};
static void Main(string[] args)
{
var exchage = "change2";
var route = "route2";
var queue = "queue2";
using (IConnection conn=rabbitMqFactory.CreateConnection())
{
using (IModel channel = conn.CreateModel())
{
channel.ExchangeDeclare(exchage,type:"direct",durable:true,autoDelete:false);//创建change2
channel.QueueDeclare(queue,durable:true,exclusive:false,autoDelete:false);//创建queue2
channel.QueueBind(queue, exchage, route);//将queue2绑定到change2
#region 发送消息
var props = channel.CreateBasicProperties();
props.Persistent = true;//持久化
channel.BasicPublish(exchage, route, true, props, Encoding.UTF8.GetBytes("hellorrabbitmq"));
#endregion
//#region 消费信息
//while (true)
//{
// var message = channel.BasicGet(queue, true);//第二个参数说明自动释放消息,如为false,需手动释放消息
// if (message != null)
// {
// var msgBody = Encoding.UTF8.GetString(message.Body);
// Console.WriteLine(string.Format("***接收时间:{0},消息内容:{1}",DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"),msgBody));
// }
// System.Threading.Thread.Sleep(TimeSpan.FromSeconds(1));
//}
//#endregion
//#region 让失败消息回到队列中
//while (true)
//{
// var message = channel.BasicGet(queue,false);
// if (message != null)
// {
// var msgBody = Encoding.UTF8.GetString(message.Body);
// Console.WriteLine(string.Format("***接收时间:{0},消息内容:{1}",DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"),msgBody));
// Console.WriteLine(message.DeliveryTag);//当前消息被处理的次序数
// if (1==1)
// {
// channel.BasicReject(message.DeliveryTag, true);
// }
// System.Threading.Thread.Sleep(TimeSpan.FromSeconds(1));
// }
//}
//#endregion
//#region 监听消息
//channel.BasicQos(prefetchSize:0,prefetchCount:20,global:false);//一次接受10条消息,否则rabbit会把消息一次性推到client,会增大client的负荷
//EventingBasicConsumer consumer = new EventingBasicConsumer(channel);
//consumer.Received += (model, ea) =>
//{
// Byte[] body = ea.Body;
// string message = Encoding.UTF8.GetString(body);
// Console.WriteLine(message + Thread.CurrentThread.ManagedThreadId);
// channel.BasicAck(deliveryTag:ea.DeliveryTag,multiple:false);
//};
//channel.BasicConsume(queue: queue, autoAck: false, consumer: consumer);
//Console.WriteLine();
//#endregion
}
}
}