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

RabbitMQ从入门到实战-2

文章目录

  • Java客户端
  • 快速入门
  • WorkQueue(多消费)
    • 能者多劳配置
  • 交换机
    • fanout交换机
      • 案例
    • Direct交换机
    • Topic交互机
  • 声明队列和交互机(IDEA中)
    • 基于Bean声明队列和交换机
    • 基于注解声明(推)
  • 消息转换器
    • 配置Json消息转换器
  • 业务改造(实际例子)

这篇讲解通过java客户端操作rabbitmq

Java客户端

可以通过不同客户端操作mq
我们这里用spring AMQP(AMQP是一种协议)
在这里插入图片描述

快速入门

交换机需要和队列进行绑定,而我们的消费者需要监听队列,生产者指定生产到哪个队列

这里我们先不发交换机,直接发送到队列,为了简单一点
自己创建队列哈,这里就不说了
在这里插入图片描述
使用springAMQP过程

在这里插入图片描述
这里配置根据自己的情况不同调整
在这里插入图片描述
提供生产者发送消息
提供的也是一个template,convertAndSend方法去发送消息,测试类中编写完直接运行即可
在这里插入图片描述
提供消费者监听simple.queue,这里的接收参数和我们发送参数类型一致,spring会帮我们自动转化并接收
然后将项目启动就可以监听了
在这里插入图片描述
在这里插入图片描述

WorkQueue(多消费)

一个队列,多个消费者
消费者之间属于竞争关系(队列中的一个数据只能被一个消费者获取)
这点和交换机与队列的关系不同(由交换)

消费者从queue中获取数据,进行处理,如果不设置其他操作,每一个消费者只需要处理n/m个数据(n为生产者生成数,m为消费者消费数)

下面我们在一个类建了两个消费者方法,一般不会这样做(因为他们消耗的是同一个机器资源)
正常我们会写一个消费者方法,复制多个springboot项目实例部署,形成集群
启动多个消费者,绑定到这个队列,这样里面的代码逻辑也相同,减轻单个消费者服务器的压力

在这里插入图片描述
生产者发50条数据
在这里插入图片描述
这里我设置了两个消费者
会均匀分一人一个这样,这里消费者2接收1、3、5…
消费者1接收2、4、6、8…
在这里插入图片描述
在这里插入图片描述

能者多劳配置

新需求
让消费者1每秒处理40条消息,消费者2每秒处理5条消息
代码改造
在这里插入图片描述
出现问题
我们消息消费速度跟不上消息分配速度
我们消息分配还是一人一条这样分配,先给1再给2
这样没有考虑到谁消费的快的问题,这样的话,2处理的慢,你还给人分50条就太离谱了,影响整体性能
如果可以让1消费完去帮助2消费就可以了
在这里插入图片描述

那么如何让先消费完的消费者优先获取消息呢?

如何发挥我们MQ消费者最大性能(处理完的先分配)
而不是轮询,做以下设置
保证同一时刻给一条信息,处理完就会再给,不空闲
这样处理快的可能处理2条的同时慢的处理1条,发挥最大效能
在消费者项目的配置文件中进行配置
在这里插入图片描述
这样就实现了最大效率
在这里插入图片描述

交换机

交换机绑定队列,由其交换机类型决定发送的到绑定队列的方式
发送到交互机要写三个参数,(交换机名,队列名,信息)
在这里插入图片描述
在这里插入图片描述

fanout交换机

队列发的消息,只可能被一个消费者处理
而通过我们这个交互机可以达到同一个消费被多个连接不同队列的消费者处理(因为队列没有广播性质)

应用场景:比如说我们之前的支付案例
我们会干1.通知订单服务2.通知短信服务3.通知积分服务
三件事都要做,不同的微服务相当于消费者,不同服务连接不同队列
如果你只能发送一条信息,只有三者之一可以实现,如果可以广播,三者都可以实现

在这里插入图片描述

案例

在这里插入图片描述
声明队列,在控制台添加就行,这里不展示
在这里插入图片描述
这里也可以用他默认的交互机,也可以自己建,从type中选择类型
在这里插入图片描述
消费者设置
在这里插入图片描述
发送到交互机要写三个参数,(交换机名,队列名,信息)
我们这里因为要发给交换机,队列直接弄成null,如果不写null,会把你的交换机名当成队列名发送
在这里插入图片描述
然后发送,两个队列都会监听到
在这里插入图片描述

Direct交换机

交换机和队列链接时候设置bingkey(连接在同一个交互机的该值可以相同)
然后我们设置三个参数时候
设置第二个参数,只有bindkey=routingkey这两才,对应的队列才可以接收到交换机的消息
(由于bindkey可相同,可以实现多发和单发两种效果)
在这里插入图片描述

