当前位置: 首页 > news >正文

RabbitMQ-交换机

文章目录

    • 交换机
      • fanout
      • Direct
      • topic
      • Headers
      • RPC

交换机

**交换机 **是消息队列中的一个组件,其作用类似于网络路由器。它负责将我们发送的消息转发到相应的目标,就像快递站将快递发送到对应的站点,或者网络路由器将网络请求转发到相应的服务器或客户端一样。交换机的主要功能是提供转发消息的能力,根据消息的路由规则将消息投递到合适的队列或绑定的消费者。
我们可以理解为,如果说一个快递站已经承受不了那么多的快递了,就建多个快递站。

fanout

扇出,广播
特点:消息会被转发到所有绑定到该交换机的队列
场景:很适用于发布订阅的场景,比如写日志,可以多个系统间共享

示例场景:
image.png
生产者代码:

package com.yupi.springbootinit.mq;import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;import java.util.Scanner;public class FanoutProducer {// 交换机名字private static final String EXCHANGE_NAME = "fanout-exchange";public static void main(String[] argv) throws Exception {ConnectionFactory factory = new ConnectionFactory();factory.setHost("localhost");try (Connection connection = factory.newConnection();Channel channel = connection.createChannel()) {// 创建交换机channel.exchangeDeclare(EXCHANGE_NAME, "fanout");Scanner scanner = new Scanner(System.in);while (scanner.hasNext()) {String message = scanner.nextLine();channel.basicPublish(EXCHANGE_NAME, "", null, message.getBytes("UTF-8"));System.out.println(" [x] Sent '" + message + "'");}}}
}

消费者代码:

package com.yupi.springbootinit.mq;import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.DeliverCallback;public class FanoutConsumer {//交换机名字private static final String EXCHANGE_NAME = "fanout-exchange";public static void main(String[] argv) throws Exception {//建立连接ConnectionFactory factory = new ConnectionFactory();factory.setHost("localhost");Connection connection = factory.newConnection();//创建频道Channel channel1 = connection.createChannel();// 声明交换机channel1.exchangeDeclare(EXCHANGE_NAME, "fanout");// 创建队列1,连接到交换机上String queueName = "xiaowang_queue";channel1.queueDeclare(queueName, true, false, false, null);channel1.queueBind(queueName, EXCHANGE_NAME, "");// 创建队列2,连接到交换机上String queueName2 = "xiaoli_queue";channel1.queueDeclare(queueName2, true, false, false, null);channel1.queueBind(queueName2, EXCHANGE_NAME, "");System.out.println(" [*] Waiting for messages. To exit press CTRL+C");// 创建交付回调函数1DeliverCallback deliverCallback1 = (consumerTag, delivery) -> {String message = new String(delivery.getBody(), "UTF-8");System.out.println(" [小王] Received '" + message + "'");};// 创建交付回调函数2DeliverCallback deliverCallback2 = (consumerTag, delivery) -> {String message = new String(delivery.getBody(), "UTF-8");System.out.println(" [小李] Received '" + message + "'");};// 开始消费消息队列1channel1.basicConsume(queueName, true, deliverCallback1, consumerTag -> { });// 开始消费消息队列2channel1.basicConsume(queueName2, true, deliverCallback2, consumerTag -> { });}
}

Direct

官方教程:https://www.rabbitmq.com/tutorials/tutorial-four-java.html
特点:消息会根据路由键转发到指定的队列
场景:特定的消息只交给特定的系统(程序)来处理

注意:不同队列可以绑定相同的路由键

示例场景:
老板在发送消息同时会带上路由键,根据路由键找对应的队列来发送
image.png
生产者代码:

