Photo @NeONBRAN

文 | 李杰

前言:

本文介绍了饿了么交付中心由 Python 语言栈转换到 Java 语言栈大致过程,一来是对前段时间的工作做下总结,另外也是想通过此次总结为其他应用服务转型提供些借鉴。写的不好,欢迎板砖。

背景


饿了么并入阿里集团,为了能高效与集团内部系统协同对接,同时方便利用集团优势技术资源,更好的融入阿里集团技术生态圈,饿了么交易中台在上半年启动了交易领域的四大应用语言栈转型项目,为阿里集团本地生活服务平台打好技术平台基础做准备。另外,随着业务量的激增,饿了么平台支持的品类不仅仅是最初的外卖单品,整个交易中台也需要一次相对大的重构来快速应对复杂多变的业务需求。而本文中的交付中心即是饿了么交易领域四大应用之一。

准备


在开展相关工作之前,首先必须得清楚我们是要将一个系统从什么样变成什么样,新的系统相较老的系统在哪些方面做的更好,同时必须保证新老系统的无缝切换,做到业务无感不影响交易系统的稳定性。

系统价值

外卖订单的业务特点是重交易, C 端用户从下单选餐到骑手完成餐品交付过程,目前大部分都能在半小时左右完成,对即时配送实时性要求较高。整个订单交易过程大致划分为:

1.添加购物车确认订单。

2.订单生成及订单支付。

3.接单及订单交付。

4.可能的售后退单。而要更好的服务用户,对四个系统稳定的协同能力提出很高的要求。

如前文所述,我们知道履约环节对交易订单的价值是什么,即是将外卖订单对应的餐品交付到用户手中,技术层面上来讲,交付对交易订单屏蔽了一切其他履约细节,使订单更专注订单领域业务。

内核分析

接下来,我们再进一步详细的剖析下转型前交付系统所承载的功能。

如上图所示,原交付履约领域中包含了三个较大板块:

  • 订单对接运力线模块

  • 商户订单信息模块

  • 部分金额计算模块

可以看出原系统所承载功能并非真正聚焦在订单交付过程。怎么办?转型重构是个契机。商户订单回归到订单,金额计算下沉至结算,这两部分的相关转型重构这里不再赘述,相关部分也已由兄弟团队完成。其实到这里交付履约应该关注的已经很明显:把外卖订单给运力线,使其完成交付履约。

基于刚才提取后的交付履约核心领域,我们对主要的场景用例进行了详细的梳理。如下图所示,可以看到:

    • 参与交付过程的主要角色有四个:

      • 商户

      • 订单

      • 履约运力线

      • 用户

    • 交付提供的主要支撑能力有:

      • 乎单交付能力

      • 运单状态同步能力

      • 运单信息透出能力

      • 履约方式切换能力

      • 运单状态广播触达下游能力等。

    • 部分运单取消或异常管理。

系统核心用例分析如下图所示:

更详细的系统用例梳理或系统上下游交互时序这里不再一一列举,需要说明一点,当大流量系统转型遇到重构,要想走的够远够稳,前期的仔细调研工作及功能对齐过程非常重要。特别是生产环境已经跑了好几年核心功能系统,实际业务情况错综复杂。例如要转型重构系统接口能力,接口含义,场景必须都要详细掌握。

设计


至此,我们的目标已经很明确:

1.语言栈转型。

2.过程中要将不属于交付的东西从原系统中分离出去,使得交付领域更干净。

结合交付未来可能的发展方向,其中交付能力可复用的,履约运力线可扩展的。这对整个交付可快速迭代对接提出了更高要求。另外,我们也在领域建模设计思想指导下做了些实践尝试,于是有了以下框架结构。

系统设计

转型是把 Python 方言转换到 Java 方言,交付系统核心能力不会有变化。能力的复用是通过接口维度的抽象聚合产生,履约运力线能力可扩展通过利用业务框架扩展点特性满足。拆分后的业务框架应如下图所示:

系统架构

业务框架结合当前饿场基础组件支持我们不难给出以下系统内部模块划分:

简单对各组成模块做简要说明:

  • Api:处于业务框架中上游系统接入层,对外暴漏契约屏蔽细节,对内定义系统能力。

  • starter:启动项目

  • service:rpc服务暴漏

  • domain:核心业务能力实现,聚合层

  • infra:基础数据支撑能力层

  • extension:履约能力扩展层

  • tester:单元测试包

