服务异步通讯与RabbitMQ

server/2025/3/1 0:36:17/

服务异步通讯

文章目录

  • 服务异步通讯
  • MQ
  • RabbitMQ
      • 1、安装(部署)
      • 2、结构
      • 3、消息模型
      • 4、SpringAMQP
        • 4.1、基本消息队列
        • 4.2、工作消息队列
        • 4.3、发布订阅模型
          • 4.3.1、FanoutExchange(广播类型的交换机)
          • 4.3.2、DirectExchange(路由类型的交换机)
          • 4.3.3、TopicExchange(话题类型的交换机)
      • 5、消息转换器

异步通讯是相对于同步通讯而言的。
微服务之间同步调用的优点:

  • 时效性较强,可以立即得到结果

微服务之间同步调用的缺点:

  • 微服务的耦合度高
  • 性能和吞吐能力下降
  • 有额外的资源消耗
  • 有级联失败问题

异步调用的常见实现是事件驱动模式
在这里插入图片描述
异步通信的优点:

  • 服务之间的耦合度降低
  • 吞吐量提升
  • 故障隔离
  • 流量削峰

异步通信的缺点:

  • 依赖于Broker的可靠性、安全性、吞吐能力
  • 架构复杂了,业务没有明显的流程线,不好追踪管理

MQ

在这里插入图片描述

RabbitMQ

1、安装(部署)

两种部署方式:单机部署和集群部署,在此演示单机部署

  1. docker pull rabbitmq:3-management

  2. docker run \
    -e RABBITMQ_DEFAULT_USER=hekai \
    -e RABBITMQ_DEFAULT_PASS=123456 \
    –name mq \
    –hostname mq1 \
    -p 15672:15672 \
    -p 5672:5672 \
    -d \
    rabbitmq:3-management

  3. 访问RabbitMQ后台
    浏览器输入,服务器IP:15672
    在这里插入图片描述
    输入用户名:hekai,密码:123456,登录即可
    在这里插入图片描述

2、结构

RabbitMQ的结构
在这里插入图片描述
概念:

  • channel:操作MQ的工具
  • exchange:路由消息到队列中
  • queue:缓存消息
  • virtual host:虚拟主机,对exchange、queue等资源的分组

3、消息模型

在这里插入图片描述
基本消息队列的使用流程:
在这里插入图片描述

4、SpringAMQP

SpringAMQP的官方地址:https://spring.io/projects/spring-amqp
在这里插入图片描述
SpringAMQP能够简化3中消息发送和消息接收的步骤
接下来讲解5种消息模型的逻辑和实现

4.1、基本消息队列

基本消息队列:一个队列绑定一个消费者
逻辑:
在这里插入图片描述
实现:
1、引依赖
在这里插入图片描述
2、消息发送方的微服务中编写RabbitMQ的配置,方法中使用RabbitTemplate调用convertAndSend方法发送消息
在这里插入图片描述
3、消息接收方的微服务中编写RabbitMQ的配置, 处理消息的方法上添加@RabbitListener注解。注解的参数是监听的队列名称,方法参数是消息
在这里插入图片描述
注意:消息一旦消费就会从队列中删除。RabbitMQ没有消息回溯功能(但可以通过死信队列或其他方式实现消息回溯功能)

4.2、工作消息队列

工作消息队列:一个队列绑定多个消费者,同一条消息只会被一个消费者处理,因为消息一旦被消费就会从队列中删除。可以提高消息处理速度,避免队列中消息堆积。
在这里插入图片描述
实现:
在基本消息队列的基础上,消费者再定义一个加了@RabbitListener注解的方法即可,监听同一个队列

注意:RabbitMQ默认的预取的消息数量是没有上限的,这会导致不同处理消息能力的监听器取到并消费的消息数量是一样的,降低了服务的性能,因此在消息消费方的微服务中要配置RabbitMQ预取的消息数量,设置为1,控制预取消息的上限
在这里插入图片描述

4.3、发布订阅模型

发布订阅模式与上述两种模式的区别在于发布订阅模式允许同一条消息发送给多个消费者消费。实现方式就是加入了Exchange(交换机),交换机可以绑定多个队列,将同一条消息发送给绑定的多个队列中,从而实现多个消费者消费同一条消息。(队列中的消息始终只能被一个消费者消费)
在这里插入图片描述
在发布订阅模型中,交换机与队列有这几种绑定方式:广播、路由、话题等,分别对应着三种交换机:FanoutExchange、DirectExchange、TopicExchange
注意:Exchange只负责消息的转发,不负责消息的存储,一旦消息转发失败,则这条消息就会丢失

4.3.1、FanoutExchange(广播类型的交换机)

FanoutExchange会将接收到的消息路由到每一个跟其绑定的queue
在这里插入图片描述
逻辑:
在这里插入图片描述

实现:
1、在消费消息的服务中,代码声明交换机和队列,并绑定
在这里插入图片描述
2、在消费消息的服务中,编写监听队列的方法
在这里插入图片描述
3、编写发送消息的方法,指定交换机名称和消息,routingKey为空字符串
在这里插入图片描述

