RabbitMQ 介绍与 SpringBootAMQP使用

一、MQ概述

异步通信的优点:

  • 耦合度低
  • 吞吐量提升
  • 故障隔离
  • 流量削峰

异步通信的缺点:

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

什么是的MQ
MQ(Message Queue),消息队列,就是放消息的队列。也是事件驱动架构中的Broker。

RabbitMQActiveMQRocketMQKafka
公司/社区RabbitApache阿里Apache
开发语言ErlangJavaJavaScala&Java
协议支持AMQP、XMPP、
SMTP、STOMP
OpenWire、STOMP、
REST、XMPP、AMQP
自定义协议自定义协议
可用性一般
单机吞吐量一般非常高
消息延迟微秒级毫秒级毫秒级毫秒级
消息可靠性一般一般

二、RabbitMQ概述

1. RabbitMQ的结构和概念

  • Channel:操作MQ的工具
  • Exchange:路由消息到队列中
  • Queue:缓存消息
  • Virtual Host:虚拟主机,是对Queue、Exchange等资源的逻辑分组

在这里插入图片描述
2. 常见消息模型

  • 基本消息队列(BasicQueue)
    在这里插入图片描述

    • Publisher:消息发布者,将消息发送到队列Queue
    • Queue:消息队列,负责接受并缓存消息
    • Consumer:订阅队列,处理队列中的消息

    在这里插入图片描述

  • 工作消息队列(WorkQueue)
    在这里插入图片描述
    Work queues,也被称为(Task queues),任务模型。简单来说就是让多个消费者绑定到一个队列,共同消费队列中的消息

    当消息处理比较耗时的时候,可能生产消息的速度会远远大于消息的消费速度。长此以往,消息就会堆积越来越多,无法及时处理。此时就可以使用work 模型,多个消费者共同进行消息处理,提高消费速度。

    在这里插入图片描述

  • 发布订阅(Publish、Subscribe),根据交换机类型不同分为三种:

  • Publisher:生产者,也就是要发送消息的程序,但是不再发送到队列中,而是发给X(交换机)

  • Exchange:交换机,图中的X。一方面,接收生产者发送的消息。另一方面,知道如何处理消息,例如递交给某个特别队列、递交给所有队列、或是将消息丢弃。到底如何操作,取决于Exchange的类型。Exchange有以下3种类型:

    • Fanout:广播,将消息交给所有绑定到交换机的队列
    • Direct:定向,把消息交给符合指定routing key 的队列
    • Topic:通配符,把消息交给符合routing pattern(路由模式) 的队列
  • Consumer:消费者,与以前一样,订阅队列,没有变化

  • Queue:消息队列也与以前一样,接收消息、缓存消息。

    在这里插入图片描述
    Exchange(交换机)只负责转发消息,不具备存储消息的能力,因此如果没有任何队列与Exchange绑定,或者没有符合路由规则的队列,那么消息会丢失!

在这里插入图片描述

  • Fanout Exchange: 广播
    在这里插入图片描述
    在广播模式下,消息发送流程:

    - 1)  可以有多个队列
    - 2)  每个队列都要绑定到Exchange(交换机)
    - 3)  生产者发送的消息,只能发送到交换机,交换机来决定要发给哪个队列,生产者无法决定
    - 4)  交换机把消息发送给绑定过的所有队列
    - 5)  订阅队列的消费者都能拿到消息
    

在这里插入图片描述

  • Direct Exchange:路由
    在这里插入图片描述

    在Fanout模式中,一条消息会被所有订阅的队列都消费。但是,在某些场景下,希望不同的消息被不同的队列消费。这时就要用到Direct类型的Exchange。
    在这里插入图片描述

    在Direct模型下:

    • 队列与交换机的绑定,不能是任意绑定了,而是要指定一个RoutingKey(路由key)
    • 消息的发送方在 向 Exchange发送消息时,也必须指定消息的 RoutingKey
    • Exchange不再把消息交给每一个绑定的队列,而是根据消息的Routing Key进行判断,只有队列的Routingkey与消息的 Routing key完全一致,才会接收到消息
  • Topic Exchange:主题
    在这里插入图片描述

