分布式异步队列学习总结5(交换机DirectExchange)

在整个rabbitmq服务中,生产者发送的所有消息都要先经过交换机(exchange),然后再到队列(queue)中。在往队列写入消息时,如果需要写入不同的策略,只需要修改交换机的转发策略即可(为交换机指定消息写入队列的策略)。

rabbitmq中交换机的类型:

 

首先看第一种类型DirectExchange

生产者在往交换机发送消息时,会指定一个key,如果key值和交换机与队列之间绑定的key一致,则消息会通过交换机发送到对应的队列中。

应用实例:

通过一个写日志的实例来展示DirectExchange的用法,日志类型分为四种info、debug、warn、error。这四种类型的日志都需要记录到本文中,其中error类型的日志不仅需要记录到文本中,还需要发送邮件给管理员。

实现思路:

生产者

定义一个生产者服务,负责发送日志消息到rabbitmq队列中。生产者服务中需要声明两个队列。

队列一(DirectExchangeLogAllQueue)负责接收所有类型的日志消息(100条消息)。

队列二(DirectExchangeLogErrorQueue)负责接收error类型的日志消息(25条消息)。

消费者

定义二个消费者服务。

消费者服务一负责将四种类型的日志记录到文本中(DirectExchangeConsumerLogAll)(100条消息)。

消费者服务二负责将error类型的日志发送邮件给管理员(DirectExchangeConsumerLogError)(25条消息)。

项目结构:

 

代码实现:

生产者

using RabbitMQ.Client;
using System;
using System.Collections.Generic;
using System.Text;

namespace AspNetCore.RabbitMQ.MessageProducer.MessageProducer
{
    /// <summary>
    /// Direct路由
    /// </summary>
    public class DirectExchange
    {
        public static void Show()
        {
            ConnectionFactory factory = new ConnectionFactory();
            factory.HostName = "localhost";//rabbitmq服务在本地运行
            factory.UserName = "guest";//用户名
            factory.Password = "guest";//密码

            //创建链接
            using (IConnection connection = factory.CreateConnection())
            {
                //创建信道
                using (IModel channel = connection.CreateModel())
                {
                    Console.ForegroundColor = ConsoleColor.Red;
                    Console.WriteLine("生产者已准备就绪......");

                    //声明两个队列
                    channel.QueueDeclare(queue: "DirectExchangeLogAllQueue", durable: true, exclusive: false, autoDelete: false, arguments: null);
                    channel.QueueDeclare(queue: "DirectExchangeLogErrorQueue", durable: true, exclusive: false, autoDelete: false, arguments: null);

                    //声明交换机exchange
                    channel.ExchangeDeclare(exchange: "DirectExchange", type: ExchangeType.Direct, durable: true, autoDelete: false, arguments: null);



                    //待发送的消息
                    {
                        string[] logtypes = { "info", "debug", "warn", "error" };
                        foreach (string logtype in logtypes)
                        {
                            //绑定exchange和queue
                            channel.QueueBind(queue: "DirectExchangeLogAllQueue", exchange: "DirectExchange", routingKey: logtype);
                        }


                        //绑定exchange和queue
                        channel.QueueBind(queue: "DirectExchangeLogErrorQueue", exchange: "DirectExchange", routingKey: "error");


                        List<LogMsgModel> logList = new List<LogMsgModel>();
                        for (int i = 1; i <= 100; i++)
                        {
                            if (i % 4 == 0)
                            {
                                logList.Add(new LogMsgModel()
                                {
                                    LogType = "info",
                                    Msg = Encoding.UTF8.GetBytes($"info第{i}条信息")
                                });
                            }

                            if (i % 4 == 1)
                            {
                                logList.Add(new LogMsgModel()
                                {
                                    LogType = "debug",
                                    Msg = Encoding.UTF8.GetBytes($"debug第{i}条信息")
                                });
                            }

                            if (i % 4 == 2)
                            {
                                logList.Add(new LogMsgModel()
                                {
                                    LogType = "warn",
                                    Msg = Encoding.UTF8.GetBytes($"warn第{i}条信息")
                                });
                            }

                            if (i % 4 == 3)
                            {
                                logList.Add(new LogMsgModel()
                                {
                                    LogType = "error",
                                    Msg = Encoding.UTF8.GetBytes($"error第{i}条信息")
                                });
                            }

                        }

                        Console.WriteLine("生产者发送100条日志消息");

                        //发送日志消息
                        foreach (var log in logList)
                        {
                            channel.BasicPublish(exchange: "DirectExchange", routingKey: log.LogType, basicProperties: null, body: log.Msg);
                            Console.WriteLine($"{Encoding.UTF8.GetString(log.Msg)} 已发送");
                        }
                    }
                }
            }
        }
    }