到此,我们可以按照设计与既定的计划撸代码了。

嗯,代码撸完了测完了,从调研到开发完成历时两个半月,代码仓库总行数约 4.7w 行,提交 1000 次左右,完成 63 个接口 +16 个消息消费入口转型迁移,共计测出 117+bug ,期间有喜有忧,奋战两点多是常态。职业生涯中浓重的一笔。此时尤记起与 超哥@邹超周 末代理联调于北 14 楼小黑屋之畔,和 明龙@张明龙 并肩作战对接服务接口,还有 晓波@俞晓波 凌晨一同压测观察总结问题第二天分析反馈提升优化,当然还有 杰哥@汤良杰 的用例设计全面不失细节、对 bug 常常究其根本,对代码 review 逻辑核对一丝不苟明察秋毫。凡此种种,历历在目。一起走来,真心感谢。

------  不由自主的感概  

平稳过渡


代码撸完测完才做好转型工作的第一步,将流量稳步平滑过渡到新的服务中,做到上下游无感是转型过程中面临的另一大挑战。

说到这里,要达到系统的语言转型前后的平稳过渡其实是在说转型前后对我们系统的用户 SLA(Service Level Agreement) 提供一致性的保证。这里先简单聊聊系统服务的 SLA 。

上表格是业界服务高可用的几个级别的衡量标准,例如:服务可用性是 3 个 9 时,全年宕机时长约为 8.76 天的统计概率。另外,我们需要明确的是不同的系统,不同的场景以及不同的用户规模对系统可用性要求是不一样的。如:某些业务的支付链路场景可能 tps 不是很高,但是作为交易的核型链路必须得保证高级别的可用性。

怎么保证或者提升系统服务的 SLA 呢?在明确我们目标后,接下来就是拆解目标量化目标。

you cant measure it,you cant fix it and improve it.

一般来说,影响系统服务可用性有两个重要因子:

  • MTBF:Mean Time Between Failures,系统服务平均故障时间间隔。

  • MTTR:Mean Time To Recover,系统服务平均故障恢复时间时长。

所以大致可以简单归纳为这样的一个函数关系:

可能无法给到一个精确的数学描述,但是可以做定性的分析:恢复时长因子与系统可用度成正相关,故障间隔因子与系统可用度成逆相关。也即:问题出现时恢复时长要尽可能的短,尽可能降低故障频率以增大故障间隔。

基于以上理论,我们在做系统平稳过渡无缝切换时,无论资源使用,业务内部逻辑实现及灰度方案,我们都需要着眼于这两个方面。接下来我们将从这两个点出发分析转型过程存在的挑战及我们的应对方式。

快速响应,降低恢复时长

要做到恢复时长尽可能的短,首先我们需要保证在前期出现问题时流量切换过程中流量规模尽可能的小,即需要一个相对的合理的灰度梯度方案。其次当问题出现后我门需要能立即回切到原系统,不至于反应过慢导致大量增量问题产生,即需要一个响应高效的开关回滚方案。由于转型过程中涉及的接口和消息消费入口较多,另外我们还需要考虑到后期问题排障和快速定位的可能耗时。

  • 针对灰度梯度合理制定,根据业务特征,开始阶段我们选择了较冷门城市(订单量较低)进行了各个运力标品业务的逻辑验证。标品验证完后说明我们新迁移实现的逻辑和原系统具有一致性。随后我们拉取了当前订单城市分布,根据城市订单分布占比制定灰度梯度,由小到大逐步增加。

  • 针对回切需要响应高效,我们应该有一个总的开关可以控制流量,回切应该是一键控制的。

  • 针对排障快速定位,灰度单生命周期内的操作能在单应用内自闭合,不至于排障时还需要确认灰度单某个状态到底走的原系统服务还是新系统服务。另外我们还希望,写操作灰度和查询灰度能单独隔离开,等写数据完全一致的情况下我们再开启新数据新接口查的灰度,将风险控制到最低。

所以我们采用了如下的老系统服务代理方案:

如上图所示,订单系统创建订单时根据既定的灰度计划读取配置给订单打标,灰度计划分为前期分标品,门店维度验证,后期按城市订单分布维度配置。若新系统服务出现问题可一键切掉灰度流量,止血增量问题。接着,原交付老服务识别标记做代理转发,订单不存在迁移标记则原流程操作处理,否则转发到新交付中心新服务操作处理,相应的消息监听处理同样也是参照订单标记,这样保证了同一个订单的交付过程能在一个应用中完成,有利于后期处理流量上来后的快速问题定位。

