第5章:路由(Routing)与直连交换机(Direct Exchange)

本章目标

  • 理解直连交换机(Direct Exchange)的工作原理。

  • 掌握基于路由键(Routing Key)的消息过滤机制。

  • 学习多重绑定(Multiple Bindings)的概念。

  • 实现一个可以根据日志级别进行过滤的智能日志系统。


一、理论部分

1. 直连交换机(Direct Exchange)

直连交换机是比扇形交换机更智能的路由器。它的工作逻辑很简单:

  • 消息带着一个路由键(Routing Key) 被发送到直连交换机。

  • 队列通过一个绑定键(Binding Key) 绑定到交换机。

  • 当绑定键与路由键完全匹配时,消息就会被路由到该队列。

2. 路由键(Routing Key)与绑定键(Binding Key)

  • 路由键(Routing Key):生产者发送消息时指定的一个字符串,用于描述消息的特征或类型。

  • 绑定键(Binding Key):消费者在将队列绑定到交换机时指定的字符串,用于声明该队列对哪些消息感兴趣。

对于直连交换机,路由键和绑定键必须精确匹配(完全相等)。

3. 多重绑定(Multiple Bindings)

一个队列可以绑定多个绑定键,同样,多个队列也可以用相同的绑定键绑定到同一个交换机。这提供了很大的灵活性:

  • 一个队列,多个兴趣:队列Q1可以同时绑定errorwarning键,接收所有错误和警告消息。

  • 多个队列,相同兴趣:队列Q1和Q2都可以绑定info键,这样它们都会收到所有信息级别的消息(类似于扇形交换机的效果,但仅限于特定路由键)。

4. 使用场景

直连交换机非常适合需要有选择性接收消息的场景,比如:

  • 日志级别过滤:只接收特定级别(error、warning、info)的日志。

  • 业务类型路由:根据消息类型(order.created、payment.processed)路由到不同的处理服务。

  • 优先级处理:将高优先级任务路由到专用队列。


二、实操部分:构建智能日志系统

我们将改进第4章的日志系统,使其能够根据日志级别(error、warning、info)进行智能路由。

第1步:创建项目

  1. 创建一个新的解决方案。

  2. 添加一个控制台应用程序项目作为生产者:EmitLogDirect

  3. 添加三个控制台应用程序项目作为消费者:

    • ReceiveLogsDirect - 接收所有日志

    • ReceiveWarningsAndErrors - 只接收警告和错误

    • ReceiveErrorsOnly - 只接收错误

  4. 为所有项目添加RabbitMQ.Client NuGet包。

第2步:编写智能日志生产者(EmitLogDirect.cs)

using System.Text;
using RabbitMQ.Client;var factory = new ConnectionFactory() { HostName = "localhost", UserName = "myuser", Password = "mypassword" };using (var connection = factory.CreateConnection())
using (var channel = connection.CreateModel())
{// 1. 声明一个直连交换机(Direct Exchange)channel.ExchangeDeclare(exchange: "direct_logs", type: ExchangeType.Direct);// 2. 从命令行参数获取日志级别和消息内容// 用法:dotnet run [severity] [message]// 示例:dotnet run error "Database connection failed"var severity = (args.Length > 0) ? args[0] : "info";var message = (args.Length > 1) ? string.Join(" ", args.Skip(1).ToArray()) : "Hello World!";var body = Encoding.UTF8.GetBytes(message);// 3. 发布消息到直连交换机,并指定路由键(日志级别)channel.BasicPublish(exchange: "direct_logs",routingKey: severity, // 关键:使用日志级别作为路由键basicProperties: null,body: body);Console.WriteLine($" [x] Sent '{severity}':'{message}'");
}Console.WriteLine(" Press [enter] to exit.");
Console.ReadLine();

关键点:

  • 交换机类型改为ExchangeType.Direct

  • 使用命令行第一个参数作为路由键(日志级别)。

  • BasicPublish中明确指定routingKey参数。

第3步:编写接收所有日志的消费者(ReceiveLogsDirect.cs)

这个消费者会绑定三个不同的绑定键,从而接收所有级别的日志。