    public class LogMsgModel
    {
        public string LogType { get; set; }
        public byte[] Msg { get; set; }
    }

}

main方法:

 class Program
    {
        static void Main(string[] args)
        {
            //路由类型
            DirectExchange.Show();

            Console.ReadLine();

        }
    }

消费者一:

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

namespace AspNetCore.RabbitMQ.MessageConsumer_01.MessageConsumer
{
    /// <summary>
    /// 消费者 所有日志类型
    /// </summary>
    public class DirectExchangeConsumerLogAll
    {
        public static void Show()
        {
            ConnectionFactory factory = new ConnectionFactory();
            factory.HostName = "localhost";//rabbitmq服务在本地运行
            factory.UserName = "guest";//用户名
            factory.Password = "guest";//密码

            //创建链接
            using (IConnection connection = factory.CreateConnection())
            {
                //创建信道
                using (IModel channel = connection.CreateModel())
                {
                    Console.ForegroundColor = ConsoleColor.Green;
                    try
                    {
                        //基于当前信道创建事件
                        var consumer = new EventingBasicConsumer(channel);
                        consumer.Received += (model, ea) =>
                        {
                            var body = ea.Body;
                            var message = Encoding.UTF8.GetString(body.ToArray());
                            Console.WriteLine($"{message} 写入文本中...");
                        };

                        Console.WriteLine("消费者准备就绪......");

                        //处理消息
                        channel.BasicConsume(queue: "DirectExchangeLogAllQueue", autoAck: true, consumer: consumer);

                        Console.ReadLine();
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine(ex.Message);
                    }

                }
            }

        }
    }
}

main方法:

class Program
    {
        static void Main(string[] args)
        {
            //路由类型
            DirectExchangeConsumerLogAll.Show();
            Console.ReadLine();
        }
    }

消费者二:

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

namespace AspNetCore.RabbitMQ.MessageConsumer_02.MessageConsumer
{
    /// <summary>
    /// 消费者 error日志类型 特殊处理
    /// </summary>
    public class DirectExchangeConsumerLogError
    {
        public static void Show()
        {
            ConnectionFactory factory = new ConnectionFactory();
            factory.HostName = "localhost";//rabbitmq服务在本地运行
            factory.UserName = "guest";//用户名
            factory.Password = "guest";//密码

            //创建链接
            using (IConnection connection = factory.CreateConnection())
            {
                //创建信道
                using (IModel channel = connection.CreateModel())
                {
                    Console.ForegroundColor = ConsoleColor.Green;
                    try
                    {
                        //基于当前信道创建事件
                        var consumer = new EventingBasicConsumer(channel);
                        consumer.Received += (model, ea) =>
                        {
                            var body = ea.Body;
                            var message = Encoding.UTF8.GetString(body.ToArray());
                            Console.WriteLine($"{message} 已发送邮件通知管理员...");
                        };

                        Console.WriteLine("消费者准备就绪......");

                        //处理消息
                        channel.BasicConsume(queue: "DirectExchangeLogErrorQueue", autoAck: true, consumer: consumer);

                        Console.ReadLine();
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine(ex.Message);
                    }

                }
            }

        }
    }
}

main方法:

class Program
    {
        static void Main(string[] args)
        {
            //路由类型
            DirectExchangeConsumerLogError.Show();

            Console.ReadLine();
        }
    }

运行结果:

 

 

 

总结:需要分支处理的时候,就可以选择使用Direct类型的交换机。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值