解读 Service Mesh 的实现方式与同程艺龙的具体实践

tommyhp 2019-07-21

解读 Service Mesh 的实现方式与同程艺龙的具体实践

随着云计算的快速发展,软件开发的方式也从传统的单体应用过渡到了 SOA 及时下流行的微服务。软件方式的转变也催生了一些新的技术发展,Service Mesh 就是在此环境下诞生的新的热点技术。

当互联网架构面临数据量,高并发、高可用场景几何增长的情况,Service Mesh 可以在其中发挥什么样的作用?什么样的场景适合使用 Service Mesh?如果有需要使用,又将如何来实现 Service Mesh 呢?…针对上述问题,InfoQ 记者在 ArchSummit 全球架构师峰会(深圳站)2019 的现场采访了同程艺龙研发中心架构师雷飞尉。

什么是 Service Mesh?  

什么是 Service Mesh 呢?目前业内公认的是 Linkerd CEO Willian Morgan 对 Service Mesh 的定义,即 Service Mesh 是一个基础设施层,用于处理服务间通信。云原生应用有着复杂的服务拓扑,Service Mesh 保证请求可以在这些拓扑中可靠地穿梭。在实际应用当中,Service Mesh 通常是由一系列轻量级的网络代理组成的,它们与应用程序部署在一起,但应用程序不需要知道它们的存在。

Service Mesh 定义中有这么多关键词,那么到底什么才是最关键的呢?在雷飞尉看来,Service Mesh 最关键的部分在于设计时所定义的服务模型。Service Mesh 模型设计不仅有服务的概念,还会有环境的概念,而这些概念的提出会使得 Service Mesh 系统不再是一个普通的提供服务发现、负载均衡等功能的服务治理框架, 我们可以依此实现强大的服务环境间路由功能, 让 7 层的服务间调用也能像 3 层的 IP 报文一样路由起来。

如果我们把之前经典的服务发现 +RPC 的服务治理框架看作是服务治理 1.0 的话,那么 Service Mesh 技术就可以称为服务治理 2.0,它是业界基于之前的服务治理实践总结出来的全新思路。

Service Mesh 实际上是在解决什么问题呢?雷飞尉认为 Service Mesh 主要解决的就是服务间调用解耦的问题。

在没有 Service Mesh 之前,服务间调用要么写死 IP 地址,要么写死域名,但是这些方案太死板了,写死域名虽然比写死 IP 地址稍微灵活一点点,但由于各种历史包袱,很多 DNS 解析库对域名的处理并不规范,典型的就是忽略域名的 TTL 导致不能快速变更域名的 IP 地址列表。

第一代服务发现 +RPC 的服务治理框架虽然解决了最基本的 IP 地址调用的问题,但是对于多环境间的请求路由要么完全没有考虑,要么非常不灵活,这就造成很多业务为了实现 A/B 测试或泳道发布,不得不多写很多专门的代码。而 Service Mesh 在请求路由的层面进一步解耦了服务间调用,使得以前需要每个业务专门写代码处理的问题,有了一套通用而且业务无关的解决方案。

Service Mesh 的实现方式  

目前业内比较流行的 Service Mesh 开源软件有 Linkerd、Envoy、Istio、Conduit、nginMesh 和 Kong。

其中 Istio 是 Service Mesh 比较经典的实现方式,它是由 Google、IBM 和 Lyft 联合开发,于 2017 年 5 月 24 日首次发布。Istio 在逻辑上可以分为数据层和控制层,数据层是由一组智能的代理(Envoy)构成,负责协调和控制服务间的所有网络的通信,而控制层负责管理和配置路由转发流量,就是运行时实施的策略。

解读 Service Mesh 的实现方式与同程艺龙的具体实践

上图是 Istio 的架构图,从图中我们可以看到 Istio 的核心组件主要包括 Proxy 代理、Mixer 混合器、Pilot 引导、Citadel 堡垒和 Galley。其中,Proxy 代理的代理组件主要是 Envoy,用来拦截所有想拦截的流量;Mixer 混合器混合了各种策略以及后端数据采集或遥测系统的适配器,实现了前端 Proxy 与后端系统的隔离与汇合;Pilot 引导提供了一系列 rules api,允许运维人员指定一系列高级的流量管理规则;Citadel 堡垒管理着集群的密钥和证书,是集群的安全部门;Galley 主要是用来验证用户编写的 Istio api 配置。

作为经典的 Service Mesh 实现方式,Istio 在架构设计和服务模型设计方面都没有问题,但也不是完全完美。雷飞尉表示:“Istio 因为出现时间较短,所以有很多场景没有覆盖到,例如跨地域的 Service Mesh,Istio 的实现方案暂时不是那么漂亮;而多环境路由方案由于可能要侵入业务, Istio 暂时也没有提出统一的解决方案。”

