RabbitMQ基础使用

news2024/9/28 14:03:53

1.MQ基础介绍

同步调用

OpenFeign的调用。这种调用中,调用者发起请求后需要等待服务提供者执行业务返回结果后,才

能继续执行后面的业务。也就是说调用者在调用过程中处于阻塞状态,因此我们称这种调用方式为同步调用

异步调用

异步调用通常是基于消息通知的方式,包含三个角色:

        消息发送者:投递消息的人,就是原来的调用者

        消息接收者:接收和处理消息的人,就是原来的服务提供者

        消息代理:管理、暂存、转发消息,就是原来的服务提供方

不同的MQ介绍

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

本文讲解RabbitMQ

2.RabbitMQ

1.安装部署

在docker安装rabbit,代码如下:

docker run \
 -e RABBITMQ_DEFAULT_USER=itheima \
 -e RABBITMQ_DEFAULT_PASS=123321 \
 -v mq-plugins:/plugins \
 --name mq \
 --hostname mq \
 -p 15672:15672 \
 -p 5672:5672 \
 --network hm-net\
 -d \
 rabbitmq:3.8-management

安装完成后,我们访问 http://192.168.150.101:15672即可看到管理控制台。

2.收发消息

交换机

点开amq.fanout交换机,将交换机和队列做绑定

队列

指定队列的名字添加队列

3.数据隔离

问题:要实现不同虚拟主机之间不同的交换机之间的隔离,需要用到数据隔离的技术。

添加用户

添加自己的虚拟主机

3.SpringAMQP

RabbitMQ官方提供的Java客户端编码相对复杂,一般生产环境下我们更多会结合Spring来使用。

而Spring的官方刚好基于RabbitMQ提供了这样一套消息收发的模板工具:SpringAMQP。并且

还基于SpringBoot对其实现了自动装配,使用起来非常方便。

1.快速入门

导入依赖:

        <!--AMQP依赖,包含RabbitMQ-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-amqp</artifactId>
        </dependency>

配置信息:

spring:
  rabbitmq:
    host: 192.168.145.129 # 你的虚拟机IP
    port: 5672 # 端口
    virtual-host: /hmall # 虚拟主机
    username: hmall # 用户名
    password: 123 # 密码

编写消息发送者和接收者的代码

发送者:写了一个测试类,注入了RabbitTemplate对象调用convertAndSend方法把队列名和消息发送出去。

@SpringBootTest
public class amqp {
    @Autowired
    private RabbitTemplate rabbitTemplate;

    @Test
    public void testsimplequeue(){
        //队列名
        String queue="simple.queue";
        //消息
        String message="hello";
        //发送消息
        rabbitTemplate.convertAndSend(queue,message);
    }
}

接收者:在方法上加上 @RabbitListener(queues = "simple.queue")即可实现对消息的接收。

@Component
public class listen {
    //队列的名称
    @RabbitListener(queues = "simple.queue")
    //发送者发送的什么类型,接收者用什么类型接收
    public void listen1(String message){
        System.out.println("接收到消息"+message);
    }
}

2.WorkQueues模型

Work queues,任务模型。简单来说就是多个消费者绑定到一个队列,共同消费队列中的消息

模拟此环境再多加一个消费者即可。

AMQP默认是采用类似轮询的机制,性能慢的机器会拖慢速度,因此需做如下配置实现能者多劳:

spring:
  rabbitmq:
    listener:
      simple:
        prefetch: 1 # 每次只能获取一条消息,处理完成才能获取下一个消息

3.交换机

1.Fanout交换机

fanout交换机是将消息全部发送到绑定的队列中。

使用fanout交换机发送消息要使用如下函数:

    @Test
    public void testfanout(){
        //交换机名称
        String exchange="hmall.fanout";
        //消息
        String message="hello,everyone";
        //fanout交换机发送消息         交换机    队列   消息
        rabbitTemplate.convertAndSend(exchange,null,message);
    }

2.Direct交换机

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

在Direct模型下:

        队列与交换机的绑定,不能是任意绑定了,而是要指定一个RoutingKey(路由key)

        消息的发送方在 向 Exchange发送消息时,也必须指定消息的 RoutingKey

        Exchange不再把消息交给每一个绑定的队列,而是根据消息的Routing Key进行判断,只有            队列的Routingkey与消息的 Routing key完全一致,才会接收到消息

绑定路由key实例:

代码示例:

