菜鸟使用RabbitMQ消息队列感触

public class MQConnection
{
private static IConnection Connection;
配置:
public static IConnection GetConnection()
{
if (Connection == null)
{
var factory = new ConnectionFactory()
{
HostName = BasicConfig.MQHostName,
UserName = BasicConfig.MQUserName,
Password = BasicConfig.MQPassword,
VirtualHost= BasicConfig.MQVirtualHost,
RequestedHeartbeat = new TimeSpan(60),//指定连接的心跳间隔时间,用于检测连接是否存活
AutomaticRecoveryEnabled = true, //要启用自动连接恢复
TopologyRecoveryEnabled=true,//指定是否启用拓扑恢复功能
};
//创建连接
Connection = factory.CreateConnection();
return Connection;
}
return Connection;
}
}

生产消息:
public static ResultInfo Dlx_Publish(string strBody)
{
ResultInfo res = new ResultInfo();
try
{
using (var channel = MQConnection.GetConnection().CreateModel())
{
// 声明死信交换机
channel.ExchangeDeclare("dlx_exchange", ExchangeType.Direct,true);
// 声明死信队列
channel.QueueDeclare("dlx_info_queue", true, false, false, null);
// 绑定死信队列到死信交换机(假设使用固定的路由键)
channel.QueueBind("dlx_info_queue", "dlx_exchange", "dlx_routing_key");

                // 声明普通队列,并设置死信交换机和路由键
                var queueArgs = new Dictionary<string, object>
            {
                { "x-dead-letter-exchange", "dlx_exchange" },
                { "x-dead-letter-routing-key", "dlx_routing_key" }
            };

                var MQExchange = BasicConfig.MQExchange;
                // 声明Fanout交换机
                channel.ExchangeDeclare(MQExchange, BasicConfig.MQExchangeType, true, false, queueArgs);
                //开启ACK确认
                channel.ConfirmSelect();
                // 设置消息的expiration属性,这里设置为5秒
                var properties = channel.CreateBasicProperties();
                properties.Expiration = "5000"; // 毫秒为单位

                try
                {
                    // 定义要发送的消息
                    var body = Encoding.UTF8.GetBytes(strBody);
                    channel.BasicAcks += (sender, ea) =>
                    {
                        res.Success = true;
                        res.Message = $"消息发送成功";
                    };
                    channel.BasicNacks += (sender, ea) =>
                    {
                        res.Success = false;
                        res.Message = $"消息发送失败";
                    };

                    // 发送消息到Fanout交换机
                    channel.BasicPublish(exchange: MQExchange, routingKey: "", basicProperties: properties, body: body);

                }
                catch (Exception ex)
                {
                    res.Success = false;
                    res.Message = $"消息发生异常:{ex.Message}-{ex.StackTrace}-{ex.InnerException?.Message}";
                }
            }
        }
        catch (Exception ex)
        {
            res.Success = false;
            res.Message = $"消息发生异常:{ex.Message}-{ex.StackTrace}-{ex.InnerException?.Message}";
        }

        return res;
    }

消费消息:
///


/// 此方法直接读取队列 ,不做队列声明
///

public static void ReceivedQueueInfor()
{
try
{
string strQueue = BasicConfig.MQQueue;
using (var channel = MQConnection.GetConnection().CreateModel())
{
if (QueueExists(channel, strQueue))
{
var consumer = new EventingBasicConsumer(channel);
consumer.Received += (model, ea) =>
{
var body = ea.Body.ToArray();
var msg = Encoding.UTF8.GetString(body);
// 使用Polly实现重试策略
var policyRetryCount = 0;
var retryPolicy = Policy.Handle() // 定义触发重试的异常类型
.Retry(3, (exception, retryCount) => // 最多重试3次
{
Console.WriteLine($"Exception in processing message. Retrying: {retryCount}");
policyRetryCount = retryCount;
Thread.Sleep(1000);
});

                        retryPolicy.Execute(() =>
                        {
                            var result = ProcessMessage(msg);
                            if (result)
                            {
                                Console.WriteLine($"消息消费成功");
                                channel.BasicAck(ea.DeliveryTag, false);
                            }
                            else
                            {
                                Console.WriteLine($"消息消费失败");
                                if (policyRetryCount == 3)
                                {
                                    // 消息处理失败,重新入队
                                    channel.BasicNack(ea.DeliveryTag, false, true);
                                    Console.WriteLine("消息重试处理 3次失败,重新入队");
                                }
                                throw new Exception("processing failure");
                            }
                        });
                    };
                    channel.BasicConsume(strQueue, false, consumer);
                }
                else
                {
                    Console.WriteLine("消息队列不存在!");
                }
                Console.ReadKey();
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine($"消息消费发生异常:{ex.Message}-{ex.StackTrace}-{ex.InnerException?.Message}");
        }
    }
    /// <summary>
    /// 此方法读取死信队列
    /// </summary>
    public static void Dlx_ReceivedMQ()
    {
        using (var channel = MQConnection.GetConnection().CreateModel())
        {
            // 这里的queueName应该替换为你想要消费的队列的名称
            string queueName = BasicConfig.DlxMQQueue;
            if (QueueExists(channel, queueName))
            {
                // 声明一个消费者
                var consumer = new EventingBasicConsumer(channel);
                consumer.Received += (model, ea) =>
                {
                    var body = ea.Body.ToArray();
                    var message = System.Text.Encoding.UTF8.GetString(body);
                    var res = Dlx_Publish(message);
                    if (res.Success)
                    {
                        // 处理完消息后应答
                        channel.BasicAck(ea.DeliveryTag, false);
                        LogHelper.Write($"{DateTime.Now}-Received Message: {message}");
                        Console.WriteLine("Received Message: {0}", message.Length > 100 ? message.Substring(0, 100) : message);
                    }
                    else {
                        // 消息处理失败,重新入队
                        channel.BasicNack(ea.DeliveryTag, false, true);
                    }
                };
                Console.WriteLine("start processing messages!");
                // 开始消费消息
                channel.BasicConsume(queue: queueName, autoAck: false, consumer: consumer);
            }
            else
            {
                Console.WriteLine("消息队列不存在!");
            }

            Console.ReadLine();
        }
    }
    /// <summary>
    /// 判断队列是否存在
    /// </summary>
    /// <param name="channel"></param>
    /// <param name="queueName"></param>
    /// <returns></returns>
    private static bool QueueExists(IModel channel, string queueName)
    {
        // 尝试获取声明队列,如果队列不存在,会抛出异常
        try
        {
            var queue = channel.QueueDeclarePassive(queueName);
            // 如果声明成功,队列存在
            return true;
        }
        catch (Exception ex)
        {
            LogHelper.Write(ex);
            // 队列不存在
            return false;
        }
    }
posted @ 2024-06-28 11:59  .Net菜鸟站  阅读(1)  评论(0编辑  收藏  举报