另外,我们的接口灰度过程是写与查分离的,整个迁移过程大致分为三个阶段,如下图所示:

  • 第一阶段 灰度写阶段,灰度策略:餐厅维度,城市维度小范围灰度,读流量以老服务为准,问题出现及时切掉灰度写流量,逻辑回滚至老服务。

  • 第二阶段 灰度查询阶段,灰度标记流量以新服务为准,非灰度标记以老服务透出为准,灰度策略:各个查询接口按照百分比逐步增加灰度占比。

  • 第三阶段 迁移阶段,完成读写灰度,原系统老服务只是代理的一层皮,接下来就是上游系统迁移到新服务,去掉对原原系统服务的依赖,迁移完成。

最大努力降低故障风险

平均故障间隔是一个后验时长数据,要做到间隔时长尽可能的长,日常里就需做好发布控制,风险巡检及持续监控等工作。

1.发布控制

转型期间新系统服务必须遵循发布sop,饿场发布sop已经形成共识,我们只需严格遵守,这里不再赘述。

2.风险巡检
  • 系统逻辑核对,多人多次code review。

  • 变更发布前主干场景自动化用例全通过。

  • 周期性压测。

3.多层次持续监控
  • 部署机器,缓存集群,消息队列,数据库表等基础资源的基准监控。

  • 业务曲线成功率,日同比,周同比,曲线波动比,及主要接口入口流量到下游出口流量转换率监控,业务系统成熟后还应对各个服务响应时间指标做监控等。

  • 系统中很多情况下重试都是以异常中断为依据,这必然会对系统异常点带来较大的噪音。为此我们还需要细化各个中断异常的打点,排除不必要的干扰。

一致性问题

转型过程中我们实际上同时做了数据模型优化迁移,对外为了保证新老系统行为属性的一致性,我们还面临以下几个挑战:

  • 灰度数据需要双写新老交付系统库表,如何保证双侧底层数据的一致性?

  • 底层数据一致不等于对外服务接口数据透出一致,双侧服务应用层面怎么保证数据的一致性?

  • 订单阿波罗履约线和交付的上下游数据数据最终一致性怎么保证怎么验证?

一致性的保证,别无他法,只能通过比对来做。但在做比对的时候我们还需要考虑到比对本身只是我们验证迁移系统正确性及稳定性的一部分属旁路,并非生产环境的必须功能。即我们得考虑这部分功能对现有系统可能造成的压力。这部分压力应该是随着系统验证完毕是可开关的,压力大小应随系统的表现可随时调节。不至于因为验证拖垮了生产应用。所以我们对比对的基本要求是:能一键开关,可监控可追溯。除了这些共性,具体还应做到以下几点:

  • 针对底层数据比对:

    • 比对应是准实时的,如只比对30分钟前的数据。

    • 比对数据是基于时间可分段采样的,如只比对10分钟以内产生的数据。

    • 为了方便控制,根据情况以上策略又可以是及时调节的。即准实时偏移量可调节,分段采样窗口大小可调节。

具体实施方案如下:

  • 针对应用层数据比对:

    • 代理层接收请求后,比对应是异步的,不影响接口响应耗时。

    • 比对粒度要小,应细化到接口。

    • 识别灰度数据,只做有效比对。

具体实施方案如下:

无论数据层面还是接口层面出现比对不一致,应立刻去分析是什么原因导致不一致。解决根因逐步降噪,只至比对差异在我们认为可接受的范围内。

  • 针对上下游数据最终一致性:

    • 全量数据核对

    • 主干链路最终一致性核对

经过数据准实时比对,接口实时异步比对,其实基本可以确认新老系统能力行为属性对等性。然而稳定大于一切,要百分百确定还需要t+1数据核验。即从全局数据角度看新老系统转换的影响。这里以主干链路呼单多日成功率为例做简要说明。如下图所示,多日乎单成功率基本在99.9977%左右,可以认为新老系统代理切换交付成功率基本表现稳定。

未来


截止此文攥写时间,饿了么交付中心已经完成了整个系统的语言转换,流量也已经100%切换代理到新系统,处于流量切换的第三阶段。结合日常系统维护与需求迭代实践,我们仍需要再以下几个方面进行更深入的思考:

  • 转型过程中为了在易测,可核对同时与python的“魔法”姿势斗争中找平衡,部分逻辑是"纯翻译"的,后期维护过程很痛苦,所以我们需要几次不小的重构来达到代码层面的和谐。

  • 不断监控降噪,持续细化监控粒度,监控是服务稳定基石。

  • 交付中心数据大盘建设,从数据层面量化观测我们的交付质量。数据驱动,数字运营从数据化思维优化我们的流程,提高我们的服务。