using System.Text;
using RabbitMQ.Client;
using RabbitMQ.Client.Events;var factory = new ConnectionFactory() { HostName = "localhost", UserName = "myuser", Password = "mypassword" };using (var connection = factory.CreateConnection())
using (var channel = connection.CreateModel())
{// 声明直连交换机channel.ExchangeDeclare(exchange: "direct_logs", type: ExchangeType.Direct);var queueName = channel.QueueDeclare().QueueName;// 绑定到三个日志级别:接收所有消息// 注意:一个队列可以绑定多个路由键channel.QueueBind(queue: queueName, exchange: "direct_logs", routingKey: "info");channel.QueueBind(queue: queueName, exchange: "direct_logs", routingKey: "warning");channel.QueueBind(queue: queueName, exchange: "direct_logs", routingKey: "error");Console.WriteLine($" [*] Waiting for ALL logs (info, warning, error). Queue: {queueName}");var consumer = new EventingBasicConsumer(channel);consumer.Received += (model, ea) =>{var body = ea.Body.ToArray();var message = Encoding.UTF8.GetString(body);Console.WriteLine($" [x] [ALL] Received '{ea.RoutingKey}':'{message}'");};channel.BasicConsume(queue: queueName,autoAck: true,consumer: consumer);Console.WriteLine(" Press [enter] to exit.");Console.ReadLine();
}

关键点:

  • 一个队列通过多次调用QueueBind绑定了三个不同的路由键。

  • 通过ea.RoutingKey可以获取消息的实际路由键。

第4步:编写接收警告和错误的消费者(ReceiveWarningsAndErrors.cs)

using System.Text;
using RabbitMQ.Client;
using RabbitMQ.Client.Events;var factory = new ConnectionFactory() { HostName = "localhost", UserName = "myuser", Password = "mypassword" };using (var connection = factory.CreateConnection())
using (var channel = connection.CreateModel())
{channel.ExchangeDeclare(exchange: "direct_logs", type: ExchangeType.Direct);var queueName = channel.QueueDeclare().QueueName;// 只绑定到warning和error级别channel.QueueBind(queue: queueName, exchange: "direct_logs", routingKey: "warning");channel.QueueBind(queue: queueName, exchange: "direct_logs", routingKey: "error");Console.WriteLine($" [*] Waiting for WARNINGS and ERRORS only. Queue: {queueName}");var consumer = new EventingBasicConsumer(channel);consumer.Received += (model, ea) =>{var body = ea.Body.ToArray();var message = Encoding.UTF8.GetString(body);Console.WriteLine($" [x] [WARN+ERR] Received '{ea.RoutingKey}':'{message}'");};channel.BasicConsume(queue: queueName,autoAck: true,consumer: consumer);Console.WriteLine(" Press [enter] to exit.");Console.ReadLine();
}

第5步:编写只接收错误的消费者(ReceiveErrorsOnly.cs)

using System.Text;
using RabbitMQ.Client;
using RabbitMQ.Client.Events;var factory = new ConnectionFactory() { HostName = "localhost", UserName = "myuser", Password = "mypassword" };using (var connection = factory.CreateConnection())
using (var channel = connection.CreateModel())
{channel.ExchangeDeclare(exchange: "direct_logs", type: ExchangeType.Direct);var queueName = channel.QueueDeclare().QueueName;// 只绑定到error级别channel.QueueBind(queue: queueName, exchange: "direct_logs", routingKey: "error");Console.WriteLine($" [*] Waiting for ERRORS only. Queue: {queueName}");var consumer = new EventingBasicConsumer(channel);consumer.Received += (model, ea) =>{var body = ea.Body.ToArray();var message = Encoding.UTF8.GetString(body);Console.WriteLine($" [x] [ERRORS ONLY] Received '{ea.RoutingKey}':'{message}'");// 模拟错误处理(比如发送警报邮件)Console.WriteLine("    -> Sending alert email to admin...");Thread.Sleep(1000);};channel.BasicConsume(queue: queueName,autoAck: true,consumer: consumer);Console.WriteLine(" Press [enter] to exit.");Console.ReadLine();
}

第6步:运行与演示

  1. 启动所有消费者
    打开四个终端窗口,分别运行:

    # 终端1 - 接收所有日志
    cd ReceiveLogsDirect
    dotnet run# 终端2 - 接收警告和错误
    cd ReceiveWarningsAndErrors  
    dotnet run# 终端3 - 只接收错误
    cd ReceiveErrorsOnly
    dotnet run# 终端4 - 用于发送消息
    cd EmitLogDirect
  2. 查看管理后台
    访问 http://localhost:15672,查看direct_logs交换机的绑定情况:

    • 你应该看到三个队列,每个队列有不同的绑定键组合。

    • ReceiveLogsDirect的队列绑定了三个键。

    • ReceiveWarningsAndErrors的队列绑定了两个键。

    • ReceiveErrorsOnly的队列只绑定了一个键。

  3. 发送不同级别的日志消息

     
     
    # 发送info消息
    dotnet run info "User login successful"# 发送warning消息  
    dotnet run warning "Database connection slow"# 发送error消息
    dotnet run error "Payment service unavailable"# 发送另一个info消息
    dotnet run info "Cache updated successfully"
  4. 观察路由结果
    观察各个消费者的输出:

    • 信息级别(info)消息:

      • ReceiveLogsDirect:✅ 接收(因为它绑定了info)

      • ReceiveWarningsAndErrors:❌ 不接收

      • ReceiveErrorsOnly:❌ 不接收

    • 警告级别(warning)消息:

      • ReceiveLogsDirect:✅ 接收

      • ReceiveWarningsAndErrors:✅ 接收

      • ReceiveErrorsOnly:❌ 不接收

    • 错误级别(error)消息:

      • ReceiveLogsDirect:✅ 接收

      • ReceiveWarningsAndErrors:✅ 接收

      • ReceiveErrorsOnly:✅ 接收(并模拟发送警报)

  5. 测试多重绑定效果
    再启动一个ReceiveErrorsOnly消费者(第二个实例):

     
     
    cd ReceiveErrorsOnly
    dotnet run

    发送一条error消息,你会发现两个ReceiveErrorsOnly实例都会收到消息,因为它们都使用相同的绑定键绑定到了同一个交换机。这展示了直连交换机也支持"一个路由键,多个队列"的广播式路由。