4.3.2、DirectExchange(路由类型的交换机)

在这里插入图片描述
此外,优化一下Exchange、queue、binding的声明,上述在FanoutExchange中这些都是使用Bean声明的,比较麻烦。这里使用@RabbitListener注解声明。

逻辑:
在这里插入图片描述
实现:
1、使用@RabbitListener注解声明Binding、Exchange、Queue、RoutingKey,并编写消费消息的方法体
在这里插入图片描述
2、消息发送方的微服务中编写消息方法的方法,向交换机发送消息
在这里插入图片描述
DirectExchange与FanoutExchange的区别:FanoutExchange会将消息发送给与之绑定的所有的队列,而DirectExchange只会将消息发送给与之绑定的且RoutingKey和队列的BindingKey一致的队列

4.3.3、TopicExchange(话题类型的交换机)

在这里插入图片描述
逻辑:
在这里插入图片描述
实现:
具体实现与上述的DirectExchange的实现类似,只是交换机类型、bindingkey和发送消息时指定的routingkey不同罢了
在这里插入图片描述
在这里插入图片描述

5、消息转换器

在SpringAMQP的发送方法时,消息的类型是Object,也就是说可以发送任意对象类型的消息,比如String、Map、List,自定义的Java对象等,SpringAMQP会将消息序列化为字节后再发送。

发送消息不用改,在发送消息的微服务中引入下面的依赖并声明MessageConverter的Bean即可
在这里插入图片描述
在接收消息的微服务中也要引入下面的依赖并声明MessageConverter的Bean;接收消息时消息的类型要与发送消息时消息的类型一致,因为要将消息反序列化。其他代码不用改
在这里插入图片描述
总结:
在这里插入图片描述


http://www.ppmy.cn/server/171422.html

相关文章

【Redis】在Java中以及Spring环境下操作Redis

Java环境下&#xff1a; 1.创建maven 项目 2.导入依赖 <!-- redis --><dependency><groupId>redis.clients</groupId><artifactId>jedis</artifactId><version>4.3.2</version></dependency> 此处使用的是Jedis&…

Buildroot 添加自定义模块-内置文件到文件系统

目录 概述实现步骤1. 创建包目录和文件结构2. 配置 Config.in3. 定义 cp_bin_files.mk4. 添加源文件install.shmy.conf 5. 配置与编译 概述 Buildroot 是一个高度可定制和模块化的嵌入式 Linux 构建系统&#xff0c;适用于从简单到复杂的各种嵌入式项目. buildroot的源码中bui…

五、AIGC大模型_04LLaMA-Factory基础知识与SFT实战

1、LLaMA-Factory 基本介绍 1.1 定义 LLaMA-Factory 是一个开源的大型语言模型&#xff08;LLM&#xff09;微调框架&#xff0c;旨在帮助开发者和研究人员轻松地对预训练语言模型进行定制化训练和优化 1.2 功能特点 支持多种预训练模型 LLaMA Factory 支持超过 100 种主流的…

2025年信息科学与工程学院科协机器学习介绍——机器学习基本模型介绍

机器学习 目录 机器学习一.安装基本环境conda/miniconda环境 二.数据操作数据预处理一维数组二维数组以及多维数组的认识访问元素的方法torch中tenson的应用张量的运算张量的广播 三.线性代数相关知识四.线性回归SoftMax回归问题&#xff08;分类问题&#xff09;什么是分类问题…

面试问题——如何解决移动端1px 边框问题?

面试问题——如何解决移动端1px 边框问题&#xff1f; 最近&#xff0c;不少小伙伴向我反映&#xff0c;他们在面试中频繁被问到关于1px边框的问题。这个看似老生常谈的话题&#xff0c;没想到在面试中的出现率依然这么高&#xff0c;着实让我有些意外。对于那些对这个问题感到…

Kubernetes (K8S) 核心原理深度剖析:从架构设计到运行机制

Kubernetes(K8S)作为容器编排领域的“操作系统”,其设计和实现原理是开发者进阶的必修课。本文将从架构设计、核心组件协作、关键机制实现三个维度,结合源码逻辑与实战场景,分享 K8S 的底层运行原理。 一、Kubernetes 架构设计 1. 声明式 API 与控制器模式 K8S 的核心设…

DaoCloud 亮相 2025 GDC丨开源赋能 AI 更多可能

2025 年 2 月 21 日至 23 日&#xff0c;上海徐汇西岸&#xff0c;2025 全球开发者先锋大会以 “模塑全球&#xff0c;无限可能” 的主题&#xff0c;围绕云计算、机器人、元宇宙等多元领域&#xff0c;探讨前沿技术创新、应用场景拓展和产业生态赋能&#xff0c;各类专业论坛、…

python-leetcode-最长公共子序列

1143. 最长公共子序列 - 力扣&#xff08;LeetCode&#xff09; class Solution:def longestCommonSubsequence(self, text1: str, text2: str) -> int:m, n len(text1), len(text2)dp [[0] * (n 1) for _ in range(m 1)]for i in range(1, m 1):for j in range(1, n …