package com.yupi.springbootinit.mq;import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;import java.util.Scanner;public class DirectProducer {private static final String EXCHANGE_NAME = "direct-exchange";public static void main(String[] argv) throws Exception {ConnectionFactory factory = new ConnectionFactory();factory.setHost("localhost");try (Connection connection = factory.newConnection();Channel channel = connection.createChannel()) {//声明交换机是directchannel.exchangeDeclare(EXCHANGE_NAME, "direct");//输入消息 和 路由键Scanner scanner = new Scanner(System.in);while (scanner.hasNext()) {String userInput = scanner.nextLine();String[] strings = userInput.split(" ");if (strings.length < 1) {continue;}String message = strings[0];String routingKey = strings[1];//发布消息的时候注意指定路由键channel.basicPublish(EXCHANGE_NAME, routingKey, null, message.getBytes("UTF-8"));System.out.println(" [x] Sent '" + message + " with routing:" + routingKey + "'");}}}
}

消费者代码:

package com.yupi.springbootinit.mq;import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.DeliverCallback;public class DirectConsumer {private static final String EXCHANGE_NAME = "direct-exchange";public static void main(String[] argv) throws Exception {ConnectionFactory factory = new ConnectionFactory();factory.setHost("localhost");Connection connection = factory.newConnection();Channel channel = connection.createChannel();//声明交换机,不过生成者已经声明过了,消费者声不声明都可以channel.exchangeDeclare(EXCHANGE_NAME, "direct");// 创建队列String queueName = "xiaoyu_queue";channel.queueDeclare(queueName, true, false, false, null);channel.queueBind(queueName, EXCHANGE_NAME, "xiaoyu"); //指定2交换机和路由键// 创建队列,随机分配一个队列名称String queueName2 = "xiaopi_queue";channel.queueDeclare(queueName2, true, false, false, null);channel.queueBind(queueName2, EXCHANGE_NAME, "xiaopi");System.out.println(" [*] Waiting for messages. To exit press CTRL+C");DeliverCallback xiaoyuDeliverCallback = (consumerTag, delivery) -> {String message = new String(delivery.getBody(), "UTF-8");System.out.println(" [xiaoyu] Received '" +delivery.getEnvelope().getRoutingKey() + "':'" + message + "'");};DeliverCallback xiaopiDeliverCallback = (consumerTag, delivery) -> {String message = new String(delivery.getBody(), "UTF-8");System.out.println(" [xiaopi] Received '" +delivery.getEnvelope().getRoutingKey() + "':'" + message + "'");};channel.basicConsume(queueName, true, xiaoyuDeliverCallback, consumerTag -> {});channel.basicConsume(queueName2, true, xiaopiDeliverCallback, consumerTag -> {});}
}

topic

官方教程:https://www.rabbitmq.com/tutorials/tutorial-five-java.html
特点:消息会根据一个模糊的路由键转发到指定的队列
场景:特定的一类消息可以交给特定的一类系统(程序)来处理
规则:

  1. :匹配一个单词,比如.orange,那么 abc.orange、ikun.orange 都能匹配
  2. #:匹配0个或多个单词,比如orange.#,那么orange,orange.abc.ikun都能匹配


应用场景:
老板要下发一个任务,让多个组来处理
image.png
生产者代码:

package com.yupi.springbootinit.mq;import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;import java.util.Scanner;public class TopicProducer {private static final String EXCHANGE_NAME = "topic-exchange";public static void main(String[] argv) throws Exception {ConnectionFactory factory = new ConnectionFactory();factory.setHost("localhost");try (Connection connection = factory.newConnection();Channel channel = connection.createChannel()) {channel.exchangeDeclare(EXCHANGE_NAME, "topic");Scanner scanner = new Scanner(System.in);while (scanner.hasNext()) {String userInput = scanner.nextLine();String[] strings = userInput.split(" ");if (strings.length < 1) {continue;}String message = strings[0];String routingKey = strings[1];channel.basicPublish(EXCHANGE_NAME, routingKey, null, message.getBytes("UTF-8"));System.out.println(" [x] Sent '" + message + " with routing:" + routingKey + "'");}}}
}

消费者代码:

package com.yupi.springbootinit.mq;import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.DeliverCallback;public class TopicConsumer {private static final String EXCHANGE_NAME = "topic-exchange";public static void main(String[] argv) throws Exception {ConnectionFactory factory = new ConnectionFactory();factory.setHost("localhost");Connection connection = factory.newConnection();Channel channel = connection.createChannel();channel.exchangeDeclare(EXCHANGE_NAME, "topic");// 创建队列String queueName = "frontend_queue";channel.queueDeclare(queueName, true, false, false, null);channel.queueBind(queueName, EXCHANGE_NAME, "#.前端.#");// 创建队列String queueName2 = "backend_queue";channel.queueDeclare(queueName2, true, false, false, null);channel.queueBind(queueName2, EXCHANGE_NAME, "#.后端.#");// 创建队列String queueName3 = "product_queue";channel.queueDeclare(queueName3, true, false, false, null);channel.queueBind(queueName3, EXCHANGE_NAME, "#.产品.#");System.out.println(" [*] Waiting for messages. To exit press CTRL+C");DeliverCallback xiaoaDeliverCallback = (consumerTag, delivery) -> {String message = new String(delivery.getBody(), "UTF-8");System.out.println(" [xiaoa] Received '" +delivery.getEnvelope().getRoutingKey() + "':'" + message + "'");};DeliverCallback xiaobDeliverCallback = (consumerTag, delivery) -> {String message = new String(delivery.getBody(), "UTF-8");System.out.println(" [xiaob] Received '" +delivery.getEnvelope().getRoutingKey() + "':'" + message + "'");};DeliverCallback xiaocDeliverCallback = (consumerTag, delivery) -> {String message = new String(delivery.getBody(), "UTF-8");System.out.println(" [xiaoc] Received '" +delivery.getEnvelope().getRoutingKey() + "':'" + message + "'");};channel.basicConsume(queueName, true, xiaoaDeliverCallback, consumerTag -> {});channel.basicConsume(queueName2, true, xiaobDeliverCallback, consumerTag -> {});channel.basicConsume(queueName3, true, xiaocDeliverCallback, consumerTag -> {});}
}

这样生产者发消息:前端.后端
image.png
就可以匹配到前端和后端两个队列
image.png

Headers

可以根据headers中的内容来指定发送到哪个队列,由于性能差,比较复杂,一般不推荐使用

RPC

支持用消息队列来模拟RPC的调用,但是一般没必要,直接用 Dubbo、GRPC 等 RPC 框架就好了。

相关文章:

RabbitMQ-交换机

文章目录 交换机fanoutDirecttopicHeadersRPC 交换机 **交换机 **是消息队列中的一个组件&#xff0c;其作用类似于网络路由器。它负责将我们发送的消息转发到相应的目标&#xff0c;就像快递站将快递发送到对应的站点&#xff0c;或者网络路由器将网络请求转发到相应的服务器…...

mapreduce中的MapTask工作机制(Hadoop)

MapTask工作机制 MapReduce中的Map任务是整个计算过程的第一阶段&#xff0c;其主要工作是将输入数据分片并进行处理&#xff0c;生成中间键值对&#xff0c;为后续的Shuffle和Sort阶段做准备。 1. 输入数据的划分&#xff1a; 输入数据通常存储在分布式文件系统&#xff08;…...

景区文旅剧本杀小程序亲子公园寻宝闯关系统开发搭建

要开发景区文旅剧本杀小程序亲子公园寻宝闯关系统&#xff0c;您需要考虑以下步骤&#xff1a; 1. 设计游戏场景和规则&#xff1a;根据亲子公园的主题和特点&#xff0c;设计适合亲子游玩的游戏场景和规则。您需要考虑游戏的安全性、趣味性和互动性&#xff0c;确保孩子们能够…...

性能优化---webpack优化

1、如何提高webpack打包速度 a、优化Loader--影响Loader打包速度的首要元素是Babel&#xff0c;Babel 会将代码转为字符串生成 AST&#xff0c;然后对 AST 继续进行转变最后再生成新的代码&#xff0c;项目越大&#xff0c;转换代码越多&#xff0c;效率就越低。先优化 Loader …...

YOLOv9改进策略 | 损失函数篇 | EIoU、SIoU、WIoU、DIoU、FocusIoU等二十余种损失函数

一、本文介绍 这篇文章介绍了YOLOv9的重大改进&#xff0c;特别是在损失函数方面的创新。它不仅包括了多种IoU损失函数的改进和变体&#xff0c;如SIoU、WIoU、GIoU、DIoU、EIOU、CIoU&#xff0c;还融合了“Focus”思想&#xff0c;创造了一系列新的损失函数。这些组合形式的…...

贪心算法-跳跃游戏

给你一个非负整数数组 nums &#xff0c;你最初位于数组的 第一个下标 。数组中的每个元素代表你在该位置可以跳跃的最大长度。 判断你是否能够到达最后一个下标&#xff0c;如果可以&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。 示例 1&#xff1a; 输…...

sql知识总结二

一.报错注入 1.什么是报错注入&#xff1f; 这是一种页面响应形式&#xff0c;响应过程如下&#xff1a; 用户在前台页面输入检索内容----->后台将前台输入的检索内容无加区别的拼接成sql语句&#xff0c;送给数据库执行------>数据库将执行的结果返回给后台&#xff…...

VSCode和CMake实现C/C++开发

VSCode和CMake实现Ubuntu下C/C++开发总结 目录 0.简介1.Linux系统介绍2.开发环境搭建2.1 编译器,调试器安装2.2 CMake安装3.GCC编译器3.1 编译过程3.2 g++重要编译参数4.g++编译实战4.0 编译前4.1 直接编译4.2 生成库文件并编译4.3 编译后4.3.1 编译完成后的目录结构4.3.2 运行…...

【机器学习300问】74、如何理解深度学习中L2正则化技术?

深度学习过程中&#xff0c;若模型出现了过拟合问题体现为高方差。有两种解决方法&#xff1a; 增加训练样本的数量采用正则化技术 增加训练样本的数量是一种非常可靠的方法&#xff0c;但有时候你没办法获得足够多的训练数据或者获取数据的成本很高&#xff0c;这时候正则化技…...

C语言程序设计每日一练(4)

完全平方数 首先&#xff0c;我们需要明确什么是完全平方数。完全平方数是指一个整数&#xff0c;它可以表示为另一个整数的平方。例如&#xff0c;1、4、9、16等都是完全平方数&#xff0c;因为它们分别是1、2、3、4的平方。 现在&#xff0c;让我们回到这个问题。我们知道这…...

m4p转换mp3格式怎么转?3个Mac端应用~

M4P文件格式的诞生伴随着苹果公司引入FairPlay版权管理系统&#xff0c;该系统旨在保护音频的内容。M4P因此而生&#xff0c;成为受到FairPlay系统保护的音频格式&#xff0c;常见于苹果设备的iTunes等平台。 MP3文件格式的多个优点 MP3格式的优点显而易见。首先&#xff0c;其…...

全国产化无风扇嵌入式车载电脑在车队管理嵌入式车载行业应用

车队管理嵌入式车载行业应用 车队管理方案能有效解决车辆繁多管理困难问题&#xff0c;配合调度系统让命令更加精确有效执行。实时监控车辆状况、行驶路线和位置&#xff0c;指导驾驶员安全有序行驶&#xff0c;有效降低保险成本、事故概率以及轮胎和零部件的磨损与损坏。 方…...

爬虫入门——Request请求

目录 前言 一、Requests是什么&#xff1f; 二、使用步骤 1.引入库 2.请求 3.响应 三.总结 前言 上一篇爬虫我们已经提及到了urllib库的使用&#xff0c;为了方便大家的使用过程&#xff0c;这里为大家介绍新的库来实现请求获取响应的库。 一、Requests是什么&#xff1…...

创建一个javascript公共方法的npm包,js-tool-big-box,发布到npm上,一劳永逸

前端javascript的公共方法太多了&#xff0c;时间日期的&#xff0c;数值的&#xff0c;字符串的&#xff0c;搞复制的&#xff0c;搞网络请求的&#xff0c;搞数据转换的&#xff0c;几乎就是每个新项目&#xff0c;有的拷一拷&#xff0c;没有的继续写&#xff0c;放个utils目…...

【在线OJ系统】自定义注解实现分布式ID无感自增

实现思路 首先自定义参数注解&#xff0c;然后根据AOP思想&#xff0c;找到该注解作用的切点&#xff0c;也就是mapper层对于mapper层的接口在执行前都会执行该aop操作&#xff1a;获取到对于的方法对象&#xff0c;根据方法对象获取参数列表&#xff0c;根据参数列表判断某个…...

35. UE5 RPG制作火球术技能

接下来&#xff0c;我们将制作技能了&#xff0c;总算迈进了一大步。首先回顾一下之前是如何实现技能触发的&#xff0c;然后再进入正题。 如果想实现我之前的触发方式的&#xff0c;请看此栏目的31-33篇文章&#xff0c;讲解了实现逻辑&#xff0c;这里总结一下&#xff1a; …...

计算机网络 TCP/IP体系 物理层

一. TCP/IP体系 物理层 1.1 物理层的基本概念 物理层作为TCP/IP网络模型的最低层&#xff0c;负责直接与传输介质交互&#xff0c;实现比特流的传输。 要完成物理层的主要任务&#xff0c;需要确定以下特性&#xff1a; 机械特性&#xff1a;物理层的机械特性主要涉及网络…...

微服务相关

1. 微服务主要七个模块 中央管理平台&#xff1a;生产者、消费者注册&#xff0c;服务发现&#xff0c;服务治理&#xff0c;调用关系生产者消费者权限管理流量管理自定义传输协议序列化反序列化 2. 中央管理平台 生产者A在中央管理平台注册后&#xff0c;中央管理平台会给他…...

虚拟机下如何使用Docker(完整版)

Docker详细介绍&#xff1a; Docker 是一款开源的应用容器引擎&#xff0c;由Docker公司最初开发并在2013年发布。Docker的核心理念源自于操作系统级别的虚拟化技术&#xff0c;尤其是Linux上的容器技术&#xff08;如LXC&#xff09;&#xff0c;它为开发人员和系统管理员提供…...

asp.net core 依赖注入后的服务生命周期

ASP.NET Core 依赖注入&#xff08;DI&#xff09;容器支持三种服务的生命周期选项&#xff0c;它们定义了服务实例的创建和销毁的时机。理解这三种生命周期对于设计健壯且高效的应用程序非常重要&#xff1a; 瞬时&#xff08;Transient&#xff09;&#xff1a; 瞬时服务每次…...

微软PowerBI考试 PL300-选择 Power BI 模型框架【附练习数据】

微软PowerBI考试 PL300-选择 Power BI 模型框架 20 多年来&#xff0c;Microsoft 持续对企业商业智能 (BI) 进行大量投资。 Azure Analysis Services (AAS) 和 SQL Server Analysis Services (SSAS) 基于无数企业使用的成熟的 BI 数据建模技术。 同样的技术也是 Power BI 数据…...

【入坑系列】TiDB 强制索引在不同库下不生效问题

文章目录 背景SQL 优化情况线上SQL运行情况分析怀疑1:执行计划绑定问题?尝试:SHOW WARNINGS 查看警告探索 TiDB 的 USE_INDEX 写法Hint 不生效问题排查解决参考背景 项目中使用 TiDB 数据库,并对 SQL 进行优化了,添加了强制索引。 UAT 环境已经生效,但 PROD 环境强制索…...

对WWDC 2025 Keynote 内容的预测

借助我们以往对苹果公司发展路径的深入研究经验&#xff0c;以及大语言模型的分析能力&#xff0c;我们系统梳理了多年来苹果 WWDC 主题演讲的规律。在 WWDC 2025 即将揭幕之际&#xff0c;我们让 ChatGPT 对今年的 Keynote 内容进行了一个初步预测&#xff0c;聊作存档。等到明…...

rnn判断string中第一次出现a的下标

# coding:utf8 import torch import torch.nn as nn import numpy as np import random import json""" 基于pytorch的网络编写 实现一个RNN网络完成多分类任务 判断字符 a 第一次出现在字符串中的位置 """class TorchModel(nn.Module):def __in…...

管理学院权限管理系统开发总结

文章目录 &#x1f393; 管理学院权限管理系统开发总结 - 现代化Web应用实践之路&#x1f4dd; 项目概述&#x1f3d7;️ 技术架构设计后端技术栈前端技术栈 &#x1f4a1; 核心功能特性1. 用户管理模块2. 权限管理系统3. 统计报表功能4. 用户体验优化 &#x1f5c4;️ 数据库设…...

Redis:现代应用开发的高效内存数据存储利器

一、Redis的起源与发展 Redis最初由意大利程序员Salvatore Sanfilippo在2009年开发&#xff0c;其初衷是为了满足他自己的一个项目需求&#xff0c;即需要一个高性能的键值存储系统来解决传统数据库在高并发场景下的性能瓶颈。随着项目的开源&#xff0c;Redis凭借其简单易用、…...

MacOS下Homebrew国内镜像加速指南(2025最新国内镜像加速)

macos brew国内镜像加速方法 brew install 加速formula.jws.json下载慢加速 &#x1f37a; 最新版brew安装慢到怀疑人生&#xff1f;别怕&#xff0c;教你轻松起飞&#xff01; 最近Homebrew更新至最新版&#xff0c;每次执行 brew 命令时都会自动从官方地址 https://formulae.…...

在树莓派上添加音频输入设备的几种方法

在树莓派上添加音频输入设备可以通过以下步骤完成&#xff0c;具体方法取决于设备类型&#xff08;如USB麦克风、3.5mm接口麦克风或HDMI音频输入&#xff09;。以下是详细指南&#xff1a; 1. 连接音频输入设备 USB麦克风/声卡&#xff1a;直接插入树莓派的USB接口。3.5mm麦克…...

多元隐函数 偏导公式

我们来推导隐函数 z z ( x , y ) z z(x, y) zz(x,y) 的偏导公式&#xff0c;给定一个隐函数关系&#xff1a; F ( x , y , z ( x , y ) ) 0 F(x, y, z(x, y)) 0 F(x,y,z(x,y))0 &#x1f9e0; 目标&#xff1a; 求 ∂ z ∂ x \frac{\partial z}{\partial x} ∂x∂z​、 …...

海云安高敏捷信创白盒SCAP入选《中国网络安全细分领域产品名录》

近日&#xff0c;嘶吼安全产业研究院发布《中国网络安全细分领域产品名录》&#xff0c;海云安高敏捷信创白盒&#xff08;SCAP&#xff09;成功入选软件供应链安全领域产品名录。 在数字化转型加速的今天&#xff0c;网络安全已成为企业生存与发展的核心基石&#xff0c;为了解…...