Service Mesh 的实践价值  

Service Mesh 作为一种新兴的技术,哪些企业适合使用呢?对于企业来说有哪些价值?落地过程中又会存在哪些问题呢?

雷飞尉认为 Service Mesh 适合所有的 IT 公司使用,只要其业务规模已经大到需要拆分为不止一个服务,那么就需要服务治理,就应该使用 Service Mesh 技术。

Service Mesh 的价值主要体现在三个方面,一是增强了业务服务的快速故障恢复能力,例如当某个业务实例出现故障可以自动健康检查剔除掉,又或者整机房出现故障,只需要一句 select 语句更新一下即可;二是增强了业务服务的快速迭代能力,业务可以通过 Service Mesh 轻松实现小流量功能,这样业务验证的速度就非常快;三是节省了大量硬件和人力成本,基于 Service Mesh 的泳道发布方案把硬件资源的耗费降到了最低,同时也把人力配置和沟通的成本降到了最低。

当然,任何事情都是机遇与挑战并存,所以 Service Mesh 在企业落地时也会存在很多挑战。“Service Mesh 在落地时最大的挑战在于存量业务”,雷飞尉认为:“存量业务由于历史原因往往会使用一些比较老的服务间调用方案,如写死 IP 地址或者域名,在这种情况除了改造业务别无他法。”

如果企业存量业务使用了服务发现 +RPC 这样的第一代服务治理方案,那么可以使用 Service Mesh 的服务发现 + Sidecar 去兼容以前的 RPC 协议。通过这种方式,我们可以以最小的修改代价将该存量业务升级到 Service Mesh,业务只需要进行重新编译,如果该业务暂时用不到 Service Mesh 的流量路由功能, 甚至都可以不用编译,无缝接入。

同程艺龙的 Service Mesh 实践  

同程艺龙的 Service Mesh 实践可以追溯到 2016 年底,当时同程艺龙技术团队研发了一个服务发现系统,之后基于此系统不断外延,形成了一个完善的、自研的 Service Mesh 系统。雷飞尉表示:“Service Mesh 是所有业务系统的底层支持技术,如果 Service Mesh 垮了,那么全公司的业务都会受影响,轻则不能变更配置,重则损失全部用户流量。所以,在技术选型时,我们没有直接使用 Istio,而是选择了自研 Service Mesh 系统,并且在应用时提前准备了处理各种故障场景的预案,设计层层保底方案。”

Service Mesh 系统不仅可以处理传统的服务发现、负载均衡等应用,更为关键的是其拥有 7 层路由功能,基于此功能,同程艺龙开发了可同时支持几百个泳道发布的泳道发布系统,并将人力成本降到了最低。

以推荐功能为例,由于同程艺龙的酒店业务本质上是一个垂直搜索引擎,搜索结果中的推荐位就很关键,向用户推荐什么样的酒店直接关系到用户体验,所以必须要做大量的 A/B 测试来验证模型的效果。

雷飞尉把同程艺龙酒店业务推荐功能的 Service Mesh 应用分成了三部分:

第一部分  

Service Mesh 刚刚上线,业务同学不认可,怎么办?这时就要考虑谁是最需要 Service Mesh 的人,当然是运维同学,他们需要维护 nginx、lvs、RPC 等各种负载均衡系统,而 Service Mesh 中刚好有服务发现功能。所以,我们首先解决了运维同学统一维护负载均衡系统的 upstream 列表的需求,把所有服务导入到 Service Mesh 上,再由 Service Mesh 去对接 nginx/lvs/RPC 等各个系统。通过这样的方式,运维同学不再需要配置 nginx、lvs、RPC 等多个系统,只需在 Service Mesh 系统上统一维护每个服务的 IP 列表。

第二部分:  

接下来,我们做的是业务系统直接对接 Service Mesh 的 Sidecar,这种方式可以省掉对接 nginx 的开销。这一部分会比较难一点,因为 Sidecar 要过流量,大家的疑虑就会大一些。针对此,我们的方案是稳扎稳打,按灰度发布的路子稳步推进。

第三部分  

业务对接 Java Agent,这是我们设想中的 Service Mesh 完全体,只有这样才能实现最灵活的 Service Mesh 的动态流量调度功能。我们的方案是配合发布系统来做这件事, 直接把 Java Agent 内置于 JVM 中。这样,随着业务不断迭代发布,就把 Java Agent 带到了线上。Java Agent 上线以后,Service Mesh 的作用就能得到充分发挥,极大的方便了 A/B 测试,业务可以在整个调用链的任意一点创建多个灰度环境,并把多个环境串联起来,同时进行多个 A/B 测试。通过这种方式,模型验证的效率得到了极大的提高。

写在最后  

相关推荐