一、什么是消息队列?
消息队列(Message Queue),是分布式系统中重要的组件,其通用的使用场景可以简单地描述为: 当不需要立即获得结果,但是并发量又需要进行控制的时候,差不多就是需要使用消息队列的时候
二、消息队列有什么用?
1. 提高响应速度
异步处理,串行化的功能变成并行化,从而提升系统性能,缩短响应时间 常用于秒杀、发送短信通知等,需要立即返回结果的场景
2. 流量控制
在高并发的情况,为了避免大量的请求冲击后端服务,可以使用消息队列暂存请求,后端服务按照自己的重能力,从队列中消费,例如秒杀、埋点场景。 这样可以随时增加服务的实例数量水平扩容,而不用对系统的其他部分做修改
3.系统解耦
例如一个下单的信息需要同步多个子系统,每个子系统都需要保存订单的数据的一部分,如果光靠订单服务的团队去维护所有的子系统数据同步,代价太大 解决方法是,通过发布订阅模型,订单服务在订单变化时发送一条消息到一个主题中,所有的下游子系统都订单主题,这样可以每个子系统都可以获得一份完整的订单数据 即使是增加、减少子系统,也不会对订单服务造成影响
三、消息队列有什么缺点?
- 同步消息改成了异步,增加了系统的调用链,增加了系统的复杂度
- 降低了数据一致性,如果要保持一致性,需要高代价的补偿(如分布式事务、对账)
- 引入了消息队列带来的延迟问题
四、如何自定义一个消息队列?
我们可使用 Queue 来实现消息队列,Queue 大体可分为以下三类:
双端队列(Deque)是 Queue 的子类也是 Queue 的补充类,头部和尾部都支持元素插入和获取; 阻塞队列指的是在元素操作时(添加或删除),如果没有成功,会阻塞等待执行,比如当添加元素时,如果队列元素已满,队列则会阻塞等待直到有空位时再插入; 非阻塞队列,和阻塞队列相反,它会直接返回操作的结果,而非阻塞等待操作,双端队列也属于非阻塞队列。
自定义消息队列的实现代码如下:
1 | |
以上程序的执行结果为
1 | |
可以看出消息是以先进先出顺序进行消费的。
实现自定义延迟队列需要实现 Delayed 接口,重写 getDelay() 方法,延迟队列完整实现代码如下:
1 | |
1 | |
同样,一个简易版的延迟消息队列就这样完成了!