dotnet学习笔记-专题03-RabbitMQ-01

专题03——RabbitMQ

1. RabbitMQ安装

服务端

使用如下sh脚本安装:

#!/bin/sh

sudo apt-get install curl gnupg apt-transport-https -y

## Team RabbitMQ's main signing key
curl -1sLf "https://keys.openpgp.org/vks/v1/by-fingerprint/0A9AF2115F4687BD29803A206B73A36E6026DFCA" | sudo gpg --dearmor | sudo tee /usr/share/keyrings/com.rabbitmq.team.gpg > /dev/null
## Community mirror of Cloudsmith: modern Erlang repository
curl -1sLf https://ppa1.novemberain.com/gpg.E495BB49CC4BBE5B.key | sudo gpg --dearmor | sudo tee /usr/share/keyrings/rabbitmq.E495BB49CC4BBE5B.gpg > /dev/null
## Community mirror of Cloudsmith: RabbitMQ repository
curl -1sLf https://ppa1.novemberain.com/gpg.9F4587F226208342.key | sudo gpg --dearmor | sudo tee /usr/share/keyrings/rabbitmq.9F4587F226208342.gpg > /dev/null

## Add apt repositories maintained by Team RabbitMQ
sudo tee /etc/apt/sources.list.d/rabbitmq.list <<EOF
## Provides modern Erlang/OTP releases
##
deb [signed-by=/usr/share/keyrings/rabbitmq.E495BB49CC4BBE5B.gpg] https://ppa1.novemberain.com/rabbitmq/rabbitmq-erlang/deb/ubuntu jammy main
deb-src [signed-by=/usr/share/keyrings/rabbitmq.E495BB49CC4BBE5B.gpg] https://ppa1.novemberain.com/rabbitmq/rabbitmq-erlang/deb/ubuntu jammy main

## Provides RabbitMQ
##
deb [signed-by=/usr/share/keyrings/rabbitmq.9F4587F226208342.gpg] https://ppa1.novemberain.com/rabbitmq/rabbitmq-server/deb/ubuntu jammy main
deb-src [signed-by=/usr/share/keyrings/rabbitmq.9F4587F226208342.gpg] https://ppa1.novemberain.com/rabbitmq/rabbitmq-server/deb/ubuntu jammy main
EOF

## Update package indices
sudo apt-get update -y

## Install Erlang packages
sudo apt-get install -y erlang-base \
                        erlang-asn1 erlang-crypto erlang-eldap erlang-ftp erlang-inets \
                        erlang-mnesia erlang-os-mon erlang-parsetools erlang-public-key \
                        erlang-runtime-tools erlang-snmp erlang-ssl \
                        erlang-syntax-tools erlang-tftp erlang-tools erlang-xmerl

## Install rabbitmq-server and its dependencies
sudo apt-get install rabbitmq-server -y --fix-missing

配置文件在/etc/rabbitmq中,通过rabbitmq-env.conf配置环境,rabbitmq-env.conf如下:

export RABBITMQ_NODENAME=rabbit@localhost
export RABBITMQ_NODE_IP_ADDRESS=127.0.0.1
export ERL_EPMD_ADDRESS=127.0.0.1

客户端

使用NuGet安装RabbitMQ.Client

2. 接收者

using System.Text;
using RabbitMQ.Client;
using RabbitMQ.Client.Events;

// 工厂方法,用于配置连接
var factory = new ConnectionFactory
{
	// RabbitMQ的服务端地址
    HostName = SharedConfig.Configuration.HostName,
    // 异步消费
    DispatchConsumersAsync = true
};

// 建立连接
using var connection = factory.CreateConnection();
// 创建信道
var channel = connection.CreateModel();

// 注:XxxDeclare的意思是:没有就创建,有就复用(由于不知道是Sender还是Receiver先启动,所以都要声明)
// 声明交换机
channel.ExchangeDeclare(exchange: SharedConfig.Configuration.ExchangeName,
    type: SharedConfig.Configuration.ExchangeType);
// 声明队列
channel.QueueDeclare(queue: SharedConfig.Configuration.QueueName, durable: true, exclusive: false, autoDelete: false,
    arguments: null);
// 将队列与交换机绑定
channel.QueueBind(queue: SharedConfig.Configuration.QueueName, exchange: SharedConfig.Configuration.ExchangeName,
    routingKey: SharedConfig.Configuration.EventName);

// 从队列中获取消息(拉取模式)
var asyncEventingBasicConsumer = new AsyncEventingBasicConsumer(channel);
// 订阅Received事件
asyncEventingBasicConsumer.Received += OnMessageReceived;
// 确认队列中正在消费的事件状态(Ack或Reject)
channel.BasicConsume(queue: SharedConfig.Configuration.QueueName, autoAck: false, consumer: asyncEventingBasicConsumer);

Console.ReadLine();

async Task OnMessageReceived(object sender, BasicDeliverEventArgs args)
{
    try
    {
        var bytes = args.Body.ToArray();
        var message = Encoding.UTF8.GetString(bytes);
        Console.WriteLine($"{DateTime.Now}: 收到了消息-{message}");
        channel.BasicAck(args.DeliveryTag, multiple: false);
        await Task.Delay(800);
    }
    catch (Exception e)
    {
        channel.BasicReject(args.DeliveryTag, true); // 失败重发
        Console.WriteLine($"处理收到的消息出错,{e.Message}");
    }
}

3. 发送者

using System.Globalization;
using System.Text;
using RabbitMQ.Client;

var connectionFactory = new ConnectionFactory
{
    HostName = SharedConfig.Configuration.HostName,
    DispatchConsumersAsync = true
};
// 和RabbitMQ建立TCP连接
using var connection = connectionFactory.CreateConnection();

// 每间隔3s将当前时间发送到队列当中去,共发送30次
for (int i = 0; i < 30; i++)
{
    // 等待发送的消息
    string message = DateTime.Now.ToString(CultureInfo.InvariantCulture);
    // 将消息重新编码为RabbitMQ能够接受的格式(byte[])
    var mqMessage = Encoding.UTF8.GetBytes(message);

    // 创建信道
    using (var channel = connection.CreateModel())
    {
        var properties = channel.CreateBasicProperties();
        // 消息递送模式:持久化模式
        properties.DeliveryMode = 2;
        // 声明交换机
        // 注:XxxDeclare的意思是:没有就创建,有就复用(由于不知道是Sender还是Receiver先启动,所以都要声明)
        channel.ExchangeDeclare(exchange: SharedConfig.Configuration.ExchangeName,
            type: SharedConfig.Configuration.ExchangeType);
        // 发布消息
        channel.BasicPublish(exchange: SharedConfig.Configuration.ExchangeName,
            routingKey: SharedConfig.Configuration.EventName, mandatory: true,
            basicProperties: properties, body: mqMessage);
    }

    Console.WriteLine($"发布了消息:{message}");
    Thread.Sleep(3000);
}

4. 共用的配置类

namespace SharedConfig;

public struct Configuration
{
    // RabbitMQ的地址,这里用本地地址和默认端口
    public const string HostName = "localhost";
    // 交换机名称
    public const string ExchangeName = "exchange1";
    // 交换机类型
    public const string ExchangeType = "direct";
    // 当作routingKey使用(路由的依据)
    public const string EventName = "event1";
    // 队列名称
    public const string QueueName = "queue1";
}
posted @ 2024-11-22 23:21  random_d  阅读(37)  评论(0)    收藏  举报