Topic类型的ExchangeDirect相比,都是可以根据RoutingKey把消息路由到不同的队列。只不过Topic类型Exchange可以让队列在绑定Routing key 的时候使用通配符。

通配符规则:

  • #:匹配一个或多个词
  • *:匹配不多不少恰好1个词

如下图:

  • Queue1:绑定的是china.# ,因此凡是以 china.开头的routing key 都会被匹配到。包括china.news和china.weather
  • Queue2:绑定的是#.news ,因此凡是以 .news结尾的 routing key 都会被匹配。包括china.news和japan.news
    在这里插入图片描述

3. RabbitMQ的安装

1、安装Erlang:RabbitMQ是用Erlang编写的,因此首先需要安装Erlang运行环境(注意Erlang与RabbitMQ的对应版本)。运行以下命令进行安装:sudo apt install erlang

2、在线拉取镜像:docker pull rabbitmq:3-management

3、运行以下命令来下载并启动RabbitMQ Docker镜像:docker run -d --name rabbitmq -p 5672:5672 -p 15672:15672 rabbitmq:3-management

4、浏览器访问RabbitMQ管理页面:http://IP:15672/(注意:若网页无法访问,可能是rabbitmq_management插件未启用)

5、进入sbin目录下,查看插件,命令:rabbitmq-plugins list
在这里插入图片描述

6、 若 rabbitmq_management 插件未启用(状态无 * ),通过命令启用该插件:rabbitmq-plugins enable rabbitmq_management
在这里插入图片描述

7、启用后,重新访问地址,用户名/密码默认:guest/guest
在这里插入图片描述

三、SpringAMQP

AMQP,Adanced Message Queuing Protocol,是用于在应用程序之间传递业务消息的开发标准,与语言和平台无关。

SpringAMQP是基于RabbitMQ封装的一套模板,并且还利用SpringBoot对其实现了自动装配,使用起来非常方便。

SpringAmqp的官方地址:https://spring.io/projects/spring-amqp

SpringAMQP提供了三个功能:

  • 自动声明队列、交换机及其绑定关系
  • 基于注解的监听器模式,异步接收消息
  • 封装了RabbitTemplate工具,用于发送消息

1、使用SpringBootAMQP- SimpleQueue的步骤

  • 引入AMQP的Starter依赖
<!--AMQP依赖,包含RabbitMQ-->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
  • 配置RabbitMQ地址
logging:pattern:dateformat: MM-dd HH:mm:ss:SSS
spring:rabbitmq:host: 127.0.0.1port: 5672username: guestpassword: guestvirtual-host: /listener:simple:prefetch: 3 # 每次只能获取一条消息,处理完成才能获取下一个消息
  • 利用RabbitTemplate的convertAndSend方法
package com.example.rabbitmq_demo;import org.junit.jupiter.api.Test;
import org.junit.runner.RunWith;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;@RunWith(SpringRunner.class)
@SpringBootTest
class RabbitmqDemoApplicationTests {@Autowiredprivate RabbitTemplate rabbitTemplate;@Testpublic void testSimpleQueue() {//queueNameString queueName = "ty.simple.queue";//messageString message = "hello world ";//send MessagerabbitTemplate.convertAndSend(queueName, message);}}

2、使用SpringBootAMQP- FanoutExchange的步骤

  • 创建Spring配置类,绑定交换机 - 队列
package com.example.rabbitmq_demo.consumer.config;import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.FanoutExchange;
import org.springframework.amqp.core.Queue;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
public class FanoutConfig {@Beanpublic FanoutExchange fanoutExchange(){return new FanoutExchange("ty.fanout");}@Beanpublic Queue fanoutQueue1(){return new Queue("fanout.queue1");}@Beanpublic Queue fanoutQueue2(){return new Queue("fanout.queue2");}/*** 绑定交换机与队列*/@Beanpublic Binding fanoutBinding1(Queue fanoutQueue1, FanoutExchange fanoutExchange){return BindingBuilder.bind(fanoutQueue1).to(fanoutExchange);}@Beanpublic Binding fanoutBinding2(Queue fanoutQueue2, FanoutExchange fanoutExchange){return BindingBuilder.bind(fanoutQueue2).to(fanoutExchange);}
}
  • 利用RabbitTemplate的convertAndSend方法
package com.example.rabbitmq_demo;import org.junit.jupiter.api.Test;
import org.junit.runner.RunWith;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;@RunWith(SpringRunner.class)
@SpringBootTest
class RabbitmqDemoApplicationTests {@Autowiredprivate RabbitTemplate rabbitTemplate;@Testpublic void testSendFanoutExchange() {//exchangeNameString exchangeName = "ty.fanout";//messageString message = "hello world fanout";//send MessagerabbitTemplate.convertAndSend(exchangeName, "", message);}}

2、使用SpringBootAMQP- Direct的步骤