本章总结

在这一章中,我们学习了比扇形交换机更智能的直连交换机,并实现了精确的消息路由:

  1. 直连交换机(Direct Exchange):基于路由键和绑定键的精确匹配进行消息路由。

  2. 路由键与绑定键:理解了生产者指定路由键、消费者指定绑定键的分工。

  3. 多重绑定:掌握了队列可以绑定多个路由键,以及多个队列可以绑定相同路由键的灵活配置。

  4. 选择性消息消费:实现了消费者只接收特定类型消息的智能日志系统。

直连交换机提供了精确的路由控制,但有时候我们需要更灵活的模式匹配。在下一章,我们将学习功能最强大的主题交换机(Topic Exchange),它支持通配符匹配,能够实现极其复杂的消息路由规则。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/914298.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

网站做的好的tkd培训机构怎么做线上推广

原文 http://www.cnblogs.com/BoyceYang/archive/2013/06/15/3138142.html 阅读导航 1. 概述 2. 规范逻辑数据库设计 3. 使用高效索引设计 4. 使用高效的查询设计 5. 使用技术分析低性能 6. 总结 1. 概述 在比较大的范围内找出能够大幅提高性能的区域,并且专注于分析…

网站内容与功能设计与实现的wordpress 主页 慢

大家好,我是微三云周丽,今天给大家分析当下市场比较火爆的商业模式! 小编今天跟大伙们分享什么是社交电商与拼购玩法的wan美结合? 随着社交电商和拼购玩法的兴起,全民拼购模式正逐渐成为电商行业的新宠。结合了人性化…

网站页面类型中国去中心化搜索引擎

编程器可以做什么游戏:探索游戏开发的无限可能 编程器,作为游戏开发的核心工具,赋予了开发者创造独特游戏体验的能力。那么,编程器究竟可以做什么游戏呢?本文将从四个方面、五个方面、六个方面和七个方面,…

移动互联网网站建设网站设计 布局

文章目录 1 简介2 Docker安装与配置2.1 安装Docker2.2 配置Docker镜像加速器2.3 调整Docker资源限制 3 准备Elasticsearch Docker镜像3.1 下载Elasticsearch镜像3.2 自定义镜像配置3.3执行Docker Compose 4 运行Elasticsearch容器4.1 创建Elasticsearch容器4.2 修改配置文件4.3…

前程无忧做简历网站网站已运行时间代码

在视频编辑和处理的领域,转换格式是一项常见的任务。在某些编辑和发布工作中,可能需要使用WMV格式。提前将素材转换为WMV可以节省在编辑过程中的时间和精力。从MP4到WMV的批量转换,不仅能使视频素材在不同的平台和设备上得到更好的兼容性&…

吴江那里有做公司网站的政务网站建设依据国家

初步认识JUnit 目前大多数的基于Java的企业应用软件,肯定少不了单元测试,程序员通过编写单元测试来验证自己程序的有效性;管理者通过持续自动的执行单元测试和分析单元测试覆盖率来确保软件本身的质量。可以说单元测试和集成测试在软件开发整…

怎么开个人网站赚钱网络推广公司名称

std::thread是C11线程库提供的线程创建。参数绑定的是线程需要调用的函数与参数。 1、如何创建 std::thread th;//空的, std::thread th1([]() { //匿名函数, //执行线程代码 }); void thFun(int k); std::thread th(thFun,10);// thFun为…

科技公司网站php源码wordpress被禁

在 Git 中,如果你想从本地其他设备上获取分支,可以通过以下几种方式实现。不过,需要注意的是,Git 本身是分布式版本控制系统,通常我们是从远程仓库(如 GitHub、GitLab 等)拉取分支,而…

