解读 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)构成,负责协调和控制服务间的所有网络的通信,而控制层负责管理和配置路由转发流量,就是运行时实施的策略。
上图是 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 测试。通过这种方式,模型验证的效率得到了极大的提高。
写在最后