  • 基于注解来声明队列和交换机
package com.example.rabbitmq_demo.consumer;import org.springframework.amqp.core.ExchangeTypes;
import org.springframework.amqp.rabbit.annotation.Exchange;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.QueueBinding;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;@Component
public class ConsumerDemo {/*** 基于@Bean的方式声明队列和交换机比较麻烦,Spring还提供了基于注解方式来声明* 在consumer的SpringRabbitListener中添加两个消费者,同时基于注解来声明队列和交换机* @param msg*/@RabbitListener(bindings = @QueueBinding(value = @Queue(name = "ty.direct.queue1"),exchange = @Exchange(name = "ty.direct", type = ExchangeTypes.DIRECT),key = {"red", "green"}))public void listenDirectQueue1(String msg){System.out.println("listener ty.direct.queue1 Get message : " + msg);}@RabbitListener(bindings = @QueueBinding(value = @Queue(name = "ty.direct.queue2"),exchange = @Exchange(name = "ty.direct", type = ExchangeTypes.DIRECT),key = {"red", "blue"}))public void listenDirectQueue2(String msg){System.out.println("listener ty.direct.queue2 Get message : " + msg);}
}
  • 通过convertAndSend发送消息,会根据的RoutingKey,将消息发送至指定队列。
package com.example.rabbitmq_demo;import org.junit.jupiter.api.Test;
import org.junit.runner.RunWith;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;@RunWith(SpringRunner.class)
@SpringBootTest
class RabbitmqDemoApplicationTests {@Autowiredprivate RabbitTemplate rabbitTemplate;@Testpublic void testSendDirectExchange(){String exchangeName = "ty.direct";String message = "hello ty";rabbitTemplate.convertAndSend(exchangeName, "red", message);}
}

3、使用SpringBootAMQP- Tpic的步骤

  • 基于注解来声明队列和交换机
package com.example.rabbitmq_demo.consumer;import org.springframework.amqp.core.ExchangeTypes;
import org.springframework.amqp.rabbit.annotation.Exchange;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.QueueBinding;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;@Component
public class ConsumerDemo {/*** Topic类型的Exchange与Direct相比,都是可以根据RoutingKey把消息路由到不同的队列。只不过Topic类型Exchange可以让队列在绑定Routing key的时候使用通配符* @param msg*/@RabbitListener(bindings = @QueueBinding(value = @Queue(name = "ty.topic.queue1"),exchange = @Exchange(name = "ty.topic", type = ExchangeTypes.TOPIC),key = "ty.#"))public void listenTopicQueue1(String msg){System.out.println("listener ty.topic.queue1 Get message : " + msg);}@RabbitListener(bindings = @QueueBinding(value = @Queue(name = "ty.topic.queue2"),exchange = @Exchange(name = "ty.topic", type = ExchangeTypes.TOPIC),key = "#.tyty"))public void listenTopicQueue2(String msg){System.out.println("listener ty.topic.queue2 Get message : " + msg);}
}
  • 根据RoutingKey通配符,发送到对应Queue
package com.example.rabbitmq_demo;import org.junit.jupiter.api.Test;
import org.junit.runner.RunWith;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;@RunWith(SpringRunner.class)
@SpringBootTest
class RabbitmqDemoApplicationTests {@Autowiredprivate RabbitTemplate rabbitTemplate;@Testpublic void testSendTopicExchange(){String exchangeName = "ty.topic";String message = "hello ty";rabbitTemplate.convertAndSend(exchangeName, "ty.tyty", message);}}

4、SpringBootAMQP对象序列化

SpringBootAMQP默认使用的是 x-java-serialized-object,JDK序列化数据体积过大、有安全漏洞,且可读性差。
在这里插入图片描述
可通过配置JSON转换器,使用Json的方式做序列化和反序列化。

