.net core 下nuget :RabbitMQ.Client
API:https://www.rabbitmq.com/dotnet-api-guide.html
RabbitMQ创建exchange的方式一共有4中:direct,fanout,headers,topic.
direct:直接建立发送消息
fanout:将不通过路由,发送该exchange上所有绑定的队列
topic:将通过路由匹配,发送相应的队列
public static class ExchangeType
{
//
// Summary:
// Exchange type used for AMQP direct exchanges.
public const string Direct = "direct";
//
// Summary:
// Exchange type used for AMQP fanout exchanges.
public const string Fanout = "fanout";
//
// Summary:
// Exchange type used for AMQP headers exchanges.
public const string Headers = "headers";
//
// Summary:
// Exchange type used for AMQP topic exchanges.
public const string Topic = "topic";
//
// Summary:
// Retrieve a collection containing all standard exchange types.
public static ICollection<string> All();
}
生产者代码:
string exchangeName = "TestFanoutChange";
string queueName1 = "hello1";
string queueName2 = "hello2";
string routeKey = "";
//创建连接工厂
ConnectionFactory factory = new ConnectionFactory
{
UserName = "guest",//用户名
Password = "guest",//密码
HostName = "localhost"//rabbitmq ip
};
//创建连接
var connection = factory.CreateConnection();
//创建通道
var channel = connection.CreateModel();
//定义一个Direct类型交换机
channel.ExchangeDeclare(exchangeName, ExchangeType.Fanout, false, false, null);//第三个参数表示交换机持久化
//定义队列
channel.QueueDeclare(queueName1, true, false, false, null);//第二个参数表示队列持久化
//将队列绑定到交换机
channel.QueueBind(queueName1, exchangeName, routeKey, null);
IBasicProperties props = channel.CreateBasicProperties();
props.ContentType = "text/plain";
props.DeliveryMode = 2;//2代表队列中的消息持久化
props.Expiration = "36000000";
Console.WriteLine($"\nRabbitMQ连接成功,\n\n请输入消息,输入exit退出!");
for (int i = 0; i < 1000; i++)
{
var sendBytes = Encoding.UTF8.GetBytes(i.ToString());
//发布消息
channel.BasicPublish(exchangeName, routeKey, props, sendBytes);
}
channel.Close();
connection.Close();
消费者代码:
//创建连接工厂
ConnectionFactory factory = new ConnectionFactory
{
UserName = "guest",//用户名
Password = "guest",//密码
HostName = "localhost"//rabbitmq ip
};
//创建连接
var connection = factory.CreateConnection();
//创建通道
var channel = connection.CreateModel();
channel.BasicQos(0, 1, false);
//事件基本消费者
EventingBasicConsumer consumer = new EventingBasicConsumer(channel);
//接收到消息事件
consumer.Received += (ch, ea) =>
{
var message = Encoding.UTF8.GetString(ea.Body);
Console.WriteLine($"收到消息: {message}");
// Console.WriteLine($"收到该消息[{ea.DeliveryTag}] 延迟10s发送回执");
// Thread.Sleep(10000);
//确认该消息已被消费
channel.BasicAck(ea.DeliveryTag, false);
// Console.WriteLine($"已发送回执[{ea.DeliveryTag}]");
};
//启动消费者 设置为手动应答消息
channel.BasicConsume("hello1", false, consumer);
Console.WriteLine("消费者已启动");
Console.ReadKey();
channel.Dispose();
connection.Close();
持久化:将内存中的数据写入到磁盘上
如果需要达到持久化的目的,必须要让队列持久化,然后再需要消息持久化
队列持久化: channel.QueueDeclare(queueName1, true, false, false, null);//第二个参数表示队列持久化
消息持久化: channel.QueueBind(queueName1, exchangeName, routeKey, null);
//channel.QueueBind(queueName2, exchangeName, routeKey, null);
IBasicProperties props = channel.CreateBasicProperties();
props.ContentType = "text/plain";
props.DeliveryMode = 2;//2代表队列中的消息持久化
props.Expiration = "36000000";
消费确认:一般使用手动方式来进行消费确认,一旦消费确认,该条消息会从队列中删除,如果出现业务逻辑执行到一半,机器挂了,由于没有执行到消费确认,该条消息会被分发到其他机器上,这就是手动确认的好处。
分发方式是对于消费者来说,如果不配置,默认循环分发,意思是如果有2台消费者服务器,会你一个我一个,但是这样可能会出现一个问题,比如一台机器执行的业务很快,而另外一台因为服务器内存小,执行速度慢,但是循环分发,导致内存小的机器满负荷,所以可以进行配置,让代码没有执行到消费确认那一步的时候,不允许有新的消息被分发过来,可以这样设置
var channel = connection.CreateModel();
channel.BasicQos(0, 1, false);//代码没有执行到消费确认那一步的时候,不允许有新的消息被分发过来
//事件基本消费者
EventingBasicConsumer consumer = new EventingBasicConsumer(channel);