rabbitTemplate.convertAndSend(exchange,"white",message);指定路由key,发送到指定的队列。

    @Test
    public void testdirect(){
        //交换机名称
        String exchange="hmall.direct";
        //消息
        String message="hello,everyone,direct";
        //发送消息                             指定路由key
        rabbitTemplate.convertAndSend(exchange,"white",message);
    }

3.Topic交换机

Topic类型的ExchangeDirect相比,都是可以根据RoutingKey把消息路由到不同的队列。

只不过Topic类型Exchange可以让队列在绑定BindingKey 的时候使用通配符!

BindingKey 一般都是有一个或多个单词组成,多个单词之间以.分割,例如: item.insert

通配符规则:

  • #:匹配一个或多个词

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

举例:

  • item.#:能够匹配item.spu.insert 或者 item.spu

  • item.*:只能匹配item.spu

绑定示例:

代码示例:

    @Test
    public void testdirect(){
        //交换机名称
        String exchange="hmall.topic";
        //消息
        String message="hello,everyone,topic";
        //发送消息 topic
        rabbitTemplate.convertAndSend(exchange,"#.news",message);
    }

4.基于bean声明队列交换机

在java代码中注册交换机和队列

fanout交换机代码如下:

@Configuration
public class fanout {
    //注册交换机
    @Bean
    public FanoutExchange fanoutExchange(){
        //return ExchangeBuilder.fanoutExchange("hmall.fanout").build();
        return new FanoutExchange("hmall.fanout");
    }
    //注册队列
    @Bean
    public Queue queue1(){
        //return QueueBuilder.durable("fanout.queue1").build();
        return new Queue("fanout.queue1");
    }
    //绑定
    @Bean
    public Binding fanoutbindingqueue1(Queue queue1,FanoutExchange fanout){
        return BindingBuilder.bind(queue1).to(fanout);
    }
    @Bean
    public Queue queue2(){
        return new Queue("fanout.queue2");
    }
    @Bean
    public Binding fanoutbindingqueue2(Queue queue2,FanoutExchange fanout){
        return BindingBuilder.bind(queue2).to(fanout);
    }
}

direct交换机代码如下:

@Configuration
public class DirectConfig {

    /**
     * 声明交换机
     * @return Direct类型交换机
     */
    @Bean
    public DirectExchange directExchange(){
        return ExchangeBuilder.directExchange("hmall.direct").build();
    }

    /**
     * 第1个队列
     */
    @Bean
    public Queue directQueue1(){
        return new Queue("direct.queue1");
    }

    /**
     * 绑定队列和交换机
     */
    @Bean
    public Binding bindingQueue1WithRed(Queue directQueue1, DirectExchange directExchange){
        return BindingBuilder.bind(directQueue1).to(directExchange).with("red");
    }
    /**
     * 绑定队列和交换机
     */
    @Bean
    public Binding bindingQueue1WithBlue(Queue directQueue1, DirectExchange directExchange){
        return BindingBuilder.bind(directQueue1).to(directExchange).with("blue");
    }

    /**
     * 第2个队列
     */
    @Bean
    public Queue directQueue2(){
        return new Queue("direct.queue2");
    }

    /**
     * 绑定队列和交换机
     */
    @Bean
    public Binding bindingQueue2WithRed(Queue directQueue2, DirectExchange directExchange){
        return BindingBuilder.bind(directQueue2).to(directExchange).with("red");
    }
    /**
     * 绑定队列和交换机
     */
    @Bean
    public Binding bindingQueue2WithYellow(Queue directQueue2, DirectExchange directExchange){
        return BindingBuilder.bind(directQueue2).to(directExchange).with("yellow");
    }
}

5.基于注解声明队列交换机

基于bean声明太过复杂,尤其是direct交换机绑定key时,因此要用到注解声明。

在注解下同时创建队列交换机并完成绑定,代码如下:

    @RabbitListener(bindings = @QueueBinding(
            //注册队列                  名称              持久化
            value = @Queue(name = "direct.queue",durable = "ture"),
            //注册交换机                 名称              类型为direct
            exchange = @Exchange(name = "hmall.direct",type = ExchangeTypes.DIRECT),
            //交换机绑定队列属性有red和white
            key = {"red","white"}
    ))
    public void listen(String message){
        System.out.println("接收到消息"+message);
    }

4.消息转化器

spring在数据传输时,它会把你发送的消息序列化为字节发送给MQ,接收消息的时候,还会把字节反序列化为Java对象。

只不过,默认情况下Spring采用的序列化方式是JDK序列化。众所周知,JDK序列化存在下列问题:(比如用rabbitmq发送map集合,数据被序列化后字节太多而且可读性差)

  • 数据体积过大

  • 有安全漏洞

  • 可读性差

因此我们使用JSON方式来做序列化和反序列化。

导入依赖:

<dependency>
    <groupId>com.fasterxml.jackson.dataformat</groupId>
    <artifactId>jackson-dataformat-xml</artifactId>
    <version>2.9.10</version>
</dependency>

配置消息转换器,在publisherconsumer两个服务的启动类中添加一个Bean即可:

@Bean
public MessageConverter messageConverter(){
    // 1.定义消息转换器
    Jackson2JsonMessageConverter jackson2JsonMessageConverter = new Jackson2JsonMessageConverter();
    // 2.配置自动创建消息id,用于识别不同消息,也可以在业务中基于ID判断是否是重复消息
    jackson2JsonMessageConverter.setCreateMessageIds(true);
    return jackson2JsonMessageConverter;
}

RabbitMQ高级

未完待续

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

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

相关文章

Lucene 倒排索引原理详解:深入探讨相关算法设计

引言 随着互联网的快速发展&#xff0c;数据量呈现爆炸性的增长&#xff0c;如何从海量数据中快速准确地获取所需信息成为了一项挑战。全文搜索引擎的出现极大地解决了这个问题&#xff0c;而 Lucene 正是一款优秀的开源全文搜索引擎库。本文将深入探讨 Lucene 的核心技术之一…

NtripShare测量机器人自动化监测系统测站更换仪器后重新设站

NtripShare测量机器人自动化监测系统投入商业运营已经很久了&#xff0c;在MosBox与自动优化网平差技术的加持下&#xff0c;精度并不让人担心&#xff0c;最近基于客户需求处理了两个比较大的问题。 1、增加对反射片和免棱镜的支持。 2、进一步优化测站更换仪器或重新整平后重…

顶点缓存对象(VBO)与顶点数组对象(VAO)

我们的顶点数组在CPU端的内存里是以数组的形式存在,想要GPU去绘制三角形,那么需要将这些数据传输给GPU。那这些数据在显存端是怎么存储的呢?VBO上场了,它代表GPU上的一段存储空间对象,表现为一个unsigned int类型的变量,GPU端内存对象的一个ID编号、地址、大小。一个VBO对…

Cpp内存管理(7)

文章目录 前言一、C/C内存区域划分二、C/C动态内存管理C语言动态内存管理C动态内存管理对于内置类型对于自定义类型 三、new和delete的底层实现四、new和delete的实现原理五、定位new六、malloc/free和new/delete的区别总结 前言 软件开发过程中&#xff0c;内存管理的重要性不…

vue3中echarts柱状图横轴文字太多放不下怎么解决

问题&#xff1a;在做数据展示的时候&#xff0c;使用的是echarts&#xff0c;遇到了个问题&#xff0c;就是数据过多&#xff0c;但是设置的x轴的文字名称又太长&#xff0c;往往左边第一个或右边最后一个的名称展示不全&#xff0c;只有半个。 从网上找到了几种办法&#xff…

进击J8:Inception v1算法实战与解析

&#x1f368; 本文为&#x1f517;365天深度学习训练营 中的学习记录博客&#x1f356; 原作者&#xff1a;K同学啊 一、实验目的&#xff1a; 了解并学习图2中的卷积层运算量的计算过程了解并学习卷积层的并行结构与1x1卷积核部分内容&#xff08;重点&#xff09;尝试根据模…

pdf转换成word有哪些方法?10种将PDF转成word的方法

pdf转换成word有哪些方法&#xff1f;在数字化世界中&#xff0c;PDF和word文档是最常用的两种文件格式。PDF凭借其固定布局和跨平台的兼容性&#xff0c;成为了文件分享的首选&#xff0c;而word则因其灵活的编辑功能被广泛应用于各种文本处理需求。在许多情况下&#xff0c;我…

高效IaC测试利器:AlibabaCloud ROS-Tool-Iact3快速上手

在云计算时代&#xff0c;基础设施即代码&#xff08;Infrastructure as Code, IaC&#xff09;已成为提升运维效率、实现自动化部署的重要手段。为了进一步简化IaC模板的测试流程&#xff0c;alibabacloud-ros-tool-iact3工具应运而生&#xff0c;它专为Terraform和阿里云资源…

再次重温 Spring 中 Bean 的生命周期

Bean的生命周期 Spring中的bean的生命周期主要包含四个阶段&#xff1a;实例化Bean --&#xff1e; Bean属性填充 --&#xff1e; 初始化Bean --&#xff1e;销毁Bean 首先是实例化Bean&#xff0c;当客户向容器请求一个尚未初始化的bean时&#xff0c;或初始化bean的时候需要…

