干货 | 携程 SOA 的 Service Mesh 架构落地

作者简介

 

本文作者 Dozer、Bender、vio-lin 来自携程 SOA 团队。目前主要负责 SOA 系统的研发工作和 Service Mesh 架构的演进、落地工作,同时也关注服务治理、JVM、云原生等技术领域。

一、背景

携程的 SOA 系统经历了 ESB、微服务等架构的演变,正处于一个较平稳的阶段。但当前的微服务架构却遇到了各种业内经常遇到的问题,例如:

1)无法支撑多语言战略,团队没有精力维护除了 Java 以外其他语言的 SDK;

2)客户端 SDK 版本升级推进困难,特别是遇到 Bug 的时候,彻底下线一个版本可能会花上几个月的时间,给业务带来了隐患;

在 Service Mesh 架构出现时,我们就注意到了它。一边探索一边实践,尝试着用 Service Mesh 来解决我们的痛点。

二、技术方案

携程主营业务在国内,并且在国际上也有着不小的业务量。基于这个特点,国内使用自建机房、国外使用公有云的模式是非常合适的。

正因为技术栈需要支持跨机房部署,所以将云原生架构作为演进的目标。

Istio 作为云原生架构中重要的一位成员,和云原生架构中的其他成员相辅相成。

除此以外,携程当前 SOA 以 HTTP 协议为主,Istio 对 HTTP、HTTPS、gRPC 这几个传输协议有着全面的支持。

自然地,基于 Istio 做二次开发成为了我们内部推行 Service Mesh 的技术实现方案。

虽然开源项目开箱即用,但在调研和方案设计的过程中,我们也遇到了很多问题,例如:

  1. 1)如何实现不改造业务代码即可接入 Service Mesh,做到无感知迁移

  2. 2)Istio 无法覆盖所有携程需要的功能

  3. 3)Istio 没有配置按需下发方案

  4. 4)Istio 性能无法支撑携程规模

  5. 5)Istio 对高可用方面的支持不够

接下来,本文会着重介绍 1-3 的解决思路,4-5 可以参考我们另外两篇文章:

三、控制平面

控制平面想要实现无感知迁移,那么最重要的就是要实现两套系统的互通,其中主要包括:统一配置管理、服务注册与发现、功能对齐和 SDK 兼容。

3.1 统一配置管理

我们现有的 SOA 系统已经有了一套包括管理后台、实时推送等功能模块的系统,并不需要再造一套。

但从云原生架构的角度看,这样的设计就不够云原生。云原生的架构下更推崇声明式 API 和 GitOps 工作流。我们现有的系统显得有点落伍,对将来上公有云也不太友好。

所以这里就出现了两个方案:

  • • 方案一:用户依然在现有系统中操作,通过 Operator 转换成 Istio 的配置;

  • • 方案二:上线后一次性将现有配置全部迁移到 Istio 配置,编写适配器给原系统使用者调用,用户可以用 GitOps 工作流也可以用原有的管理后台操作;

团队内部对这两个方案也争论了很久,两者各有利弊。

最终我们还是采取了先用当前配置为权威的方案,将来再慢慢将 Istio 配置作为权威并引入 GitOps 工作流。

这样选择最主要的原因就是,做现有系统配置和 Istio 配置的映射并不是一个确定的转换规则,随着我们对 Istio 的改造和理解更深入,转换逻辑会得到优化,最终的结果也会改变。另外想要实现方案二,不仅要实现一套老配置到新配置的适配,还要实现一套新配置到老的管理后台的适配,工作量非常大。

3.2 服务注册与发现

想要让服务注册与发现互通,主要方案也会有两个:

  • • 方案一:按照 Istio 的标准用法,Service Mesh 应用部署在独立的集群中,所有进出集群的流量都走 Gateway;

  • • 方案二:无论是原有的 SOA 集群还是新的 Service Mesh 集群,网络打通,两套服务注册与发现系统做实例双向同步;

由于历史原因,当前携程内部的应用有部署在 BM、VM、Kubernetes 等环境中,之前并未给不同集群做网络隔离,相互之间都是互通的。因此在实现 Service Mesh 的时候也采用了相同的方案,我们要做的就是一套实例双向同步系统。

4e1259694d6fcf50f6c82e0faf0269f5.png

对于在 Service Mesh 环境中部署的应用,我们的 Operator 会读取系统中应用和服务之间的绑定关系,通过监听 Kubernetes API 感知到 Pods Ready 后帮助 Pods 注册到老的注册中心,应用的 SDK 无需做任何操作。也就是说在 Service Mesh 环境部署了一个其他语言编写的应用,只要它在系统中绑定了对应的服务并在标准端口暴露了服务,就可以被 Service Mesh 中的应用访问到,也可以被原 SOA 系统中的应用访问到。

