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)打印出监听的事件所接收的参数
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!