目录
5.3 发布/订阅队列(publish/subscribe)
1、rabbitMQ
rabbitmq是基于erlang语言,AMQP(Advanced Message Queuing Protocol)协议,实现的一款轻量级开源消息中间件
2、rabbitMQ的下载、安装、使用
erlang下载:https://www.erlang.org/downloads
最新版本和历史版本根据机器适配版本选择:
rabbitmq下载:https://www.rabbitmq.com/download.html
最新版本和历史版本同样根据适配的版本进行选择:
windows下使用:
找到安装的地址H:\rabbitmq\rabbitmq_server-3.9.2\sbin输入命令:
rabbitmq-plugins enable rabbitmq_management
这样就启动了管理工具,浏览器访问:http://localhost:15672/
默认账号/密码:guest / guest
3、使用场景
3.1 异步处理
场景:用户注册后会给用发送注册短信和邮箱
串行方式:用户信息添加到数据库,发送注册短信和邮箱后同步返回注册信息给用户
并行方式:用户信息添加到数据库,发送注册短信和邮箱采用并行方式,减少处理时间
消息队列:引入消息队列,将不必要的发送短信和邮箱采用异步方式处理,大大减少处理时间
如果保存到数据库是50ms,发送短信和邮箱各是50ms,消息队列是5ms,那串行是150ms,并行是100ms,而消息队列是55ms。
3.2 应用解耦
场景:双11是购物狂节,用户下单后,订单系统需要通知库存系统,传统的做法就是订单系统调用库存系统的接口.
这种做法有一个缺点:
- 当库存系统出现故障时,订单就会失败
-
订单系统和库存系统高耦合.
引入消息队列
订单系统:用户下单后,订单系统完成持久化处理,将消息写入消息队列,返回用户订单下单成功
库存系统:订阅下单的消息,获取下单消息,进行库操作,就算库存系统出现故障,消息队列也能保证消息的可靠投递,不会导致消息丢失
3.3 流量削峰
流量削峰一般在秒杀活动中应用广泛
场景:秒杀活动,一般会因为流量过大,导致应用挂掉,为了解决这个问题,一般在应用前端加入消息队列。
作用:
1.可以控制活动人数,超过此一定阀值的订单直接丢弃(我为什么秒杀一次都没有成功过呢^^)
2.可以缓解短时间的高流量压垮应用(应用程序按自己的最大处理能力获取订单)
1.用户的请求,服务器收到之后,首先写入消息队列,加入消息队列长度超过最大值,则直接抛弃用户请求或跳转到错误页面.
2.秒杀业务根据消息队列中的请求信息,再做后续处理.
3.4 定时任务
场景:指定时间上线一个商品
手动上架:比较传统的是手动操作上线一个商品
定时器:自己在系统上写一个Timer(定时器),但Timer线程是不会捕获异常的,如果TimerTask抛出的了未检查异常则会导致Timer线程终止,同时Timer也不会重新恢复线程的执行,他会错误的认为整个Timer线程都会取消。同时,已经被安排单尚未执行的TimerTask也不会再执行了,新的任务也不能被调度。故如果TimerTask抛出未检查的异常,Timer将会产生无法预料的行为
消息队列:相较于定时器,使用消息队列可以达到应用解耦,便于管理,异常ack机制确认
4、rabbitmq管理界面
用户:
1、超级管理员(administrator)
可登陆管理控制台,可查看所有的信息,并且可以对用户,策略(policy)进行操作。
2、监控者(monitoring)
可登陆管理控制台,同时可以查看rabbitmq节点的相关信息(进程数,内存使用情况,磁盘使用情况等)
3、策略制定者(policymaker)
可登陆管理控制台, 同时可以对policy进行管理。但无法查看节点的相关信息(上图红框标识的部分)。
4、普通管理者(management)
仅可登陆管理控制台,无法看到节点信息,也无法对策略进行管理。
5、其他
无法登陆管理控制台,通常就是普通的生产者和消费者
队列:
message TTL:消息生存时间,超过设置时间自动删除
auto expire:队列生存时间,超过设置时间自动删除
overflow behaviour:队列溢出行为,可设置drop-head, reject-publish 或reject-publish-dlx,drop-head会丢弃最老的消息,reject-publish或reject-publish-dlx会丢弃最新的消息
dead letter exchange:死信交换机,如果消息被拒绝或过期,将发布到改交换机绑定的队列
dead letter routing key:死信交换机路由,由该交换机根据路由键发给队列
max length:最大消息容量,超过会从头部丢弃
max length bytes:最大消息容量字节数,超过会从头部丢弃
maximum priority:最大优先级,消息的优先级参数越靠近最大优先级,越早被消费
lazy mode:惰性模式,在磁盘上保留尽可能多的消息,以减少RAM的使用,否则是一个内存缓存,尽可能快的传递消息
master locetor:集群相关
交换机:
default Exchange(默认交换机):是没有名字的direct exchange,name为空字符串,所有的queue都binding到该交换机,所有binding到该交换机的queue,routing都和queue 的name一样
direct Exchange(直接交换机):一个queue通过 routing=K binding到该交换机,那交换机可以通过routing将消息传给queue
fanout Exchange(展开交换机):交换机会把消息发给所有binding 在该交换机的queue
headers Exchange(头部交换机,自定义交换机):交换机把消息传给一个(any)或全部(all)满足header 元素内容的queue,header元素匹配规则:可用hashMap封装,内容自定义
topic Exchange(主题交换机,通配符交换机):交换机把消息传给一个或多个满足通配符规则的routing-key的queue,这里的routing-key有通配符:#表示匹配多个单词,*表示匹配一个单词
5、六种队列
<dependency>
<groupId>com.rabbitmq</groupId>
<artifactId>amqp-client</artifactId>
<version>5.7.1</version>
</dependency>
rabbitmq client实现参考:https://blog.csdn.net/kavito/article/details/91403659
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
spring 封装实现,下面队列所用,两种方式实现效果相同,根据实际情况使用
5.1 简单队列(hello world)
P:生产者
P和C之间:队列
C:消费者
简单队列是在默认交换机下完成的消息传递,routing 和queue name是一样的