方法论沉淀


凡此以上,服务系统转型迁移归结于开发者理解与认知,项目的稳定实施归结于开发者套路方法运用。可以简单进一步提炼为以下方法论:

  • 详细调研,客观问题及满足业务的系统是复杂的,详细调研做好准备是必须的。

  • 持续监控,感知系统的质量是服务质量度量的第一步,不断持续的监控才能走的更稳。

  • 稳步过渡,互联网系统服务高可用稳定不容商量。

  • 问题发现根因解决,小的问题可能隐藏大的bug,认真对待究其根本,复盘->总结->提升。

  • 归纳总结业务再认知。

关于认知提升的几个小点:

  • 对于每一位工程师,开发高并发大流量系统是挑战也是机遇。时刻保持进取学习心态,增强自身软素质。

  • 分布式情况下,承认系统并非绝对100%可靠,每一个环节都要考虑“失败”了怎么办,不同的场景我们需要在AP和CP之间作出抉择。如双链路调用保证可靠,异步重试保证顺序最终一致等。

  • 出了问题快速恢复是个永恒的话题,没有“怎么样“最快只有”这样”更快。精准定位立即恢复,如何将这个过程耗时降到更低值得深入思考。


http://www.taodudu.cc/news/show-149130.html

相关文章:

  • 高德亿级流量接入层服务的演化之路
  • Java 编程技巧之数据结构
  • 高德引擎构建及持续集成技术演进之路
  • 分布式事务 GTS 的价值和原理浅析
  • Java编码技巧之高效代码50例
  • 写给工程师的十条精进原则
  • 美团点评基于 Flink 的实时数仓建设实践
  • 如何优雅的设计一个告警系统?远没有你想的那么简单!
  • 一步一图,带你了解分布式架构的前世今生!
  • 程序员上班啥也不干年入140万,网友:这操作绝了!
  • 扎心一问!为什么前后端分离后,你比从前更痛苦?
  • 高频面试考点:Redis中有几百万数据量,如何进行高效访问?
  • 头条面试归来,有些话想和Java程序员说!
  • 从 Nginx 优秀的核心架构设计,揭秘其为何能支持高并发?
  • 【系统缓慢、CPU 100%、频繁Full GC问题】的定位排查思路!
  • 写给程序员的 HR 面试指南,助你踢好面试的临门一脚!
  • 不能精准定位bug?可能是你没get到这几个打印日志的诀窍!
  • 你应该避免的8种常见SQL错误用法!
  • 简历包装要避开哪些坑,资深面试官告诉你!
  • Java 垃圾回收机制,13张图给你讲清楚!
  • 面试被问到秒杀系统,这个点你一定得答到!
  • 大型电商网站详情页是如何支撑亿级流量访问的?
  • 阿里不让多表join?我偏要!
  • 有别于BATJ,滴滴的中台数据体系建设怎么另辟蹊径?
  • Spring 中的各种注解,光会用可不够哦!
  • Java开发中最常犯的10个错误,你中招了吗?
  • 饿了么监控体系:从架构的减法中演进而来
  • REST API安全认证研究!
  • 小红书做直播的背后,隐藏了什么秘密?
  • 中小型金融企业该如何进行灾备建设?

