《饿了么:业务井喷时,订单系统架构这样演进》阅读笔记

1、背景数据库

  饿了么是一家创业公司,业务发展很是快,可能准备不是很充分,好比说监控、日志、告警、框架、消息、数据库,不少基础设施还在建设之中。缓存

  在这个过程当中出现一些问题是在所不免的,对系统的要求不是不能挂、不能出问题,而是出了问题要第一时间能恢复。服务器

2、“拆”以及跟“拆”对等的就是分治的思想网络

  怎么拆分呢?面向服务有不少拆分原则,罗列了如下几条:架构

  一、明确的定义:框架

  以前也确实犯了一些错误,为了拆而拆。其实咱们须要更明确,什么才算是一个服务?服务必定具备很是独立的技术能力或者业务能力,并且必定意义上可以很抽象ide

  二、松耦合:学习

  最基本的松耦合就是Customer的消费不依赖于Provider的某一个特定实现,这样服务器的内部变动不会影响外部消费,消费者能够切换到其余服务能力的提供方,这是最基本的松耦合。测试

  还有时间上的松耦合或者位置上的松耦合,咱们但愿的松耦合是消费方和服务方是能够分离的编码

  三、基于领域认知:

  这对于整个产品起到很是大的做用。

  由于当时整个饿了么全部系统是在一块儿的,基于领域的认知,在面向用户的维度和面向商户的维度作了切分,还有基于交易链路作了切分。

  四、单一职责与关注分离:

  简单说,咱们但愿一个服务或者一个模块拥有单一的能力,而不是承担过多的职责,不然责任不清晰,致使能力也不清晰。

  五、可被验证的结果:

  在订单拆分的过程当中咱们犯了一些错误,当时认为这样拆分是没有问题的,可是过1、两个月,并无带来效率和能力的提高,反而是跨团队的要求愈来愈多,能力要求也愈来愈多。这时候多是拆错了。若是是一个好的拆分必定有利于发展,拆分以后的发展是更迅速的。

  基于这几条原则,他们对饿了么的总体服务作拆分以后,如上图所示,架构就有了一些变化,看起来跟刚才架构区别不大。把Order Service作了分离。当时拆分虽然比较垂直,可是用户、商户、金融、订单等仍是有一些横向交互。

  一个接口有一个很是明确的Owner,一个表、一个库也能保证仅有单一的操做方,让我感觉比较直接的是,为服务的治理奠基了基础,之后能够针对某项特定业务作一些降级、熔断,以及单独的监控。拆分其实是让各自模块的掌控力变得更强了,对业务起到更好的支撑做用。

  这时每一个部门或者每一个团队都负责本身独立的领域,代码和数据都拆分完毕是否是就能够了?

  可是后来发现好像还不对。由于虽然大的领域上确实已经干净了,可是在小的领域上依然问题不少,订单并不只仅只有一张表,一个单一的模块,其实还有不少复杂的内容。

  在一些技术工做上,这些问题曝露得并非那么明显,那时候你们对于一些领域认知或者业务边界的认识仍是模糊的,没有人界定这些。可是当更进一步地去发展一个领域的时候,仍是会有职责不清晰或者能力模糊的地方。咱们思考,还要基于业务进行更细腻的规划。

  因而咱们把订单自己作了一些业务层次的拆分,拆分以前首先要确认订单到底在整个系统中,尤为是交易系统、O2O系统中承担什么角色,担负什么职责。

3、在这个思考过程当中,咱们的认知大概是如下四点:

  一、第一,订单是整个交易链路的核心,围绕了一些相关服务,好比金额计算服务、催单服务、售中异常服务等,咱们但愿这些服务之间有明确的区别。

  二、第二,订单实时处理是整个链路的中心,咱们将这个过程定义得尽可能简洁。

  一笔交易中,订单被推动得越复杂,说明系统设计得越复杂,出问题的几率也会越高。因此咱们但愿订单核心流程很是简单、轻薄,把复杂的东西剥离出来,把简单和复杂明确成两个部分。

  三、第三,考虑到交易的时效性和异常场景愈来愈复杂,将交易分红正向交易流程和逆向交易流程两个部分

  正向交易流程,99%的订单会根据这个流程走完生命周期;逆向交易流程,好比说退单要求时效性比较低,处理会牵扯多方业务可能很复杂,因此经过一个逆向的交易流程来解决。

  四、第四,可以在功能和业务上独立的部分,尽量抽象为单独的模块或服务

  简单来讲,好比催单的服务,它其实对交易链路没法起到推动做用,它只是一个动做或者附带服务,咱们把它单独抽象出来,为后面的发展作出铺垫。

   基于这些以后,咱们对订单进行完整的认知,对订单的服务架构和业务架构作成图中的样子,大概是三层。

  下面一层是基本数据;中间层是正向逆向的流程、最核心的状态和最关联的交易链上耦合的服务;上层是用户服务、商户服务,包括跟交易链相关的,好比饿了么最近推出的“准时达”的服务。

  监控和告警的峰值很是明显,午间和晚间两个高峰,其余时间流量相对平缓。下面主要讲三个部分。

  一、第一,对于订单而言,吞吐量是最须要重点关注的指标。

  一开始对业务指标的感知并非特别清晰,就在某一个接口耗费了不少时间。后来发现一些很小BD的问题不太容易从小接口感知到,可是从业务方面感知就比较明显,因此就更多关注业务指标的控制。

  二、第二,一般咱们重视系统指标,而容易忽视业务指标,其实业务指标更能反映出隐晦的问题。

  三、第三,目前咱们致力于基于监控和数据学习的过载保护和业务自动降级。

  虽然如今尚未彻底作好,可是已经能感受到一些效果。若是商户长时间不接单,用户会自动取消订单,自动取消功能的开关目前是人工控制的,咱们更但愿是系统来控制。

  好比说有大量订单取消了,有多是接单功能出了问题,就须要临时关闭这个功能,若是仍是依靠人来作,每每已经来不及,这时候就应该基于数据的学习,让系统自动降级这个功能。

  Kennel有四个主要的做用。

  一、首先,帮助咱们发现链路中隐蔽的缺陷,将小几率事件放大。好比说缓存不一致的问题,以前极少出现,一旦出现以后,处理手段比较缺少,那就能够经过Kennel来模拟。网络的抖动是很随机的,那么Kennel能够在某个时间段专门进行模拟,把小几率事件放大。若是怀疑某个地方出了问题,能够经过它来测试是否是真的能查出问题。

  二、第二,重大功能能够在发布以前经过其进行测试,迫使你更深刻地设计和编码。经过模拟流量或者线上流量回放,来检验系统运行是否如你设计那样工做,好比监控的曲线或者告警以及相关服务之间的依赖等。

  三、第三,咱们作了不少失败的准备和设计,要看到底会不会起做用、起多大做用。能够经过Kennel进行校验,在某个时间经过随机手段攻击相关服务,服务方不知道具体的攻击内容,这时本来设定的监控告警,降级熔断等措施有没有及时起做用就是一个很好的校验。同时还能够检验以前准备的容错或者补偿措施是否能按照预期工做。

  四、第四,须要验证FailOver的设计,只有验证经过才能够依靠。全部的设计都是经历了一次一次的失败,一些设计原觉得有用,可是真实问题发生时并无起到做用。真正有意义的FailOver设计必定是通过验证的。

 

  原文连接:

  https://mp.weixin.qq.com/s?__biz=MjM5MDE0Mjc4MA==&mid=2650993858&idx=1&sn=ce2cc36b737da8c00ba5cfb5cfe9488a&scene=21#wechat_redirect