大家好,我是刘超,来自途牛订单中心部门。今天主要给大家分享下,途牛的订单系统服务化演进,与大家碰撞交流思维。

今天将从几个方面来进行分享:

  1. 背景
  2. 业务拆分
  3. 基础设施
  4. 集成开发
  5. 服务监控

首先说下,途牛最近几年的发展速度很快。

 


2013年以前大概只有屈指可数的几种业务类型,到今天已经发展到60多种业务类型的订单,我选了几个类型的订单量的数据做了个图表。

 


可以看到无论从业务类型还是业务量来说,都是飞速发展的,而像所有的公司的发展一样,我们也是从一个系统发展到今天成百上千个系统。


一个系统无论视同开发还是运行时的资源,都无法满足业务的需求,服务化是我们架构演进的方向,不是为了服务化而去做服务化,是由业务发展的复杂度和发展的业务量驱动的架构进化,是为了满足更快速的支撑更大规模的更复杂业务规则的扩展性要求设计,所以,我们做第一步,垂直拆分。



以上图形大致的描述旅游订单的概念模型,所以,随着业务的发展我们首先就把我们订单系统拆分成了会员、产品、资源、促销等等系统。


各系统通过WebService或者Rest等方式集成,以前最流行的SOA实施方式,看起来解决了业务发展过程中存在的一些问题。


业务类型较少的情况下解决了部分运行时资源紧张和故障隔离问题,代码拆分出来,项目构建影响小。就是松耦合,独立演进等等。


在只有一只手可以数的清楚的业务类型下,这种可以说基本上解决了我们一些问题,但是,我们的业务发展太速度了,每一种类型的订单,基本上都离不开这些领域的数据的交互,但是业务规则变化多样。


如果按照原来的思路,继续不断的增加一些类型判断如if...else...也能满足我们的要求,但是到最后可能就是 四五十个if else,而且相互影响,每个规则都相似又不同,所以其实大家发现了,其实这个时候订单的组装业务的规则已经成了现在的主要矛盾。


设计的问题,加一层就能解决很多问题,这个时候其实我们就需要吧我们的一些公共的服务(订单域)抽象出来,变化的规则通过具体的服务组装和编排去解决。


这个其实远了,我想说的就是,业务拆分,SOA能解决一部分问题,但是也有缺点,没有统一的管理,调用链不知谁依赖了谁,可靠性,可用性等的监控得不到保障,所以,这时候我们进入了 服务化的第二阶段 服务治理。


通过合理的管理和监控,保证所有的调用有据可循,有序有章法。


这个时候需要 服务治理的基础设施,我们研发的服务治理框架就是来解决这个问题:


基本上所有的分布式调用框架的思路都大同小异,注册中心:服务注册、审核、变更、发现。

  •   服务提供者:暴露服务接口的服务提供方。
  •   服务消费者:调用远程服务接口的服务消费方。
  •   监控中心:统计服务的调用次数、时间、结果等。


服务消费者通用组件:根据配置下载指定服务的可用服务地址列表,并缓存在本地。响应服务地址列表变更通知,更新本地可用服务地址列表。提供到注册中心长连接的重连机制。


服务提供者通用组件:启动时根据注解自动扫描提供的服务详情,上传提供的服务地址列表到注册中心,内建了还有并发控制等功能,序列化是通用的jsong,http请求,主要是方便各系统的集成,还是由于业务的不断发展,需要不断拆分,对于一些系统故障,或者流量异常怎么办?


通过设计合理的调用日志,出入参,发起方落地房,调用序列号,时长等,将日志发送到ELK平台,实施监控一些异常信息,在异常信息中也去封装调用序列号,能够对部分小范围的单点的故障现场起到快速定位的作用。


发现所依赖的服务挂了,如何处理,有可能会吧把整个容器拖挂,我们在框架中集成了 Hystrix 组件,当挂住的线程超过了一定的数量则会快速返回,从而达到降级的效果。


看起来这些服务治理的问题都搞定了,接下来该怎么走。


如果你的业务复杂度不再增长了,但是业务量增长了,或许我们就要针对单一功能的容量和性能等可靠性要求进行设计,可能这时候进行弹性资源分配,或者分库分表等设计就要入场了。


做服务化的好处就是职责更明确,不重复造轮子,另外一个方面也是提高了标准化,让专业的人做专业的事情,所以我们订单系统到目前为止 就时做公共的底层平台,成为能力中心,尽量做到最小力度的服务,在不同层次上抽象服务。


服务化到最后就成了微服务,现在很流行,也可能使我们未来的发展方向,但是,都是优点吗?不一定,现在存在的问题 :开发 调用接口困难,接口稳定 异步,沟通成本大。


有些比如异步的调试,跟踪也很烦,那么可以解决吗?


没有人解决不了的问题,我们也在努力的推行一些好的实践,稳定接口和mock测试桩,自动化测试用例,持续集成。看起来我们的沟通成本增加,开发联调复杂度增加,但个人感觉其实我们已经支撑了更加复杂和更大量的业务。


牺牲一小部分去换取更大规模的业务,这是值得的,所以总结下:


我们服务化的过程就是 拆分-》治理-》拆分,其实是一个不断迭代的过程,是随着业务发展和业务认知深度的发展而不断的拆分和治理的迭代。


Q&A

1.
Q:服务化之后问题定位一般多长时间,主要花在哪里?
A:基本上是比较快的,通过接口调用日志,进行调用链分析,异常日志中也包含了每次调用的序列号,所以基本上较快能解决问题,大概十分钟左右,我们的监控集成了一些APM ,还有一些异常告警。

2.
Q:如何保证这一系列的原子性操作?比如下单来说,要调用好几个服务,如果一个服务出现异常,就会造成数据不一致。

A:OK,这个问题不错。会区分关键性业务和非关键性业务,其实还是流程驱动,连续的调用链中可能存在一些非主流程的东西,这个时候我们可能直接保存下异常数据,主流程的话会直接回滚。