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

image-20220319184413626

#常用命令
#停止容器
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)服务端发布三条信息

image-20220319211642667

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)客户端监听消息

image-20220319211718586

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

image-20220319222751785

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

image-20220319222946598

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

image-20220319223248130

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

image-20220319223356006

posted @   peng_boke  阅读(360)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
点击右上角即可分享
微信分享提示