随着云计算的快速发展,软件的开发方式也从传统的单体应用向SOA和流行的微服务转变。软件方式的转变也催生了一些新技术的发展,ServiceMesh就是在这种环境下诞生的新热点技术。当互联网架构面临数据量几何级增长、高并发、高可用场景时,ServiceMesh能在其中扮演什么角色?什么样的场景适合使用ServiceMesh?如果有使用的需求,ServiceMesh将如何实现?……针对上述问题,InfoQ记者在2019ArchSummit全球架构师峰会(深圳站)采访了同程艺龙研发中心架构师雷飞伟。什么是ServiceMesh?什么是服务网格?目前业界公认的是LinkerdCEOWilliamMorgan对ServiceMesh的定义,即ServiceMesh是处理服务间通信的基础设施层。云原生应用具有复杂的服务拓扑,而ServiceMesh确保请求可以可靠地穿梭于这些拓扑中。在实际应用中,ServiceMesh通常由一系列轻量级的网络代理组成,它们与应用部署在一起,但应用不需要知道它们的存在。ServiceMesh定义中的关键字那么多,那么最关键的是什么?在雷飞伟看来,ServiceMesh最关键的部分是设计时定义的服务模型。ServiceMesh模型设计不仅有服务的概念,还有环境的概念,而这些概念的引入,将使ServiceMesh体系不再是一个普通的提供服务发现、负载均衡等功能的服务治理框架。我们可以依靠这个在服务环境之间实现强大的路由功能,使得七层服务间调用也可以像三层IP包一样进行路由。如果说之前经典的服务发现+RPC服务治理框架是ServiceGovernance1.0,那么ServiceMesh技术可以称为ServiceGovernance2.0,这是基于业界以往服务治理实践的新思路。ServiceMesh到底解决了什么问题?雷飞伟认为,ServiceMesh主要解决服务间调用的解耦问题。在没有ServiceMesh之前,服务间的调用要么硬编码IP地址,要么硬编码域名,但是这些方案都太死板了。虽然硬编码域名比硬编码IP地址灵活一点,但是由于各种历史包袱,很多DNS解析库对域名的处理并不规范。通常,域名的TTL被忽略,导致无法快速更改域名的IP地址列表。第一代服务发现+RPC的服务治理框架虽然解决了最基本的IP地址调用问题,但是要么根本没有考虑多环境间的请求路由,要么非常不灵活,导致很多业务实现了A/Btestorswimlanerelease,要写很多特殊的代码。ServiceMesh在请求路由层面进一步解耦了服务之间的调用,使得之前需要各业务自己写代码的问题有了一套通用的、业务独立的解决方案。ServiceMesh的实现目前业界比较流行的ServiceMesh开源软件有Linkerd、Envoy、Istio、Conduit、nginMesh、Kong。其中Istio是ServiceMesh比较经典的实现。由谷歌、IBM和Lyft联合开发,于2017年5月24日首次发布。Istio在逻辑上可以分为数据层和控制层。数据层由一组智能代理(Envoy)组成,负责协调和控制服务之间的所有网络通信,而控制层负责管理和配置路由和转发流量。它是在运行时实施的策略。上图是Istio的架构图。从图中我们可以看出Istio的核心组件主要包括Proxy代理、Mixer混音器、Pilot向导、Citadel堡垒和Galley。其中Proxy代理的代理组件主要是Envoy,用于拦截所有想要拦截的流量;Mixer混合器为后端数据采集或遥测系统混合各种策略和适配器,实现前端Proxy和后端系统的隔离和集成。合流;PilotGuide提供了一系列规则api,允许运维人员指定一系列高级流量管理规则;Citadel堡垒管理集群的密钥和证书,是集群的安全部门;Galley主要用于验证用户编写的Istioapi配置。Istio作为一个经典的ServiceMesh实现,在架构设计和服务模型设计上没有问题,但也不是完全完美。雷飞伟说:“因为Istio出现的时间不长,还有很多场景没有涉及到,比如跨地域的ServiceMesh,Istio的实现暂时没有那么漂亮;还有多环境路由方案可能会入侵业务,Istio暂时没有统一的解决方案。”ServiceMesh的实用价值ServiceMesh是一项新兴技术,它适合哪些企业使用?对企业有什么价值?落地过程中会存在哪些问题?雷飞伟认为ServiceMesh适合所有IT企业。只要他们的业务规模大到可以拆分成多个服务,就需要进行服务治理,就应该使用ServiceMesh技术。ServiceMesh的价值主要体现在三个方面,一是增强了故障的快速恢复能力业务服务的能力,比如当一个业务实例出现故障时,可以通过自动健康检查排除,或者整个机房出现故障,只需要一句话更新语句即可;二是增强快速迭代业务服务能力,业务可以通过ServiceMesh轻松实现小流功能,业务验证速度非常快;三是为节省大量的硬件和人力成本,基于ServiceMesh的泳道发布方案最大限度地减少了硬件资源的消耗,同时也最大限度地减少了人力配置和沟通的成本。当然,凡事既有机遇也有挑战,所以ServiceMesh在企业落地的时候也会遇到很多挑战。“ServiceMesh落地最大的挑战是现有业务,”雷飞伟认为:“由于历史原因,现有业务往往使用一些比较老的服务间调用方案,比如硬编码IP地址或者域名。在这种情况下,除了转型业务,别无他法。”如果企业的存量业务使用服务发现+RPC等第一代服务治理方案,那么可以利用ServiceMesh的服务发现+Sidecar来兼容之前的RPC协议,这样我们就可以将存量业务升级为修改成本最小的ServiceMesh,业务只需要重新编译,如果服务暂时不用ServiceMesh的流量路由功能,甚至可以无缝编译接入。同程艺龙的ServiceMesh实践同程艺龙的ServiceMesh实践可以追溯到2016年底,当时同程艺龙的技术团队开发了一个服务发现系统,然后在这个系统的基础上不断扩展,形成了一个完整的、自有的开发了ServiceMesh系统。雷飞伟表示:“ServiceMesh是所有业务系统的底层支撑技术,如果ServiceMesh垮了,整个公司的业务都会受到影响,小到无法更改配置,大到用户流量全部丢失。因此,在技??术选型的时候,我们并没有直接使用Istio,而是选择了自研的ServiceMesh体系,并且提前做好了应对各种故障场景的预案,设计了层层保障。”ServiceMesh系统不仅可以处理传统的服务Discovery、负载均衡等应用,更重要的是它具有7层路由功能,基于此功能,同程艺龙开发了可支持上百个的泳道发布系统泳道的同时发布,最大限度地降低人力成本,以推荐功能为例,由于同程艺龙的酒店业务本质上是一个垂直搜索引擎,因此在搜索结果中的推荐位置非常重要。酒店向用户推荐的好坏直接关系到用户体验,所以要做大量的A/B测试来验证模型的效果。雷飞伟将同程艺龙酒店的商家推荐功能的ServiceMesh应用分为三部分:第一部分是ServiceMesh刚刚上线,业务同学不认可,怎么办?这个时候需要考虑谁是pe最需要ServiceMesh的人。当然是运维同学。他们需要维护nginx、lvs、RPC等各种负载均衡系统,而ServiceMesh只是有一个服务发现的功能。因此,我们首先解决了运维同学统一维护负载均衡系统上游链表的需求,将所有服务导入ServiceMesh,然后ServiceMesh连接到nginx/lvs/RPC等各个系统。这样运维同学就不用再配置nginx、lvs、RPC等多个系统,只需要在ServiceMesh系统上统一维护各个服务的IP列表即可。第二部分:接下来我们做的是直接将业务系统连接到ServiceMesh的Sidecar上,这样可以省去连接nginx的开销。这部分会稍微难一点,因为Sidecar要过流量,大家的疑惑会比较多。针对这一点,我们的计划是按照灰度发布的路径,稳扎稳打地进行下去。第三部分是业务连接JavaAgent,也就是我们设想中的ServiceMesh的完整体。只有这样,才能实现ServiceMesh最灵活的动态流量调度功能。我们的方案是配合发布系统来做,直接将JavaAgent构建到JVM中。这样,随着业务不断迭代发布,JavaAgent上线。JavaAgent上线后,可以充分发挥ServiceMesh的作用,大大方便A/B测试。业务可以在整个调用链中的任意一点创建多个灰度环境,并将多个环境串联起来。运行多个A/B测试。这样,大大提高了模型验证的效率。写在最后虽然ServiceMesh现在很火,但是它在企业中的实践还处于初级阶段,很多企业对其实用价值存有疑虑。作为ServiceMesh实践的先行者,雷飞伟说:“前面的风景真的很好,我们还要继续往前走!”谈到ServiceMesh未来的发展方向,雷飞伟表示:“无论怎么演进,ServiceMesh的基本架构都逃不开控制平面和数据平面这两部分。控制平面本质上是一个存储系统,所以它的演进基本上是一致性和可用性的平衡;而数据平面主要是高效率和低侵入性,例如Sidecar虽然是数据平面的典型解决方案,但并不是唯一的解决方案。RPC框架也可以用于数据平面,它会更有效率,但相对更具侵入性。”