  • 引入jar
<dependency><groupId>com.fasterxml.jackson.dataformat</groupId><artifactId>jackson-dataformat-xml</artifactId><version>2.9.10</version>
</dependency>
  • 配置类中增加Bean
@Bean
public MessageConverter jsonMessageConverter(){return new Jackson2JsonMessageConverter();
}

在这里插入图片描述

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

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

相关文章

elasticsearch基本语法

这里写自定义目录标题 elasticsearch简介基本语法索引创建索引修改索引删除索引 查询简单查询精确查询条件查询范围查询&#xff1a;聚合查询&#xff1a;排序和分页&#xff1a; 参考文献&#xff1a; elasticsearch简介 Elasticsearch 是一个开源的分布式搜索和分析引擎&…

ctfshow web入门 php特性 web136-web140

1.web136 还有一种写文件的命令时tee命令 payload&#xff1a; : ls /|tee 1 访问1下载查看文件1发现根目录下有flag cat /f149_15_h3r3|tee 2 访问下载查看文件22.web137 call_user_func <?php class myclass {static function say_hello(){echo "He…

近期分享学习心得3

1、全屏组件封装 先看之前大屏端的监控部分全屏代码 整块全屏代码 常规流是下面这种 //进入全屏 function full(ele) {//if (ele.requestFullscreen) {// ele.requestFullscreen();//} else if (ele.mozRequestFullScreen) {// ele.mozRequestFullScreen();//} el…

FreeRTOS自我救赎3之USB虚拟串口

任何项目的功能都从需求出发&#xff0c;在这里我用的是斥侯蜂的一块STM32F407ZGT6 在开发一个项目的过程中&#xff0c;免不了串口调试&#xff0c;而这块板子板载的mircousb不是直接连的引脚而是一个OTGUSB

Maven(4)-利用intellij idea创建maven 多模块项目

本文通过一个例子来介绍利用maven来构建一个多模块的jave项目。开发工具&#xff1a;intellij idea。 一、项目结构 multi-module-project是主工程&#xff0c;里面包含两个模块&#xff08;Module&#xff09;&#xff1a; web-app是应用层&#xff0c;用于界面展示&#xff…

FFmpeg 命令:从入门到精通 | FFmpeg 解码流程

FFmpeg 命令&#xff1a;从入门到精通 | FFmpeg 解码流程 FFmpeg 命令&#xff1a;从入门到精通 | FFmpeg 解码流程流程图FFmpeg 解码的函数FFmpeg 解码的数据结构补充小知识 FFmpeg 命令&#xff1a;从入门到精通 | FFmpeg 解码流程 本内容参考雷霄骅博士的 FFmpeg 教程。 流…

ubuntu2204配置仓库为阿里源

官网上支持到2004&#xff0c;2204需要手动更改一下 deb https://mirrors.aliyun.com/ubuntu/ jammy main restricted universe multiverse deb-src https://mirrors.aliyun.com/ubuntu/ jammy main restricted universe multiversedeb https://mirrors.aliyun.com/ubuntu/ jam…

学生用的台灯护眼的哪种比较好?精选适合学生用的护眼台灯

现代小孩的学习压力确实很大&#xff0c;已经不能和我们以往那种“半大自然化学习”相提并论啦&#xff0c;如今各种学习PAD、电脑网课&#xff0c;成堆的学习资料与作业&#xff0c;恐怕是从小学甚至学前就已经是常态了。而且在平时我们路过学校的时候应该也不难发现&#xff…

Vue中如何进行音视频录制与视频剪辑

在Vue中进行音视频录制与视频剪辑 随着互联网的发展&#xff0c;音视频处理已经成为前端开发中一个越来越重要的领域。Vue.js作为一款流行的前端框架&#xff0c;为我们提供了丰富的工具和生态系统&#xff0c;使得音视频录制和编辑变得更加容易。本文将介绍如何在Vue中进行音…

论文阅读--Cell-free massive MIMO versus small cells

无蜂窝大规模MIMO与小蜂窝网络 论文信息 Ngo H Q, Ashikhmin A, Yang H, et al. Cell-free massive MIMO versus small cells[J]. IEEE Transactions on Wireless Communications, 2017, 16(3): 1834-1850. 无蜂窝大规模MIMO中没有小区或者小区边界的界定&#xff0c;所有接入…

位移贴图和法线贴图的区别

位移贴图和法线贴图都是用于增强模型表面细节和真实感的纹理贴图技术&#xff0c;但是它们之间也存在着差异。 1、什么是位移贴图 位移贴图&#xff1a;位移贴图通过在模型顶点上定义位移值来改变模型表面的形状。该贴图包含了每个像素的高度值信息&#xff0c;使得模型的细节…

idea compile项目正常,启动项目的时候build失败,报“找不到符号”等问题

1、首先往上找&#xff0c;看能不能找到如下报错信息 You aren’t using a compiler supported by lombok, so lombok will not work and has been disabled. 2、这种问题属于lombok编译失败导致&#xff0c;可能原因是依赖jar包没有更新到最新版本 3、解决方案 1&#xff09…

二、图像处理

待完善 一、图片缩放 import org.bytedeco.opencv.global.opencv_imgcodecs; import org.bytedeco.opencv.global.opencv_imgproc; import org.bytedeco.opencv.opencv_core.Mat; import org.bytedeco.opencv.opencv_core.Size;public class ImageResizer {public static voi…

Python —— UI自动化之八大元素定位

1、基础元素定位 1、id定位 使用html中标签的id元素去定位&#xff0c;在一般定位中优先选择&#xff0c;举例&#xff1a; from time import sleep from selenium import webdriver from selenium.webdriver.common.by import Bydriver webdriver.Firefox() driver.get(&q…

MySQ 学习笔记

1.MySQL(老版)基础 开启MySQL服务: net start mysql mysql为安装时的名称 关闭MySQL服务: net stop mysql 注: 需管理员模式下运行Dos命令 . 打开服务窗口命令 services.msc 登录MySQL服务: mysql [-h localhost -P 3306] -u root -p****** Navicat常用快捷键 键动作CTRLG设…

修炼k8s+flink+hdfs+dlink(三:安装dlink)

一&#xff1a;mysql初始化。 mysql -uroot -p123456 create database dinky; grant all privileges on dinky.* to dinky% identified by dinky with grant option; flush privileges;二&#xff1a;上传dinky。 上传至目录/opt/app/dlink tar -zxvf dlink-release-0.7.4.t…

Django REST framework API版本管理【通过GET参数传递】

API版本 在开发过程中可能会有多版本的API&#xff0c;因此需要对API进行管理。django drf中对于版本的管理也很方便。 http://www.example.com/api/v1/info http://www.example.com/api/v2/info 上面这种形式就是很常见的版本管理 在restful规范中&#xff0c;后端的API需…

css记录写一个奇怪的按钮

完成作业的时候发现一个很有意思的按钮&#xff0c;记录一下记录一下 看看界面 可以看出是一个奇形怪状的按钮&#xff0c;而且在按下的时候&#xff0c;图片和文字的颜色会改变 尝试解决 <!DOCTYPE html> <html lang"zh"> <head><meta chars…

cartographer-(0)-ubuntu(20.04)-环境安装

1.安装 ROS wiki.ros.org 1.1修改镜像源&#xff1a; 到网站上找与操作系统相匹配的镜像源 ubuntu | 镜像站使用帮助 | 清华大学开源软件镜像站 | Tsinghua Open Source Mirror # 默认注释了源码镜像以提高 apt update 速度&#xff0c;如有需要可自行取消注释 deb htt…

Linux基础指令大全

Linux基础指令大全 1. ls 指令2. pwd命令3. cd 指令4. touch指令5. mkdir指令6. rmdir指令 && rm 指令7. man指令8.cp指令9. mv指令10. cat 指令11. more指令12. less指令13. head指令14. tail指令15. 时间相关的指令1. **在显示方面&#xff0c;使用者可以设定欲显示的…