DDD之实现集成事件(RabbitMQ)
# DDD之实现集成事件(RabbitMQ)
1.1 RabbitMQ
集成事件是服务器间的通信,所以必须借助于第三方服务器作为事件总线。常用的消息中间件有Redis、RabbitMQ、Kafka、ActiveMQ等
1.2 RabbitMq简介
- 信道(Channel):信道是消息的生产者、消费者和服务器进行通信的虚拟连接。TCP连接的建立是非常消耗资源的,所以RabbitMQ在TCP连接的基础上构建了虚拟的信道。我们尽量重复使用TCP连接,而信道则是可以用完了就关闭。
- 队列(Queue):用来进行消息收发的地方,生产者把消息放到队列中,消费者从队列中获取数据。
- 交换机(exchange):把消息路由到一个或者多个队列中。
1.3 docker安装RabbitMQ
这里使用docker安装RabbitMQ
#切换root用户
sudo -i
#查询rabbitMQ镜像
docker search rabbitmq
#拉取rabbitMQ镜像
docker pull rabbitmq
#运行rabbitMQ
docker run -d --name rabbitmq -p 15672:15672 -p 5672:5672 rabbitmq
#进入容器
docker exec -it 容器id/容器名称 /bin/bash
#安装安装插件
rabbitmq-plugins enable rabbitmq_management
#容器随docker启动自动运行
docker update rabbitmq --restart=always
#退出当前容器
exit
访问:http://192.168.56.10:15672/# 用户密码都是guest

#常用命令
#停止容器
docker stop 容器id/容器名称
#删除容器
docker rm 容器id/容器名称
(3)Stats in management UI are disabled on this [node]
docker exec -it {rabbitmq容器名称或者id} /bin/bash
#进入容器后,cd到以下路径
cd /etc/rabbitmq/conf.d/
#修改 management_agent.disable_metrics_collector = false
echo management_agent.disable_metrics_collector = false > management_agent.disable_metrics_collector.conf
#退出容器
exit
#重启rabbitmq容器
docker retart {rabbitmq容器id}
1.4 基本使用
(1)安装Install-Package RabbitMQ.Client
(2)服务端发布三条信息

var factory = new ConnectionFactory();
factory.HostName = "192.168.56.10";
factory.DispatchConsumersAsync = true;
string exchangeName = "exchange1";//交换机的名字
string eventName = "myEvent";// routingKey的值
using var conn = factory.CreateConnection();
for (int i = 0; i < 3; i++)
{
string msg = DateTime.Now.TimeOfDay.ToString();//待发送消息
using (var channel = conn.CreateModel())//创建信道
{
var properties = channel.CreateBasicProperties();
properties.DeliveryMode = 2;
channel.ExchangeDeclare(exchange: exchangeName, type: "direct");//声明交换机
byte[] body = Encoding.UTF8.GetBytes(msg);
channel.BasicPublish(exchange: exchangeName, routingKey: eventName,
mandatory: true, basicProperties: properties, body: body);//发布消息
}
Console.WriteLine("发布了消息:" + msg);
Thread.Sleep(1000);
}
(3)客户端监听消息

var factory = new ConnectionFactory();
factory.HostName = "192.168.56.10";
factory.DispatchConsumersAsync = true;
string exchangeName = "exchange1";//交换机的名字
string eventName = "myEvent";// routingKey的值
using var conn = factory.CreateConnection();
using var channel = conn.CreateModel();
string queueName = "queue1";
channel.ExchangeDeclare(exchange: exchangeName, type: "direct");
channel.QueueDeclare(queue: queueName, durable: true,
exclusive: false, autoDelete: false, arguments: null);
channel.QueueBind(queue: queueName,
exchange: exchangeName, routingKey: eventName);
var consumer = new AsyncEventingBasicConsumer(channel);
consumer.Received += Consumer_Received;
channel.BasicConsume(queue: queueName, autoAck: false, consumer: consumer);
Console.ReadLine();
async Task Consumer_Received(object sender, BasicDeliverEventArgs args)
{
try
{
var bytes = args.Body.ToArray();
string msg = Encoding.UTF8.GetString(bytes);
Console.WriteLine(DateTime.Now + "收到了消息" + msg);
channel.BasicAck(args.DeliveryTag, multiple: false);
await Task.Delay(800);
}
catch (Exception ex)
{
channel.BasicReject(args.DeliveryTag, true);
Console.WriteLine("处理收到的消息出错" + ex);
}
}
2 .NET中简化集成事件
(1)安装Install-package Zack.EventBus
(2)注入EventBus

(3)Controller注入IEventBus服务,然后调用IEventBus的Publish方法发布消息。

(4)创造一个实现了IIntegrationEventHandler接口的类,这个类用来处理收到的事件。通过[EventName(“UserAdded”)]设定类监听的事件。

(5)打印出监听的事件所接收的参数


浙公网安备 33010602011771号