设计消息中间件时我关心什么?(解密电商数据一致性与完整性实现,
《设计消息中间件时我关心什么?(解密电商数据一致性与完整性实现,含PPT)》要点: 导读:应对高可用及极端峰值,每个技术团队都有自己的优秀经验,但是这些方法远没有得到体系化的讨论.高可用架构在 6 月 25 日举办了『高压下的架构演进』专题活动,进行了闭门私董会研讨及对外开放的四个专题的演讲,期望能促进业界对应对峰值的方法及工具的讨论,本文是去哪儿网余昭辉介绍设计电商消息中间件的设计经验. 作者:余昭辉——去哪儿网 基础架构部架构师,2011 年加入去哪儿网,经历过去哪儿网从小到壮大,服务拆分的过程.现负责去哪儿网基础架构部,参与设计和开发去哪儿大大小小各种基础组件.本人对互联网电商中间件,并发和异步编程尤为感兴趣,是一个自我标榜 Clean Coder.热衷于与同行技术交流. 我来自去哪儿的基础架构部,我们部门负责公司的公共组件和基础服务,包括敏感信息存储、发号器、身份证认证、监控中心、任务调度、Redis 等. 今天主要给大家分享一下消息队列基础组件的设计. 我们是 2012 年初开始自研消息队列和消息中间件的,当时也是契合公司背景,原来公司有一些庞大的单模块系统,如机票交易系统和酒店交易系统等.为了对系统进行拆分,面临着系统拆分之后事务处理的问题,于是自研了消息中间件. (小编:上文滴滴passport设计之道:帐号体系高可用的7条经验也多次提到了大系统做小的经验与实践,感兴趣的读者可以参阅) 现在去哪儿网基本所有交易环节都通过消息的方式流转,使用了一种消息驱动的架构,像订单的流转、支付等,消息中间件已经成为核心基础设施,对交易系统非常关键.最初设计消息中间件是为了满足交易场景,后来大家觉得 API 使用非常方便,现在其他业务包括部分搜索等等功能也切到这个上面来. 截止目前,除了部分搜索场景是 AMQ,公司其他业务的都使用了自研的消息中间件,一些基本数据如下:
消息中间件模型说简单也很简单,最小单元就是一条消息,所以伸缩、扩展非常容易,只要根据消息进行 hash.当中间件承受不住压力的候,扩展是非常简单的.另外一方面说它复杂也很复杂,消息中间件作为一个公司的基础组件,如果它出问题就是一个很严重的事情.消息中间件出一次故障,就是 6 ~ 7 个部门报 P1 故障. 这便是它的复杂所在,如何保证它的正常运行,那么在介绍内容之前,先说明一下上下文:今天讲的仅仅是适用交易环节的消息中间件,跟通常所说的社交领域的消息中间件有很大的不同. 在交易环节,需要考虑 3 个方面 :
在电商的场景前面两条要高于性能要求,也是今天要重点讨论的部分. 典型的消息中间件包含 3 部分 :producer(发布者)、broker(消息中间件)、consumer(消费者),是一个比较简单的模型,下图展示了把消息发送给 consumer 的全过程.? Producer 发布端设计Producer 消息发布端主要关注一致性、容灾、性能. 分布式事务一致性的难题 上图是一个订票的订单服务,生成的新订单.如果订单持久化成功(上面的红框 ),消息发送失败( 下面的红框 ).那么用户看到下单成功,假设代理商服务订阅这个消息是否给用户出票,那么现在的情况就是票没出来,这会引起用户投诉.但是如果先发消息,然后再持久化订单,那可能就是订单出票了,但其实这个订单还没下呢,这就会造成公司的损失. 这种一致性问题怎么解决? 大家可能会想到分布式事务,比如 2PC(Two phase commit).业内已经有很多文章介绍了分布式事务的利弊,它的成本还是比较高,在此不做讨论,下面主要介绍电商系统中应用比较多的另外一种方法. 数据库的一致性 先来看一下数据库中的事务 在一个 DB 实例中,比如 3306 这个,使用同一个连接,对多个库的操作是可以放在同一个事务里的.这样是可以保证数据的一致性,这是由数据库决定.比如图中的业务 DB1,业务 DB2 和一个消息 DB 都在同一个实例里,是可以放在同一个事务里的. 业务数据的一致性保证 有了数据库这层保证,就可以用这种方式来实现业务操作和消息发送了. 先将订单持久化在同一个事务里,共享订单操作的数据库连接,在这个连接里将消息持久化到同一个实例里的消息库里,然后在事务提交之后将消息发送到消息的 server.如果事务回滚了,消息就不会发送出去了. 详细看一下流程图 : (编辑:ASP站长网) |