案例
bindkey不是队列的属性,而是交换机指定和队列相连的属性
所以同一个队列可能对交互机而言有多个bindkey
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
指定红两个都可以收到,而指定蓝色,只有消费者1可以收到
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

Topic交互机

只有Topic交互机连接的队列的bindkey里带#或者*才会识别为通配符

一个key代替多种routingkey含义
减少了一个个绑定key的麻烦,而且你之后一个类型可以直接用这个通配符(符合你想处理的情况),可扩展性
这样的话,你发送china.union也会到queue1,发送china.mei也会发到queue1
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

声明队列和交互机(IDEA中)

基于Bean声明队列和交换机

在这里插入图片描述
队列和交换机直接new(也可以用Bulider创建,有ExchageBuilder和QueueBuilder),连接需要
建队列有个durable属性可以选择(默认持久),持久化,队列会持久化到磁盘(通常都是持久化)
这里bind没有指定key因为是fanout交换机是广播 ,如果是别的话,可以跟一个with方法指定交换名字
在这里插入图片描述
这些交换机和队列会在我们启动项目时候声明处理(停止后也不会消失)

基于注解声明(推)

使用bean还是比较麻烦,写的代码太多
而且每个方法只能声明一个bindkey,要写n个就得n个方法
在这里插入图片描述
还是之前的需求
用@Rabbitistener()+@QueueBinding()+@Queue()+@Exchage()只是声明bindings
声明这个后,我们的方法会作为队列的消费者,队列也会和声明的交换机产生对应的bindkey
可以使用ctrl+p提示
在这里插入图片描述

在这里插入图片描述
同样的项目启动时候这些设置会持久化到mq中

消息转换器

之前我们发送消息
在这里插入图片描述
用convertAndSend方法,该方法最后一个参数其实为Object类型
我们可以传入不同对象传到Exchange中
而我们学的这个消息转换器就是帮我们转换对象的
在这里插入图片描述
发送map到声明的队列
在这里插入图片描述
这是我们MQ中收到的消息
这里Spring AMQP默认用了JDK自带的对象序列化,将对象序列化字节的方式去发送消息
在这里插入图片描述

默认就是用这个SimpeMessageConverter类的createMessage来实现消息转换
createMessage逻辑梳理:
如果本身就是字节数组直接传递,如果是字符串getBytes传递
如果实现了Serializable接口就调用SerializableUtils序列化我们的对象(用对象流写入对象)
在这里插入图片描述

JDK默认序列化很不好,需要使用其他消息转换器
在这里插入图片描述

配置Json消息转换器

该消息转换器要在生产者消费者都要配(实现统一匹配)
在这里插入图片描述

在这里插入图片描述

业务改造(实际例子)

从OpenFegin的同步调用改成基于MQ的异步调用

订单状态在支付失败时候更新为支付失败,通知服务和积分服务就不会执行
而我们的支付成功时候,三个服务都会执行
所以说这三个服务收消息的时候不是说每一次大家都要收
而是按照业务来,direct和topic都可以,这里我用direct

所以我们这里用direct的交换机
对应设置的交换机名称和队列和bindkey都显示了,还有对应的业务逻辑
在这里插入图片描述
这边是我们原代码,上面的服务其实我们只实现了订单,所以这里我们只改这个订单变成异步通信(MQ)
在这里插入图片描述
发送业务逻辑的修改
作为异步的一个逻辑我们try起来,防止影响我们核心业务
在这里插入图片描述
监听者
发送和监听这个参数怎么匹配我不太清楚(但是好像发送者只能发送一条数据,所以只能匹配单个参数)
在这里插入图片描述


http://www.kler.cn/a/579047.html

相关文章:

  • 计算机视觉cv2入门之图像的读取,显示,与保存
  • STM32-USART串口数据包
  • 大白话JavaScript闭包实现原理与在实际开发中的应用场景
  • 六十天前端强化训练之第八天到第十四天——综合案例:用户管理系统
  • PHP:格式化JSON为PHP语法格式
  • 【贪心算法】将数组和减半的最小操作数
  • Python 数据可视化创意分享:解锁数据之
  • Python性能优化面试题及参考答案
  • 【计算机网络入门】应用层
  • NO.33十六届蓝桥杯备战|函数|返回值|声明|调用|引用|函数重载(C++)
  • 软件工程画图题
  • 前端安全面试题汇总及参考答案
  • 如何创建炫酷的 3D CSS 旋转加载器:为你的网页增添动感
  • Compose笔记(八)--权限
  • 元脑服务器:浪潮信息引领AI基础设施的创新与发展
  • 基于Asp.net的零食购物商城网站
  • Ruoyi+uniapp+websocket点对点和广播通知消息
  • SpringBoot3—场景整合:AOT
  • 【图像处理与OpenCV:技术栈、应用和实现】
  • c#面试题整理6