消息中间件使用广泛,常用来削峰填谷、系统解耦、异步处理。异步处理可能是使用的最多的场景了,比如现在的技术博客网站,都采用积分制,用户发表一篇文章后,可以获取想要的积分,为了提升系统的性能,给用户加积分的操作可以异步处理,并不需要放在同步流程中。
我们可以把用户ID,需要增加的积分封装成一条消息投递到消息系统中,异步处理加积分操作,由于这是发生在不同服务器之间,消息有可能投递失败、处理失败等问题,从而导致用户加积分失败,还有一种可能是消息重复投递,那么用户就有可能重复加积分,不管出现那种情况,都是不正常的情况。
要避免上面的两种情况,就需要我们尽量保证消息不丢失和消息只被消费一次,这篇文章抛开具体的消息中间件,从消息系统的通用层面上,谈谈如何避免这两种情况。
1、保证消息不丢失
一条消息从生产到消费这条链路中,有三个地方可能会造成消息丢失,分别如下:
- 消息从生产者写入到消息队列的过程投递失败。
- 消息在消息队列中,持久化失败。
- 消息被消费者消费的过程出现异常。
1.1 在消息生产的过程中投递失败
消息生产者和消息系统一般都是独立部署在不同的服务器上,两台服务器之间要通信就要通过网络来完成,网络是不稳定,可能会发生抖动,那么数据就有可能丢失。网络发生抖动会有以下两种情况。
情景一ÿ