对于在原 SOA 系统中部署的应用,它的 SDK 会先将自己上报到注册中心。Operator 会监听注册中心的实例变化并转换成 Istio 的配置。

在 Istio 的模型中,不仅可以将 Kubernetes 中的 Services 和 Pods 转换成 Envoy 的 Clusters 和 Instances,还可以定义 ServiceEntry 和 WorkloadEntry,将外部的地址转换成 Envoy 的 Clusters 和 Instances。我们正是利用了这个功能将原注册中心的服务和实例同步到了 Service Mesh 集群中。

3.3 功能对齐

接入 Service Mesh 之后,原来 SOA SDK 支持的一些功能,我们也需要进行支持,比如预热、熔断、限流等。

预热

基于 JVM 的应用在刚启动时,由于热点代码还没有进行 JIT 编译等原因,如果这时就接入和平时一样的请求流量,会导致这部分请求的响应时间增加。预热的基本思想就是让刚启动的机器逐步接入流量,目前 SOA SDK 中已经实现了一些预热算法,客户端会根据服务端的配置来控制流量以达到预热的效果,可配置的参数有:预热算法(例如控制流量直线型增长或指数型增长等)、预热时间等。

而 Envoy 在最新版中才提供了类似的功能:Slow start mode

那如何在现有的版本中实现这个功能?由于这里的核心目标就是让刚启动的服务实例逐步接入流量,最小连接数的负载均衡算法就可以达到这个目标,并且负载均衡方式通过 Istio 的 DestinationRule 直接就可以进行配置,这个算法可以使客户端每次都去访问当前活跃请求数最小那个服务端。于是我们考虑在服务发布期间,将服务的负载均衡方式设置为最小连接数。

对于利用最小连接数的负载均衡的实际效果我们也做了相关的测试,可以看到引入后服务端在启动过程中,客户端的平均响应时间大幅度下降。

1168180910730ea4240e7877cbb67288.png

在 SOA SDK 支持的预热中需要配置预热时长,而用户很难确定这个时长需要配置为多少。不同的机器配置、不同的 QPS、不同的业务逻辑等,都会影响服务从启动到预热完成所花的时间。如果配置的预热时长太短,实例没有真正的预热完成,就会导致部分请求响应时间增加了;而如果配置的太长,就会导致已经预热完成的实例没有充分的发挥作用。

而在服务接入 Service Mesh 后,在发布期间我们通过最小连接数的负载均衡算法,自适应地调整不同实例的负载。用户不需要关心需要配置什么预热算法,也不需要决定预热时长是多少,只要打开预热开关就可以了。

熔断

Istio 中可以通过设置DestinationRuleConnectionPoolOutlierDetection,来实现熔断策略。当服务由于某些故障开始响应变慢时,ConnectionPool中关于 pending 请求数、最大并发请求数的设置,会限制客户端继续向变慢的服务发送更多请求,以此来给服务一些时间从响应变慢中恢复。当服务的部分实例出现故障时,OutlierDetection的配置使客户端停止对这些故障实例的访问,来减轻偶发的部分服务实例故障对客户端的影响,也让故障的那部分实例有时间恢复。

我们的 SOA SDK 目前基于 Hystrix 来实现线程隔离,这部分功能基本对应到 Istio 中的ConnectionPool配置,Istio 中不同的目标服务都有自己的一组连接池。两者实现方式不同,但基本可以达到同样的效果。

当服务的部分实例出现故障时,Hystrix 会将新的请求拒绝,这部分可以对应到 Istio 中的OutlierDetection配置。不过这里有个区别,这种情况下 Istio 会将故障实例摘除,而不是直接报错。Istio 中这个功能的本质是一种客户端健康检测,但可以达到类似的效果,应该来说比直接报错更好。

限流

我们 SOA SDK 支持的限流为本地限流,具体包括对特定操作限流、对特定的请求方 AppID 限流等,我们需要在 Service Mesh 中也支持这些功能。由于目前 Istio 没有对限流抽象出模型定义,我们通过EnvoyFilter打 patch 的方式,来对开启了限流的服务生成对应的 Envoy 限流配置。

为了将 SOA SDK 已有的丰富的限流配置都在 Service Mesh 中得到对应的支持,我们使用了 Envoy 限流的descriptors特性。

参考文档:

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值