网站建站时间查询许昌网站建设汉狮怎么样

PAGE \* MERGEFORMAT43《软件工程》(第五版)习题参考答案第1章 一、判断题1、()软件的维护与硬件维护本质上是相同的。 2、(√)软件在运行和使用中也存在退化问题。 3、()软件危机的产生主要是因为程序设计人员使用了不适当的程序设计语言。 4、(√)软件同其他事物一样&#xf…

搜索百科(4):OpenSearch — 开源搜索的新选择

大家好,我是 INFINI Labs 的石阳。 欢迎关注 《搜索百科》 专栏!每天 5 分钟,带你速览一款搜索相关的技术或产品,同时还会带你探索它们背后的技术原理、发展故事及上手体验等。 上一篇我们围观了 “流量明星” Ela…

怎么学好网站开发开发网站性能监控

这是王垠发表的一篇文章,转给大家看看,希望有些收获王垠是谁?王垠,四川大学97级本科毕业,保送到清华大学计算机系直博。期间曾在清华大学计算机系软件所就读,主要进行集成电路布线算法的研究。在此期间&…

广州视频网站建站公司做淘宝客网站制作教程视频教程

目的 搜索框搜索内容重载数据只显示搜索到的结果 遇到的问题 在layui官方文档里介绍的table属性有data项,但使用下列代码 table.reload(test, {data:data //data为json数据}); 时发现,会会重新调用table.render的url拿到原来的数据,并不会显示出来传…

美容院怎么建立自己的网站国企网站建设报告

文章目录 Lambda表达式作用前提函数式接口特点 语法省略模式和匿名对象类的区别 Stream流思想作用三类方法获取方法单列集合(Collection[List,Set双列集合Map(不能直接获取)数组同一类型元素(Stream中的静态方法) 常见的中间方法终结方法收集方法 Optional类 Lambda表达式 作用…

网站导航做外链html5视频播放器 js

Deque(双向队列) 是一种优化了的、对序列两端元素进行添加和删除操作的基本序列容器。它允许较为快速地随机访问,但它不像vector 把所有的对象保存在一块连续的内存块,而是采用多个连续的存储块,并且在一个映射结构中保存对这些块及其顺序的跟踪。向deque 两端添加或删除元…

免费的域名注册网站做哪些网站比较赚钱方法

1.ROOT权限开启 2.开启网络桥接模式,选择静态IP设置,点击安装桥接网卡,填写IP地址(注意:IP地址要与host主机在同一IP段内) 3.重启后 adb shell就能进入到模拟器控制台中了,如果出现以下内容&…

公司招聘网站排行榜专业从事网站开发公司

前言 今天参考的开源组件Graceful Response——Spring Boot接口优雅响应处理器。 具体用法可以参考github以及官方文档。 基本使用 引入Graceful Response组件 项目中直接引入如下maven依赖&#xff0c;即可使用其相关功能。 <dependency><groupId>com.feiniaoji…

做网站有什么建议wordpress导航源码

勤劳是最基本的&#xff0c;所能做的就是花更多的时间在上面。 就算最后不能成功&#xff0c;尽力就好。 First . 充分清楚需求改造内容&#xff0c;具体到 哪个字段、逻辑处理等。 这是编码的核心&#xff0c;清楚了需求才能进行编码&#xff0c;也决定了你编码后续的测试情况…

国人在线做网站爱站网长尾关键词挖掘工具下载

在计算机使用过程中&#xff0c;我们经常会遇到一些错误提示&#xff0c;其中之一就是“找不到d3dcompiler_43.dll文件”。那么&#xff0c;d3dcompiler_43.dll是什么文件&#xff1f;它的作用是什么&#xff1f;如果缺失了该如何修复呢&#xff1f;本文将详细介绍d3dcompiler_…

做外贸平台还是网站怎么做捕鱼网站

粒子物理和原子核物理的理论可以应用于模拟和分析电路中的粒子束和辐射效应&#xff0c;特别是在粒子加速器和辐射探测器的设计和优化方面。通过这些理论的应用&#xff0c;可以提高加速器和探测器的性能&#xff0c;推动粒子物理和原子核物理的研究进展。粒子物理和原子核物理…

摄影网站的模板公司大气聚财的名字

前言 在实际开发中,我们经常需要处理一些周期性或定时的任务,比如每天凌晨进行数据统计、报表生成,或者每隔一段时间清理缓存等。Spring Boot 集成了 Quartz 和 Spring 自带的 TaskScheduler 等多种定时任务框架,使得实现定时任务变得非常方便。本文将通过一个详细的示例,…