饿了么交付中心语言栈转型总结相关推荐

  1. 车企数字化转型研究:如何实现“以用户为中心”的数字化转型?

    已剪辑自: https://mp.weixin.qq.com/s?__biz=MzA4NTcwMDQwMg==&mid=2650818314&idx=1&sn=05d57f87 ...

  2. 数据中心进行数字化转型的2019年

       随着45亿人口中实现网络互联的比例不断攀升,亚太地区已经成为全球数据中心发展最快的市场之一.分析师称,该地区预计将在2020年成为全球最大的数据中心市场,未来四年内将有超过三分之二的新数据中心落 ...

  3. 互联网日报 | 京东开启最大规模校招;特斯拉西部首个交付中心在蓉投入使用;嫦娥五号上升器点火起飞...

    今日看点 ✦ 嫦娥五号上升器成功点火起飞,实现我国首次地外天体起飞 ✦ 京东面向2021届高校毕业生开启最大规模校招,提供1.5万个就业岗位 ✦ 特斯拉成都龙泉交付中心正式投入使用,目前中国西部最大的 ...

  4. 阿里云全球交付中心正式成立,打造一流的全球服务能力

    在 9 月 22 日刚刚结束的 2018 杭州•云栖大会上,阿里云宣布成立全球交付中心(Global Delivery Center,GDC),这也意味着阿里云把建设全球范围的交付能力放到了更高的位置 ...

  5. 企业数据中心“云化”转型解决方案

    本文章全文约 5000 字,阅读约需 7 分钟, 以下为正文. 数字化转型正在对企业产生深远影响,面对业务数字化.互联网化.智能化对企业数据中心在性能.敏捷性.总拥有成本等方面提出的更高要求,传统数据 ...

  6. 理想汽车10月份新增12家直营交付中心 蔚来第1000座充电站上线

    理想汽车在其微信公众号上发布消息称,10月份,理想汽车新增12家直营交付中心,分别是福州青口.泉州晋江.金华金东3家正式交付中心,以及邯郸.襄阳.拉萨.榆林.遵义.汕头.中山.赣州.湛江9家合作交付中 ...

  7. 蔚来首座超充站落地苏州蔚来交付中心 已开启试运营

    7月10日消息,蔚来官方微博今日文称,蔚来首座超充站已坐落于苏州蔚来交付中心,向车主开启试运营.7月9日到7月15日,蔚来车主可享受超充桩充电免单服务. 根据官方介绍,蔚来此次推出的超级充电桩可以提供 ...

  8. c语言栈训练题目:括号匹配

    c语言栈训练题目:括号匹配 基本思路: 当前字符不是括号,不做处理: 当前字符是左括号,则进栈: 当前字符是右括号:若栈空,则表明该"右括号"多余,不匹 配,结束:否则和栈顶元素比 ...

  9. 世纪互联交付中心总监李少春:数据中心基础与服务探讨

    近日,TGO 鲲鹏会广州分会会员.世纪互联交付中心总监李少春作为 TGO 线上分享第五季的嘉宾,以直播的形式向大家分享了数据中心基础与服务探讨.本文根据当天直播内容整理.更多精彩内容请关注公众号:TG ...

最新文章

  1. mac 从终端打开应用程序
  2. 10行代码理解Java锁消除
  3. mysql 整数_MySQL 整数(int)数据类型
  4. android 音乐资源获取失败,android – 获取嵌入式mp3文件嵌入式艺术失败
  5. 网址收藏 2020.12.11
  6. php get教程,PHP $_GET 变量
  7. 什么是python元祖_Python学习之元组
  8. 基本数据结构之Sort
  9. varnish4.0简介
  10. JS 对象(Object)和字符串(String)互转方法
  11. java多线程条件变量_30秒带你读懂Java并发包工具(JUC)之Condition(并发条件变量)...
  12. 安装nuxt_一天上手Nuxt基于vue服务端渲染
  13. Spring核心之一:Spring的配置文件是干什么的
  14. iOS13适配暗黑模式/夜间模式/深色模式/暗黑主题(DarkMode)
  15. 01 Python学习--第一周--开课介绍、数据类型、数据运算、表达式、循环、三元运算、对象基本概念...
  16. 【中土世界】萨鲁曼小传
  17. 【Power BI+Excel+Python】2019年4月全国数据分析招聘岗位可视化分析
  18. 算法分析与设计期末总结
  19. 如何从零开始建站,四个步骤了解一下
  20. java机票实时比价系统计算机毕业设计MyBatis+系统+LW文档+源码+调试部署

热门文章

  1. LSTM情感分类问题再战
  2. 2021牛客暑期多校训练营3 I-Kuriyama Mirai and Exclusive Or (差分+位运算)
  3. php 求 相似 比,php计算title标题相似比
  4. java表或视图不存在_Error querying database. Cause: java.sql.SQLSyntaxErrorException: ORA-00942: 表或视图不存在...
  5. wampserver下安装redis_金山云redis安装与连接
  6. 回归方程的拟合优度检验_计量经济学第四讲(多元线性回归模型:基本假定,参数估计,统计检验)...
  7. 各大厂分布式链路跟踪系统架构对比
  8. mysql的外键探讨
  9. AndroidStudio-4-如何导入项目
  10. 【原创】浅说windows下的中断请求级IRQL