SOFA:Channel/,有趣实用的分布式架构频道。 SOFA:Channel/ 作为 SOFA 所有在线内容的承载,包含直播/音视频教程,集中体现 SOFAStack 的能力全景图。欢迎加入直播互动钉钉群:23127468(搜索群号加入即可)。
大家晚上好,今天是 SOFAChannel 第一次线上直播,感谢大家的收看。
先自我介绍下,我是来自蚂蚁金服中间件的章耿,花名余淮,目前在负责应用框架与 SOFAStack 开源相关的工作。
今天给大家的分享主要分为三部分,第一部分是蚂蚁金服服务化演进的简介,第二部分是SOFAStack开源的情况。这两部分之前的分享也提到过,我们讲快一点,第三部分会详细介绍下 SOFARPC 的一些设计和实现细节。
分享过程中如果大家对技术点比较感兴趣,或者其他组件感兴趣,也欢迎留言,后面的直播会安排更多的相关分享。
蚂蚁服务化架构演进简介
大家现在对蚂蚁金服技术的概念,听得比较多的应该是“余额宝”、“相互宝”、“蚂蚁森林”、“刷脸支付”,“扫描工具地铁”、“双十一”等等这些耳耳熟能详的产品和场景。
这些产品的背后,是蚂蚁金融科技的一套核心技术,包括 “三地五中心异地多活架构”,“金融级分布式架构”、“国产金融级分布式数据库 OceanBase”,“智能风控”,“区块链” 等诸多黑科技。
当然,蚂蚁金服的微服务架构体系像其它传统的企业一样,也不是一开始就这么高大上,也是随着业务的发展慢慢演进而来的。下面给大家简单介绍下演进的过程。
这个支付宝最早的架构示意图,可以看到当时支付宝只是电商后台的一个支付系统,是一个单体应用,里面简单的分了几个业务模块,连的也是一个数据库。但随着业务规模的不断扩展,单系统架构已经无法满足业务需求。
所以支付宝就对大系统进行了拆分,将原来的一个单体应用内部的多个模块变成了多个独立的子系统,这算是典型的 SOA 化的架构。
最开始系统之间是使用 F5 的硬件负载设备来做系统间的负载均衡,但由于 F5 设备存在单点的问题,所以后面就在中间引入一个注册中心的组件。服务提供者去注册中心注册服务,服务消费者去注册中心订阅服务列表,服务消费者通过软负载方式通过 RPC 框架直接调用服务提供者。这在现在看来是一种非常显而易见的服务化架构,但当时 07 年就采用这样的架构还是算比较超前的。
支付宝在做系统拆分的同时,对数据库也按子系统进行了垂直拆分。数据库的拆分就会引入分布式事务的问题,蚂蚁金服中间件就提供了基于 TCC 思想的分布式事务组件 DTX。
业务还是不断扩展,系统也越来越多,当系统节点到一定数量的时候,单个物理机房已经无法承受。另外考虑到同城容灾的问题,支付宝就在同城再扩建另外一个机房,通过专线部署为一个内部网络,然后将应用部署上去。
同城多机房会引入一个跨机房远程访问的问题,相比同机房调用,这个延迟损耗一定是更高的。远程访问主要包括两种:RPC 调用和数据库访问。为了解决 RPC 跨机房调用的问题,支付宝的工程师选择的方案是在每个机房都部署注册中心,同机房优先调用本机房服务的方式,也就变成图中的部署模式。但是数据库跨机房访问的问题,在这个阶段并没有解决。
另外还存在的一个问题就是调用链路混乱以及数据库连接瓶颈的调用。例如这个图里,我们对数据进行了分片,然后图中的 user0 的请求进来后,随机转到 S2,再随机转到B0,在随机到C1,最终跟进数据分配落到了数据库 D0。可以看到这里的调用链路是随机的,而每一个核心层也需要跟所有的分库都建立长连接。
为了解决上面的跨机房数据访问、数据库连接数瓶颈以及未来数据水平扩展的问题,蚂蚁的工程师们设计了一套单元化的架构,这是单元化的一个示意图。
在没有单元化的时候,用户请求进入内部后,所有请求链路都是随机走的,例如图里的 S0 到 B1 到 C2 到 D0。首先蚂蚁的请求都是跟用户相关的,所以我们将数据按用户的维度进行水平分片,例如这张示意图我们将所有用户分为三组。然后我们将我们的应用也部署成三组独立的逻辑单元,每个逻辑单元的应用和数据都是独立的,相当于每个逻辑单元都处理1/3总量用户的数据。
这个时候我们的三个不同终端的用户,不管是在PC端或者手机端或者扫二维码,当请求进入统一接入层的时候,接入层会按上面逻辑单元的分组规则,将用户请求转发到对应的逻辑单元,例如 user0 的请求转到 S0,后面的应用之间的调用、数据都只在逻辑单元 0 内。统一的 user1 只在逻辑单元 1,user2 也只到逻辑单元 2。
我们把这种逻辑单元称之为 RegionZone。在实际的部署过程中,物理数据中心 IDC 和 逻辑单元的数量没有完全的对等关系。例如图中我们物理机房可以是两地三中心,而 RegionZone 则是分为五个。
两地三中心是国家对金融机构的一个容灾指导方案,要求在同城或相近区域内 ( ≤ 200K M )建立两个数据中心 : 一个为数据中心,负责日常生产运行 ; 另一个为灾难备份中心,负责在灾难发生后的应用系统运行。同时在异地(> 200KM ) 建立异地容灾中心。
有了这套单元化的架构做指导思想,蚂蚁进行大规模的改造,包括应用改造、基础框架改造、数据中心的建设。
机房建设完成后,同时蚂蚁金服将自己的用户分成了若干份,划了几个逻辑单元,分别部署进了不同的物理机房,同时完成大规模的数据迁移。
从两地三中心到容灾能力更强大的三地五中心,我们只需要先进行第三个城市的机房建设,然后将部分 RegionZone 部署到第三个城市,最后再完成数据迁移和引流即可。
每一个 RegionZone 在异地都有备份,当发生城市级的故障时,我们通过统一的管控中心将新的逻辑规则推送到统一接入层以及异地的备 RegionZone 时,就可以做到城市级的整体容灾切换。
再后面基于单元化思想,蚂蚁工程师还建设了弹性 LDC 的能力,例如大型活动开始的时候,我们将动态的将大促相关应用调度到其它的临时机房(例如是云上的机房)去,然后将流量引入。例如图中实例将 10% 的流量引入了 ZoneX 中。等到活动结束,我们再将流量引回。
SOFAStack 开源情况
从前面的服务化演进可以看到,蚂蚁的微服务架构面临的场景已经慢慢从简单的远程调用发展到要面临复杂的三地五中心异地多活场景,为了支持这些场景,蚂蚁中间件自研了一套中间件 SOFAStack。
SOFAStack 中的 SOFA 其实是 Scalable Open Financial Architecture 的首字母缩写,它是用于快速构建金融级分布式架构的一套中间件,也是在金融场景里锤炼出来的最佳实践。
这是我们内部的技术栈,可以看到微服务领域各个功能点我们都有对应的内部系统或者组件。包括有RPC框架、服务发现、动态配置、熔断限流,还有分布式事务,分库分表等一整套中间件。
目前 SOFAStack 也在蚂蚁金融科技上进行了技术输出。我们对中间件产品进行了产品化,并在蚂蚁金融云上变成了云上的产品,并提供了诸多例如同城双活之类的解决方案。这个是商业的产品,大家有空可以看下。
在去年的 4.19 号,SOFAStack 正式宣布开源,我们第一批主要开了SOFABoot 和 SOFARPC 框架,以及 SOFABolt、SOFAArk、SOFAHessian 等周边组件;在 5 月 31 日我们第二批开源了 SOFATracer 和 SOFALookout 的客户端,完善了微服务组件;在 6 月 28 日我们的开源官网正式上线,域名就是 http://sofastack.tech ;在 7 月 16 日我们第三批开源了 ServiceMesh 领域的两个项目 SOFAMesh 和SOFAMosn。截止到今年的双十一,这些项目的总 Star 数已经破万。
这张是我们的 OpenSource Landscape,目前只开源了部分组件,部分组件还在开源准备中,虽然不少内部组件没有开源,但是在每个微服务领域我们都会打通当前已经开源的比较成熟的组件。
例如微服务里的服务发现,我们没有开源内部的 SOFARegistry,但是我们对接了 ZooKeeper/etcd/nacos 等业界成熟的注册中心产品,又例如分布式跟踪,我们虽然开源了自己的 SOFATracer,但是在 SOFARPC 我们也提供 skywalking 作为我们的分布式跟踪的实现。通过保持和业界众多优秀开源产品的兼容性,使得 SOFAStack 有更多可能。
目前 SOFAStack 的源码托管在 Github 和 Gitee 上面,欢迎感兴趣的朋友上去看看,也欢迎给我们 Star。
SOFAStack 下的项目大概有 30 来个,每天的 PV 在 10000 以上,总 Star 数一万多,到 12 月初已经有 80 多位小伙伴给我们贡献过代码或者文章。另外我们也和其它一些国内社区保持了良好的交流与合作,包括 ServiceMesher、Skywalking、AntDesign、Eggjs、K8S 中国社区等。
那如果大家对 SOFAStack 感兴趣,可以通过使用反馈、文档、文章、PR 等方式参与到我们的 SOFAStack 社区活动,或者参加我们的线下 Meetup。
蚂蚁微服务体系之SOFARPC
在微服务体系里,服务框架基本是必不可少的组件,在 SOFAStack 里这个组件叫 SOFARPC。和蚂蚁的整个微服务体系一样,SOFARPC在内部也经历了几代的发展。
可以看到从最早的支持 WebService 到现在的开源版本,SOFARPC 已经走过了十多年的发展,从时间轴可以清楚的看到随着前面整体架构的演进,RPC框架也进行了几代的升级,SOFARPC 目前已经开源在 Github上。
在 2017 年 SOFARPC 进行第五代重构的时候,就列了三大设计原则。
第一个就是核心开发,就是将接口层、 API 层、以及核心实现逻辑通通开放,内部实现保留的是一些兼容内部系统,兼容老的 API,或者是一些历史包袱比较重的代码。
第二个就是统一模型,要将历史遗留的 API 模型,领域模型统一起来,并预留扩展机制。
第三个就是平等扩展,我们模型要保持良好的扩展性,不管是内部实现还是外部实现都面向接口编程,平等对待第三方扩展。
基于这些原则,我们先对 SOFARPC 系统进行了模型分层,在原来的基础上更加细化,左边是服务端的一些模块分层,右边是客户端的模块分层,例如图中的 Filter/Router/Cluster/Loadbalance/Serilization/Protocol/Transport。
为了保证扩展性,我们也设计了两种扩展机制方便大家进行扩展。
一种就是左侧示例代码展示的 ExtensionLoader。我们可以方便的以一种类似 JDK SPI 机制的方式来扩展我们的能力。扩展方式比较简单,可以看到只需要先实现接口并加上注解、加上配置项、最后在使用的时候根据扩展别名来获取扩展实例即可。目前注册中心、Filter、Router、Loadbalance、transport等等都是通过这个扩展方式实现的。
另一种就是右侧示例代码展示的 Eventbus(事件总线)机制,在整个 RPC 调用过程中,不同的阶段都会产生不同的事件,这些事件都会发送到事件总线。如果某个扩展能力在事件总线上监听某个事件,那么就可以同步或者异步的处理这些事件,再进行一些能力扩展。目前 Metrics/Tracer/Fault tolerance 等等是通过这个扩展方式实现的。
注册中心也是扩展能力之一,目前我们能对接的有 Zookeeper,Consul,Nacos等等,社区也在帮我们共建其它例如 etcd eureka 等的注册中心实现。如果我们的注册中心 SOFARegistry 开源了,SOFARPC 也会第一时间进行支持。
基于良好的扩展,目前 SOFARPC 支持的通信协议和序列化组合如图所示。默认的组合是 Bolt+Hessian。Bolt 也是蚂蚁开源的基于 Netty 的高性能通讯框架。Bolt 协议是自研的 TCP 协议。Hessian 则是在开源的Hessian上加了一下功能优化以及反序列化安全特性的一个版本。
除了这类 TCP 长连接 + 二进制序列化的方式,也有传统的 Restful+ json 方式。其它 dubbo/gRPC 业务可以集成到 SOFARPC 中。
这是在bolt 协议下服务端线程模型,我们分为主要有三个线程池:
boss 线程是监听端口上的连接 /read/write 事件的;
worker 线程池处理具体的数据的解包和封包动作,另外在 worker 线程里会做反序列化请求的头部,如果请求对应的接口设置了业务自定义线程池,则分发到这个线程池。否则的话分发到默认的业务线程池。
业务线程池里会将请求的body解析出来,执行业务逻辑,然后把响应序列化为byte数组。
旁边还有一个回调线程池,主要执行一些回调处理、事件处理。
而客户端这边的调用链路就如这张图所示。客户端的调用主要会经过Router、loadbalance、Filter 几部分。这几个都是扩展点,所以可以实现各种各样的能力。当然我们也内置了一些扩展实现,比如负载均衡我们内置了随机、轮询、权重、一致性 hash 等算法。
SOFARPC 的分布式跟踪默认实现接的是 SOFATracer,SOFATracer也是蚂蚁开源的一个分布式跟踪组件。
这个 SOFATracer 就是根据之前提到的 EventBus 扩展实现的。可以看到请求的各个阶段都会有事件产生,例如开始调用,开始发送数据,收到请求,收到响应等等,这些阶段都会产生事件到事件总线。而 SOFATracer 模块里就有一个订阅器,订阅了这些事件,并进行相关记录。
SOFARPC 除了基本的调用、服务发现等之外,其它独特特性我这边简单介绍两个。
其中一个是 SOFARPC 内置一个单机故障摘除的能力。该能力主要针对的是那种在 Consumer 和 Provider 的长连接还在,注册中心未下发摘除,但是服务端由于某些原因(例如长时间 FullGC、硬件故障、IO 繁忙)等场景下,处于亚健康状态的节点。这类节点往往的表现就是调用超时等异常率高等动作。
为此我们设计一套模型和策略,大家可以看下上图。我们基于事件机制(和Tracer类似,不过是异步的)监听统计行为,设置一个统一的入口将调用结果都收集起来;然后按计算策略进行计算,比如每 1 分钟计算一次;计算后对计算结果进行度量,例如某个节点错误率超过平均值 5 倍,我们认为需要降级;对降级的节点我们执行降级策略,例如将权重降低为5%,那么发往这个节点的请求就会变成原来的 1/20(留 5 %是为了留少量请求进行恢复操作)。这个节点在下一次计算和度量的时候,如果错误率都恢复正常了,那么执行恢复策略,例如恢复5倍,也就是慢慢从 5% 恢复到 25% 再到 100%。这样的话,在某些节点故障的情况下,整体客户端可用率将会提高。
另外一个特性就是链路透传。其实 SOFATracer 里内置了一个链路数据,而且可以透传到各个组件。不过 SOFATracer 的数据透传是单向的。SOFARPC 基于隐式传参的能力做了一个双向链路透传的能力,可以用于一些鉴权,A/B Test 等场景。业务使用的时候可以方便的使用 API 进行数据的存取,在整个链路上也可以做到业务无感,也可以提前阻断。
其它更多特性,大家可以去我们的开源官网上查看。最近的版本我们也和 hystrix、skywalking 等做了集成。文档地址是:https://www.sofastack.tech/sofa-rpc/docs/Home
这是下一步的 Roadmap,我们会做一下数据校验类的能力来杜绝一些黑天鹅事件的发生,也会做一下加解密的能力,也会我们 SOFA 体系下的注册中心集成。其它在 6.0.0 版本我们会升级到 JDK8,也会与 gRPC 做集成,支持 etcd 做注册中心,服务注册和配置模型分离等特性,届时欢迎大家关注。
如果大家有想要的能力,也欢迎给我们提 Issue 或者 PR。https://github.com/alipay/sofa-rpc
总结
最后做个总结,今天主要给大家简单介绍了蚂蚁微服务架构的演进,从单模块应用到最终的三地五中心弹性架构。
然后介绍了我们开源的情况,欢迎大家去 Star 或者共享代码。最后介绍了 SOFARPC 的一些设计理念、思想和特性。
其实我们现在看到越来越多的企业都会选择往微服务方向转型,但是微服务体系建设是不能一蹴而就的,企业微服务架构往往会随着业务发展而慢慢演进。目前微服务的发展正在从趋势走向最佳实践,而最佳实践将大大降低微服务引入的复杂度和开销。
今天的直播分享到这里结束了,谢谢大家!
相关链接
视频回放也给你准备好啦:
https://tech.antfin.com/activities/148
提到的地址:
- SOFAStack官网:https://www.sofastack.tech/
- SOFA Github地址:https://github.com/sofastack
- SOFA 码云地址:https://gitee.com/sofastack
- SOFARPC 更多特性请关注:https://www.sofastack.tech/projects/sofa-rpc/overview/
- SOFARPC Github地址:https://github.com/sofastack/sofa-rpc