5

解决甩锅的一大难题,就是留个凭证

 3 years ago
source link: https://segmentfault.com/a/1190000040127591
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

解决甩锅的一大难题,就是留个凭证

原创:猿天地(微信公众号ID:cxytiandi),欢迎分享,转载请保留出处。

在多个团队之间的一些业务关联上,内部可以Rpc的方式进行交互。某些业务其实不需要强关联,这个时候就会用消息队列进行解耦操作。比如下单后加积分,发短信通知的这类操作。

在用消息队列的时候,我们最需要关注的一个问题就是消息会不会丢失?

这里的丢失指的就是要么你程序有问题,没有发送出去。要么发送出去了,但是在某个节点上消息丢掉了,导致消费方没有收到你发送的消息,从而引发业务问题。

对于消息丢失,有很多的解决方案。本文不聊怎么在技术层面去防止消息丢失,聊另一个话题:消息到底发没发送?

在多团队之间用消息解耦的场景下更容易出现这类问题,另一个团队的同学找你,说你们的消息是不是没发送啊,我这边这条数据的状态没流转,肯定没收到消息。

然后你屁颠屁颠的去消息队列的控制台进行消息的查询,发现确实查不到。主要问题在于这条数据是几个月之前的了,发送记录没有保存这么久,所以现在是有口难辩的这么一个状态。

别人说你没发,但你自己又拿不出来证据来证明自己发送过了消息。所以这个锅你只能自己背了。这就是今天要聊的话题,凡事要留个凭证,方便日后好追溯,特别是关键的业务场景。

存储发送记录到数据库

既然要留凭证,那么就需要将凭证存储起来。消息队列的消息量大,肯定不会全部永久存储,一般都是存储最近几天的量,所以直接利用消息队列去查有没有发送只适合最近的消息,时间比较久的就无从追溯了。

在消息发送后,可以直接存储到数据库中,方便后面查询发送记录。其实就跟短信记录一样的,短信也经常会遇到说这个短信我没收到,是不是没发送啊之类的问题。

存储需要考虑的就是量的问题,如果你们每天的消息量很大,还需要存储永久的数据,那么就得拆分了,或者采用外置其他数据库进行单独存储,比如MongoDB之类的NoSql。

存储发送记录到日志

另一种方案就是发送后直接输出一条日志即可,因为大部分公司都有统一的日志平台,去收集日志进行存储。这个方案就不用占用DB的存储或者说单独弄一套Nosql存储,比较省事。

但是需要注意的是日志的存储时间,像一些云厂商的日志服务是可以设置存储时间的,因为日志的量越大,成本越高。

在很久之前就遇到过发消息其实是打印了日志的,但是存储时间只有最近一个月。当别人来问你消息有没有发送的时候,你会发现当时的日志已经没有了,所以我们还是需要进行永久存储。

永久存储也就意味着成本的提高,其实我们可以将日志分类,普通的日志可以存储时间短一点,一些有用的日志可以单独进行输出收集和永久存储。这类日志的量相对少一点,成本可控。

直接用本地消息表发送

除了用开源的消息队列,很多公司也都会用本地消息表,单独的消息服务,基于数据库设计的消息队列这些形式来发送消息。这些形式的特点就是本身就基于DB做的持久化,所以对于查找有没有发送过消息是天然支持的。当然也有可能量大后即使分库分表了,后期还是要扩容或者定期归档,只要数据还在这个锅就背不了。

关于作者:尹吉欢,简单的技术爱好者,《Spring Cloud微服务-全栈技术与案例解析》, 《Spring Cloud微服务 入门 实战与进阶》作者, 公众号猿天地发起人。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK