Service Mesh 的观点自 2017 年初提出之后,受到了业界的广泛关注,作为微做事的下一代发展架构在社区迅速发酵,并且孵化出了诸如 Istio 等广受业界关注的面向于云原生 (Cloud Native) 的微做事架构。
目前阿里、华为云、腾讯云都在 Service Mesh 上投入了大量精力进行研发和推广。
阐述和谈论 Service Mesh 架构的文章目前网络上已经非常丰富,在此不再赘述。
本文紧张阐述 Service Mesh 架构在有赞是如何一步步发展和落地的,期望能够给读者带来一定的思考和借鉴意义,并对 Service Mesh 架构能够办理的问题和运用处景有进一步的理解。
同时,有赞 Service Mesh 架组成长的过程也正是有赞微做事架构的演进过程,期待能够给正在进行微做事改造的团队带来一定的启示和思考。

一、缘起

有赞初期,利用的是 Nginx+PHP-FPM,所有的业务逻辑代码都在一个叫做 Iron 的 PHP 代码仓库里,是一个范例的单体运用 (Monolith),整体架构可以大略的表示成下图:

该架构在有赞初期,团队规模比较小,且业务逻辑相比拟较大略的时候,很好的支撑和承载了有赞的核心业务。
但是,随着有赞业务和团队规模的极速发展,单体运用的毛病愈来愈凸显:

微服务zanphpService Mesh在有赞的实践与成长 jQuery

耦合性高隔离性差团队协作性差

一次发布带来的故障每每须要几个业务团队的人坐在一起,花费数十分钟乃至几个小时才能定位究竟是哪处改动引发的。
对单体运用进行微做事改造,势在必行。

综合当时团队和业务发展的实际情形,一方面,有赞选择了海内非常盛行且具备良好生态的 dubbo 作为 Java 措辞 RPC 框架;另一方面,考虑到团队中有相称数量 PHP 开拓的同学,有赞内部孵化出了 ZanPHP——利用 PHP 措辞的纯异步 RPC 框架,并选择了 ETCD 作为做事注册和创造中央,开始搭建有赞做事化的整体架构。
为理解决跨措辞(Java 与 PHP 措辞之间)的 RPC 通信问题,有赞在 facebook 开源的 thrift 协议根本上进行了二次封装,开拓了 NOVA 协议用以支持跨措辞 RPC 调用。

综上所述,这一期间,整体的架构选型如下:

只管将单体运用拆分成微做事能够带来一系列众所周知的收益,但任何业务迁移的过程都是痛楚的,同时,在迁移过程中必定会有相称长的一段韶光新旧业务架构代码须要同时在线上运行。
因而,现有承载了大量核心业务的单体 PHP-FPM 代码如何调用新拆分出来的 Java 或者 ZanPHP 的微做事,就成了首当其冲的问题。

由于 PHP-FPM 运行模式的分外性:单个 HTTP 要求处理完成之后会开释所有的资源和内存,导致其很难实现最基本的微做事架构的需求。
如,微做事架构须要调用端(consumer)永劫光缓存做事创造结果,并能感知做事创造结果的变革。
纵然利用共享内存的办法实现,整体的实现本钱也非常高,稳定性也难以得到很好的担保。
在这样的背景下,有赞 PaaS 团队在 16 年初利用 golang 开拓并上线了做事化代理组件 Tether 0.1 版本。
设计的紧张功能为:

实现对有赞内部跨措辞 RPC 协议 NOVA 的解析对接有赞内部 ETCD 做事创造中央,解析并缓存做事创造数据通过本地端口接管 NOVA RPC 要求,并根据解析的 NOVA 要求信息和做事创造结果,将要求通过长链接转发至后端做事

进行总结便是:Tether 0.1 版本是实现了代理、转发 NOVA RPC 要求至相应的做事供应方确当地 Agent,大略的架构图如下:

从架构图上可以看出:

对付 PHP-FPM(现存的单体运用),只须要实现 NOVA 协议的编解码即可做事化整体架构的繁芜度,包括:做事创造、负载均衡、后端做事的优雅下线等等,全部都下沉到 Tether 层处理。
Tether 与有赞监控、日志平台对接,实现了对微做事间调用的监控和报警。

从功能和架构上可以很清晰地看出,Tether 便是 Service Mesh 架构中的 Sidecar,只不过在有赞初期的实践中,只有做事的调用方(consumer 端)通过 Sidecar 发起 RPC 要求。

虽然在此阶段引入 Tether 作为 Sidecar 的出发点是为理解决 PHP-FPM 调用后端做事的问题,但是,Service Mesh 架构带来的上风很快就表示了出来:全体微做事架构的繁芜度都对运用隐蔽了,架构的功能迭代和升级对业务运用完备透明,只需由运维升级 Sidecar,业务运用便具备了新的微做事功能特性。

以此为根本,有赞开始逐步将单体的 PHP-FPM 运用拆分成逻辑和业务上相对独立的微做事,逐步缩小 PHP-FPM 运用上所承载的业务逻辑,开启了有赞微做事架构的演进之路。

二、发展

韶光来到2017年年中,随着技能团队和业务的进一步发展,有赞的核心业务中台基本上都选择了 Java 与 Dubbo 的组合,为跨措辞调用设计的 NOVA 协议以及 ZanPHP 框架逐渐衰落。
在这样的趋势和技能发展背景之下,有赞技能架构确定了新的发展方向:

后端业务中台全部迁移至 JavaPHP-FPM 中与页面拼装和渲染干系的逻辑全部迁移至 Node.js

随着 Node.js 的引入,同样的问题再次涌现:Node.js 作为业务编排和模版渲染层,如何调用支配在繁芜做事化架构中的Java中台运用?

首先,是 RPC 协议和编码的选择问题。
对付跨措辞调用业界一样平常选择利用IDL来描述接口定义,并来通过工具自动天生的桩代码序列化、反序列化数据和编码、解析 RPC 要求包,grpc 和 thrift 都是通过这种办法实现的多措辞支持。
这是笔者比较推崇的办法,IDL常日仅保留各个编程措辞公共的特性,而避免引入与特定措辞干系的特性,进而对跨措辞调用有着非常好的支持。
同时 IDL 本身便是良好的接口描述文档,能够在相称程度上减少沟通、协作本钱,也便于开拓者养成先设计接口再进行开拓的习气。

虽然有赞初期就设计了 NOVA 协议,通过编写 IDL 天生桩代码的办法实现跨措辞RPC,但是利用 dubbo 框架的 Java 开拓同学已经习气了直接编写接口就能实现Java做事之间相互调用的开拓模式,导致在推广 NOVA 协议的时候碰着了不少的阻力——存在更便捷的调用办法时,为何还要学习具有一定上手门槛的 IDL?摆在面前的困境:利用 Java 的后端开拓同学已经不宁愿、乃至抵触编写 IDL,向 Node.js 的开拓同学推广IDL也可能碰着同样的问题。

紧接着是 Node.js 框架与有赞做事化架构的整合问题。
我们调研了业界已有的开源方案 dubbo2.js。
虽然 Node.js 具有实现要求编解码、做事创造、长链接保持、要求负载均衡的能力;但是,业务前台是否有必要引入如此的繁芜度?做事化调用的监控、路由策略、限流、熔断等特性,Node.js 是否须要全部都实现一遍?若有赞后续业务须要利用新的编程措辞:C#、Python 等,那是否这些编程措辞又要再实现一遍这些特性?

dubbo2.js 对我们面临的第一个问题供应了一定的思路:通过显示的指定调用的后端Java接口的参数类型,dubbo2.js 实现了 dubbo 协议的编解码,达到了不通过 IDL 实现跨措辞调用的目的。
但是,让 Node.js 的开拓同学去感知后真个 Java 类型系统真的合理吗?

基于以上的思考,我们想到了早已接入有赞微做事框架的 Sidecar 产品:Tether。
同时,在传统的 Sidecar 上进行了创新:为了贴近 Node.js 同学的开拓模式和习气,并最大程度的隐蔽后端做事化架构的繁芜度,我们设计了大略的 HTTP+Json 的接口用以 Node.js 与 Tether 之间的调用,由 Tether 实现 HTTP 协议与微做事调用的 dubbo 协议之间的相互转换。
整体架构如下:

值得把稳的是,图中的泛化调用并不是开源版本 dubbo 的“泛化调用”,而是有赞内部仿照开源版本的“泛化调用”针对性实现的参数利用 json 编码(有赞内利用 dubbo 默认的 hessian2 序列化办法编码参数)的“跨措辞泛化调用”,该接口调用返回的也是 hessian 编码的 json 串。

至此,一劳永逸地办理了多措辞接入有赞做事化架构的问题,由于 HTTP+Json 协议的通用性,任何其他措辞都可以很方便地通过 Tether 调用核心 Java 做事的 dubbo 接口,而不用关心做事创造、监控等繁芜问题。

目前,该架构在有赞生产环境中已经运行了一年半多,通过 Tether 的要求占到有赞微做事总流量的 20%+,是有赞微做事整体架构的主要组成部分。

三、More…

在 Service Mesh 架构落地过程中,我们欣喜的创造,除了最初的设计意图之外,Tether 作为 Sidecar 还能够实现其他非常有代价的功能,进而在一些项目中发挥至关主要的浸染。

在实际项目中,我们碰着了这样一种场景:运用须要调用支配在另一个机房中的做事。
由于调用发起方和做事供应方分属不同的微做事集群,做事创造无法创造支配在另一个机房中的做事供应方;同时,在跨机房调用的场景下,数据的安全性也必须得到高度的重视,跨机房调用必须经由严格的加密和鉴权。

有赞 PaaS 团队通过“做事伪装(Service Pretender,以下简称 SP)”运用和 Tether 相结合,很奥妙的知足了跨机房做事创造和数据加密、鉴权的需求。
整体的架构图如下:

值得把稳的是,为了便于理解,图中只画出了 A 机房 Service0 调用 B 机房 Service1 的调用图示。
实际上 A、B 机房是完备对称的,B 机房调用 A 机房的运用是完备一样的。
对称的设计极大地简化了系统架构,降落了运维难度。

SP 与做事注册中央、Tether 以及对端机房对称支配的 SP 进行交互,紧张完成以下两个功能:

供应 HTTPS 做事,对真个 SP 运用可以通过相应的接口,获取到本机房做事注册中央 ETCD 上的运用元数据(图示中,机房 A 的 SP 通过 HTTPS 协议从 B 机房的SP获取到注册在 B 机房 ETCD 上的 Service1 的元数据信息)与指定的 Tether 保持心跳检讨,若 Tether 心跳正常,则将对应的 Tether 利用 1 中获取的做事元数据信息,注册到本机房的做事注册中央。
即将 Tether 伪装成对端机房的相应运用(图示中,机房 A 的 SP 将同机房的 Tether 伪装成了 B 机房的 Service1 运用)

如此,当机房 A 中的 Service0 想要调用机房B中的 Service1 时,根据做事创造的结果,Service0 会要求本机房的出口网关 TetherA,TetherA 收到要求后会直接转发至B机房的入口网关 TetherB,再由 TetherB 根据本机房内实际做事创造的结果,将调用要求路由至实际须要要求的 Service1。
同时在网关型的 TetherA 与 TetherB 之间,利用了 TLS 双向验证、加密来知够数据加密和鉴权的需求。

在架构和功能上,SP 与 Tether 完备解耦,可以各自独立迭代和升级。
由于利用了 dubbo 框架做事创造的特性,网关 Tether 可以方便地进行水平扩容;当须要进行版本升级之时,也可以通过调度做事创造的权重,方便的进行小流量灰度。
加上 Tether 早已对接有赞监控系统,所有跨机房的做事化调用都得到了很好的监控,具备很强的可不雅观测性。
所有这统统,保障了整体架构的稳定和可靠。

通过如上的设计,在无需任何业务和框架改造的条件下,有赞根本保障部门实现了运用的跨机房拆分和做事化调用。
全体过程,基本上做到了无需业务方参与和改造。

四、当下

正如上文所述,在有赞主站,Tether目前紧张是作为跨措辞调用场景下 Consumer 真个 Sidecar,以及跨机房调用时做事化流量的出入口网关。
虽然在跨机房调用场景下,Tether 实际上同时托管了 Consumer 端和 Provider 真个流量,但离真正 Sidecar 托管全部 RPC 要求的 Service Mesh 架构还存在一定的间隔。
纵然 Tether 的可靠性已经在生产环境得到了永劫光的验证,在已然非常成熟的 dubbo 生态中推广利用,还存在非常多的困难和阻力。

有赞云,是有赞面向有技能研发能力的商家和开拓者供应的实现自定义拓展和需求的“云平台”。
作为“云平台”,有赞云须要为开拓者供应一整套、包含完全功能的“微做事架构”,以便开拓者快速搭建自己的运用、做事集群。
按照有赞内部的履历,推动业务开拓者升级运用框架是一个极其漫长而痛楚的过程;面对利用“有赞云”的外部开拓者,可想而知,这个过程将会变得更加不可控。
Service Mesh 架构完美地办理了这个问题,通过将繁芜的架构功能下沉到 Sidecar,运用框架将变得非常大略和轻薄。
微做事层的功能迭代和升级,仅需静默升级 Sidecar 即可,无需任何业务开拓者的参与和协同,极大地提升了整体架构的灵巧性和功能迭代可控性。

与此同时,利用“有赞云”的开拓者们一定不会都利用 Java 这一种开拓措辞,利用 Service Mesh 架构避免了为每种支持的措辞都开拓微做事架构和进行后续功能迭代,在极大的减少开拓事情量的同时担保了各个措辞的微做事能力同步迭代。
在上文中已经提及,目前有赞主站利用的 dubbo RPC(默认利用 hessian 序列化)协议与 Java 措辞特性耦合严重,不适宜于跨措辞调用的场景。
基于此,在“有赞云”场景中,我们设计了基于 HTTP1.1 和 HTTP/2 协议的可拓展的 RPC 协议,用于跨措辞调用的场景。
个中 HTTP/2 协议由于其标准化、异步性、高性能、语义清晰等特性,期待其成为未来跨措辞调用的主流。

其余值得一提的是,“有赞云”已经全面拥抱开源社区,利用 Kubernetes 进行做事编排和运用管理,极大的提升了多用户场景下的运维效率,也为未来支持更多的开源特性和拓展打下了坚实的根本。
在此根本上,有赞 PaaS 团队将 Istio 的做事创造组件Pilot也引入到了“有赞云”的 Service Mesh 架构中,Pilot 直接对接Kubernetes 为 Tether Sidecar 供应做事创造能力。
通过Kubernetes本身的做事编排能力,业务运用不再须要进行做事注册和做事保活;“有赞云”业务微做事集群也不再须要搭建独立的做事创造集群(ETCD, Consul 等)。
在简化整体架构、降落本钱的同时,向开源社区更靠近了一步。

目前,基于 Kubernetes、Istio Pilot、Tether Sidecar 的 Server Mesh 架构已经在“有赞云”中全面落地,新特性和功能也在不断迭代中。
期待为开拓者供应更友好的开拓、托管环境和更强大的功能支持。

五、展望

有赞主站的运用目前正在逐步向容器化和 Kubernetes 迁移,并且将在 19 年年内实现绝大多数运用的容器化。
随着业务规模的不断增长,有赞微做事集群规模也随之水涨船高,有赞在做事化初期选择的 ETCD V2 做事创造在 18 年双十一期间已经碰着了瓶颈:运用发布时,全集群广播做事创造信息造成 ETCD 集群抖动。
为了支持更大规模的微做事集群规模,同时对 dubbo 框架和 Tether Sidecar 屏蔽实际做事创造数据的存储格式和存储系统,目前有赞内部也在将做事创造从 ETCD 迁移至 Istio Pilot 组件,利用 Pilot 供应的 ADS(Aggregated Discovery Service, 聚合创造做事)接口获取做事创造数据。

在开源 Pilot 的根本上,为了知足有赞内部的需求。
我们对 Pilot 进行了一系列的优化和改造,包括做事创造适配有赞 ETCD 的数据构造、对一定韶光窗口内的做事集群变更事宜进行聚合等。
有赞内部还通过 Pilot 和 Istio 的路由规则,实现了 dubbo 要求的流量掌握,通过详细的 RPC 流量掌握,在上层包装出了“灰度发布”、“蓝绿发布”等产品。
无论是 Pilot 的优化和改造,还是对 Istio 路由规则的利用,近期都会有专门的文章进行详细的先容,这里不再展开。

未来,我们期望,在有赞主站运用完备容器化+ Kubernetes 之后,主站的整体做事化架构会向“有赞云”发展:Pilot 直接通过 Kubernetes 的做事编排能力获取做事创造数据,dubbo 框架不再须要进行做事注册和做事保活。

同时,有赞内部,部分网关型的 Java 运用须要调用大量不同的后端做事接口,为免去不断的布局调用句柄之苦,已经开始接入 Tether Sidecar,并在生产环境进行利用;大量的其他 Java 运用也已经在 QA 环境接入和利用 Tether Sidecar。
期待在不久的将来,通过 Service Mesh 加上容器化两把利刃,能够让架构升级和迭代的过程更加可控,免去业务开拓者升级架构之苦的同时尽快享受到新的功能。