最近小L会听到很多学员说 , 在面试大型互联网公司的时候 , 很可能会被问到消息队列的问题:
- 在何种场景下使用了消息中间件?
为什么要在系统里引入消息中间件?
如何实现幂等?
1、 这些接口之间耦合比较严重 , 每新增一个下游功能 , 都要对上有的相关接口进行改造;举个例子:假如系统A要发送数据给系统B和C , 发送给每个系统的数据可能有差异 , 因此系统A对要发送给每个系统的数据进行了组装 , 然后逐一发送;当代码上线后 , 新增了一个需求:把数据也发送给D 。此时就需要修改A系统 , 让他感知到D的存在 , 同时把数据处理好给D 。在这个过程中你会看到 , 每接入一个下游系统 , 都要对A系统进行代码改造 , 开发联调的效率很低 。其整体架构如下图:
文章插图
2、 面对大流量并发时 , 容易被冲垮 。每个接口模块的吞吐能力是有限的 , 这个上限能力如果堤坝 , 当大流量(洪水)来临时 , 容易被冲垮 。
3、 存在性能问题 。RPC接口基本上是同步调用 , 整体的服务性能遵循“木桶理论” , 即链路中最慢的那个接口 。比如A调用B/C/D都是50ms , 但此时B又调用了B1 , 花费2000ms , 那么直接就拖累了整个服务性能 。
文章插图
根据上述的几个问题 , 在设计系统时可以明确要达到的目标:
- 1、要做到系统解耦 , 当新的模块接进来时 , 可以做到代码改动最小;
2、设置流量缓冲池 , 可以让后端系统按照自身吞吐能力进行消费 , 不被冲垮;
3、强弱依赖梳理 , 将非关键调用链路的操作异步化 , 提升整体系统的吞吐能力 , 比如上图中A、B、C、D是让用户发起付款 , 然后返回付款成功提示的几个关键流程 , 而B1是通知付款后通知商家发货的模块 , 那么实质上用户对B1完成的时间容忍度比较大(比如几秒之后) , 可以将其异步化 。
文章插图
【简单了解Java消息队列】
引入MQ之后的系统架构、交互方式与最初的链式调用架构非常不同 , 虽然可以解决上文提到的问题 , 但也要充分理解其原理特性来避免其带来的副作用 , 这里以消息队列如何保证“消息的可靠投递”为切入点 , 来看看MQ的实现方式 。
一、Client如何将消息可靠投递到MQ
- 1.Client发送消息给MQ
2.MQ将消息持久化后 , 发送Ack消息给Client , 此处有可能因为网络问题导致Ack消息无法发送到Client , 那么Client在等待超时后 , 会重传消息;
3.Client收到Ack消息后 , 认为消息已经投递成功 。
- 1.MQ将消息push给Client(或Client来pull消息)
2.Client得到消息并做完业务逻辑
3.Client发送Ack消息给MQ , 通知MQ删除该消息 , 此处有可能因为网络问题导致Ack失败 , 那么Client会重复消息 , 这里就引出消费幂等的问题;
4.MQ将已消费的消息删除
推荐阅读
- 直播APP安卓端实现推送功能的方法原来这么简单
- DDoS无解?网络攻击为什么花钱防不住?正确的解决方法了解一下?
- 你知道 Java 类是如何被加载的吗?
- 茄子怎么做才好吃?教你简单家常做法,蒜香味浓郁,特别下饭
- 干了的奶茶渍能洗掉吗 白衣服弄上奶茶一块如何简单处理
- 买茶叶,挑“红茶”还是“绿茶”_一篇文章带你了解!
- 计算机的灵魂“操作系统”,你对它了解多少?
- 动态路由协议OSPF基础了解,作为信息管理人员必须了解的网络技术
- 网络中的以太网及MAC地址协议封装,一分钟了解下
- 作为一名程序员,你真正了解CDN技术吗?