Java 导出excel

1.导出excel 带合计 如&#xff1a; public void export(DriverAndGuestMealQueryVO vo) {DriverAndGuestMealListDTO riceLiquidationPage page(vo);// 创建一个Excel工作簿Workbook workbook new XSSFWorkbook();// 创建一个工作表sheetSheet sheet workbook.createShee…

网络通信——DHCP

目录 一.DHCP应用场景 二.通信过程 三.DHCP报文 四.DHCP通信原理 &#xff08;1&#xff09;租借过程 &#xff08;2&#xff09;DHCP 租期更新 &#xff08;3&#xff09;DHCP重绑定 五.一般路由器的DHCP支持两种地址池 &#xff08;1&#xff09;接口地址池 &…

Html jquery下拉select美化插件——selectFilter.js

1. Html jquery下拉select美化插件——selectFilter.js jQuery是一个广泛使用的JavaScript库&#xff0c;它简化了DOM操作、事件处理、动画以及Ajax交互&#xff0c;使得开发者能更高效地构建交互式网页。在本案例中&#xff0c;jquery.selectlist.js插件正是基于jQuery构建的&…

复旦大学附属中山医院院士团队论文遭遇质疑

近日&#xff0c;一篇发表于肝脏领域顶级期刊《Hepatology》(IF:17.1;Q1&#xff09;杂志的肝细胞癌研究论文因图像数据的相似性问题受到质疑。该论文题为‘Protein tyrosine phosphatase receptor S acts as a metastatic suppressor in hepatocellular carcinoma by control …

找不到concrt140.dll怎么修复,这4种方法可轻松搞定

1. concrt140.dll 定义 1.1 系统文件 concrt140.dll 是一个系统文件&#xff0c;属于 Windows 操作系统中重要的动态链接库&#xff08;DLL&#xff09;之一。它通常位于系统的 System32 或 SysWOW64 文件夹中&#xff0c;是 Microsoft Visual C 2015 Redistributable 包的一…

如何在产品上扩大储存?教你一招简单好用的!

你是不是经常遇到需要扩大库存的问题&#xff1f;毕竟总是有很多文件需要存储&#xff1a;视频、音频、文件。。。 但是芯片的空间寸土寸金呀&#xff01; 内部不够只能外扩&#xff0c;然后就是要编写各种驱动&#xff0c;还有Flash替换。。。怎么听着就头疼&#xff01; 教…

【一文带你找到答案!】你了解文档透明加密系统吗?文档透明加密系统有什么功能?

在当今数字化时代&#xff0c;信息安全已成为企业和个人不可忽视的重要议题。 文档透明加密系统作为保护敏感信息的关键技术之一&#xff0c;正逐渐受到广泛关注和应用。 本文将带您深入了解文档透明加密系统&#xff0c;并详细解析其各项功能。 一、文档透明加密系统概述 文…

linux常见指令与权限【第四课】

19.tar指令&#xff08;重要&#xff09;&#xff1a;打包/解包&#xff0c;不打开它&#xff0c;直接看内容 tar [-cxtzjvf] &#xff1a; -c &#xff1a;建立一个压缩文件的参数指令 (create 的意思 ) &#xff1b; -x &#xff1a;解开一个压缩文件的参数指令&#xff…

Java线程池和原子性

文章目录 前言1 线程池1.1 线程池概述1.1.1 线程池存在的意义1.1.2 Executors默认线程池 1.2 线程状态介绍1.2.1 线程状态源码1.2.2 线程状态含义1.2.3 线程状态转换图 2 原子性2.1 volatile关键字2.2 synchronized解决2.3 原子性2.4 AtomicInteger类2.5 悲观锁和乐观锁 前言 …

TikTok五分钟开户快速步骤流程!

1、注册您的账户 首先&#xff0c;访问TikTok广告管理器的注册页面&#xff08;https://ads.tiktok.com/i18n/signup/&#xff09;以创建账户。您可以选择使用电子邮件或手机号码进行注册。输入您的电子邮件和密码后&#xff0c;您需要同意TikTok的广告条款&#xff0c;然后点击…

【路径规划】用于识别封闭多边形竞技场内两点之间的最短路径

摘要 本项目展示了一种在包含障碍物的封闭多边形区域内识别两点之间的最短路径的算法。该算法不依赖于离散化的地图&#xff08;如网格地图&#xff09;&#xff0c;而是直接通过几何计算处理路径和障碍物之间的关系&#xff0c;生成沿着障碍物边缘的最优路径。实验结果表明&a…