首页 > > > 微服务实践:我们离Service Mesh还有多远
服务网格(Service Mesh)的横空出世让人眼前一亮,但初期实践者反馈的性能、可落地性等问题让技术决策者变得谨慎。随着社区蓬勃发展、更多大厂的加入,越来越多Service Mesh落地案例开始出现:网易严选业务在接入上线中,一些企业Service Mesh已经进入大促核心链路。那么问题来了:我们离Service Mesh还有多远?
本文由作者授权网易云发布,未经许可,请勿转载!
作者:裴斐,网易杭州研究院云计算技术部工程师
网易轻舟微服务团队从2018年初开始对Service Mesh进行研究,从Istio 0.x版本时的不完善,到1.3.x release版本的逐步稳定,再到目前可以支撑网易严选、传媒逐步接入,我们对Service Mesh的认知也从浅入深,从疑虑到笃定。最初更多思考的是“Service Mesh离我们还有多远”,到目前落地期从业务出发产生“我们离Service Mesh还有多远”的思考。本文会以业务Service Mesh演进落地的思路为出发点,力求帮助对这项技术感兴趣的同行对微服务业务Service Mesh落地形成一定的认知。
业界关于Service Mesh的介绍、布道文章非常多(Istio官网,中文社区),这里不会对Service Mesh基础知识做过多展开介绍,尽量以扼要的方式介绍核心概念、架构、功能的基本面,以便读者尽快熟悉背景。
Service Mesh中文译名服务网格,是用以处理服务与服务之间通信的基础设施层。其最早由Buoyant公司(开发Service Mesh项目Linkerd的公司)提出,并在内部使用。该公司2016年9月29日第一次公开使用这个术语。
Service Mesh功能在于处理服务间通信,职责是实现请求的可靠传递。在实践中,Service Mesh通常由服务与轻量级网络代理(Sidecar,与服务部署在一起)组合而成。Sidecar中文翻译为边车,或者车斗,它在原有的客户端和服务端之间加了一个代理,但对应用程序透明。如下图所示为两个微服务之间通过Sidecar互相调用的情形:

当微服务(Service)集群扩大到一定规模后,就会形成网格状(Mesh),即形成了'Service Mesh'形态:

Service Mesh会接管整个网络,在服务之间转发所有的请求。在这种情况下,业务服务不再负责处理请求的具体逻辑,只负责完成业务处理。服务间通讯的环节就从服务里面剥离出来,呈现出一个抽象的基础设施层。对应的服务间通讯相关的治理功能,如流量路由(根据权重或参数分流、负载均衡、黑白名单)、流量治理(熔断、限流、容错)、请求认证鉴权、调用拓扑等均在下沉的Service Mesh层实现,微服务研发者专注于业务研发本身即可。
对于通常的业务微服务而言,Service Mesh所带来的核心价值可以总结为:
从功能上讲,以Google、IBM主推的Istio框架为例,其对Service Mesh核心功能表述如下所示:


整体架构说明如下:
在基于Envoy+Istio方案中,容器化是Service Mesh高效落地的基础。容器化+Kubernetes编排不仅为微服务本身带来灵活部署调度、扩缩容、高可用等诸多能力,对Service Mesh架构下Sidecar注入、生命周期管理、流量拦截、安全管理等也提供了十分重要的特性。简而言之,容器化与Service Mesh具备天生的亲和性。
Service Mesh架构本身并未限定业务微服务本身必须容器化,Istio社区也从未将支持非容器这扇“门”堵死(早期的版本Istio仅对Kubernetes进行了支持),轻舟Service Mesh方案中也提供了对非容器的支持。但从微服务业务长期规划、Service Mesh核心价值最大化、压缩迁移成本等方面考虑,容器化+Service Mesh一定是微服务业务演进的重要方向。集团内严选、传媒均已选择了上云+容器化+Service Mesh同步进行的演进规划,轻舟团队也为这两大业务提供了演进接入Service Mesh方案。
在基于Envoy+Istio方案下,Kubernetes基于ETCD的注册中心机制是社区注册中心的默认方案。对于其他注册中心,可以通过Istio的MCP机制接入(Consul、Eureka、ZooKeeper等)。
值得注意的是,Service Mesh架构下服务注册、发现与传统服务框架存在较大差异:
传统服务框架下,微服务的注册通常通过服务框架SDK将微服务注册到注册中心,通过SDK中的发现方法从注册中心发现服务与实例列表,即通过客户端SDK完成注册发现。
在Service Mesh架构下,控制面组件(如Istio Pilot)负责对接注册中心。服务在创建Kubernetes Service、Deployment时会完成自动注册;服务的发现则是由控制面组件拉取或监听注册中心,将获取到的服务与实例信息转换为统一服务模型,再通过GRPC推送到Sidecar,这样Sidecar就获取到了服务与实例信息,即通过控制面组件完成服务发现。通过控制面组件完成服务发现模式下,控制面组件可以通过实现不同注册中心的适配器,同时获取多种注册中心的服务与实例信息,即可实现多注册中心服务的互相发现。示意图如下:

虽然Istio Pilot提供了对接多种注册中心能力,Kubernetes基于ETCD的注册中心机制依然是推荐的容器化+Service Mesh下的注册中心选择。原因不仅是这是Kubernetes的原生机制,能力完整性与健壮性强,在实践过程中,通过MCP机制实现各注册中心的对接并不像想象那样平滑:控制面组件对注册中心进行定时拉取或监听,对于不同注册中心会选择不同的策略:如果对接的注册中心没有提供增量式拉取获取监听的机制,控制面组件每次对注册中心全局的信息获取会是巨大的压力(轻舟团队在严选有过对接Consul的实践,终因对Consul服务器可能带来的巨大压力而作罢)。严选、传媒业务原有注册中心均为Consul,在进行容器化+Service Mesh演进时均选择迁移使用Kubernetes基于ETCD的注册中心机制(新老注册中心互相发现方案见后续“平滑迁移”章节)。
在明确容器化、注册中心两大基本路线后,平滑迁移会是微服务业务演进到Service Mesh的最关键“战役”。纵使Service Mesh有着各种前瞻性的架构与功能特性,尽量少的让业务感知到迁移过程是Service Mesh大规模落地的关键。一般而言,涉及平滑迁移的主要包括业务/框架适配、灰度引流两大部分。
业务/框架适配
符合云原生微服务规范的业务可以自然平滑地尝试接入Service Mesh,这部分介绍可以直接跳过。对于一些没那么“云原生”的已有业务微服务来说,可能需要一些业务/框架的适配,以更好的接入Service Mesh。这里的适配一般是为了符合使用规范的服务调用配置(服务名/地址+path)。
在原生Istio方案下,对目标服务的调用配置需统一为服务名+path的方式,如调用money-rich服务的getMoney接口,服务调用配置需要是money-rich/api/getMoney,这里还需要Iptables、DNS进行流量拦截的对应支持,以实现将调用流量拦截至Sidecar。轻舟团队对原生方案进行了扩展,支持了Sidecar地址指向的方式,如指向本地Sidecar的调用配置127.0.0.1:8550/money-rich/api/getMoney,这种方式不需要对Iptables或DNS进行修改,提供了相对简单的流量拦截方式,这一特性目前已经应用于严选环境。
适配方法上,如果业务本身需要在容器化过程进行工程改造,服务调用配置可以一起改造掉;如果不希望修改业务代码,可以通过统一框架的升级、引入增强型服务框架(如轻舟微服务框架NSF)来实现。
灰度引流
在业务完成容器化+Service Mesh改造与迁移后,已经可以在容器化服务范围内互相发现、调用、治理策略分发与生效了。但对于大部分线上环境在跑的微服务业务而言,需要逐步将原有流量灰度引流到Service Mesh体系内服务。以轻舟团队为严选提供的云内/云外互访方案为例,如下图所示:

上图中左半部分为业务实现容器化+Service Mesh改造后微服务部署、调用形态,右半部分为业务已有线上业务。在两个环境之间引入了边缘网关进行跨环境方案代理、服务发现、访问控制。
自从Istio发布以来,性能问题一直是很多质疑者所诟病的核心问题。一般而言所说的性能问题主要包括两部分:
如下为Istio 1.3版本最新的性能报告:(横轴代表并发连接数,纵轴代表延时ms)

社区性能报告基于两个服务间端到端HTTP协议测试得来:绿线代表端到端测试延时基准曲线,蓝线代表两层Sidecar基准曲线(不通过Mixer),黄线代表两层Sidecar同时开放Mixer的曲线。可以看出:在中小规模访问时,延时损失可以忽略不计;在大规模访问时(16并发1000RPS,系统负荷较大)情况来看,请求过两层Sidecar不开启Mixer情况下较基准调用延时增加约2.3ms(即请求链路多两跳带来的延时增加),这个数值在开启Mixer情况下增加到约7.2ms(即Istio Mixer带来约5ms的延时增加)。注意:这里的数值非绝对值,是业务大规模访问场景时的HTTP协议的参考值。
从上面分析来看,正常负载情况下延时可以忽略;在大规模访问时,带来的延时有些不上不下:既没有做到业务真正无感(比如1ms以内),也没有带来对大部分业务来说算重大的损失(毕竟大部分业务处理本身产生的损耗要远高于10ms)。
为进一步优化大规模访问时Service Mesh带来的延时影响,轻舟团队主要从以下两个方面进行优化跟进:
Envoy Proxy -> Mixer服务 -> 策略后端服务的同步链路,相当于所有请求需要经过若干服务处理并返回后才可以调用到真正的目标服务。社区之前也已经意识到这种模式下虽然为扩展后端策略服务提供了便利,但性能上的缺陷促使Mixer V2提上日程。解决思路是在Envoy Proxy提供可多语言实现扩展filter(基于WebAssembly),直接对接到目标策略后端服务。在Mixer V2正式release之前,轻舟团队提供了脱离Mixer的方案,仍然可以实现Mixer带来的Metrics、Trace、Logging功能。但由于Mixer本身并不是必需组件,如果不需要这部分功能的话,业务可以配置不启用Mixer。Istio提供了完整的Service Mesh框架,包含服务调用、流量治理、服务治理、遥测(监控,分布式追踪,日志)、安全等,整体上封装了数据面(Envoy Proxy,Pilot-agent)、控制面(Pilot-discovery,Mixer,Citadel,Galley)等诸多服务组件,架构上确实比较复杂,加上Istio为了使服务模型、治理策略、遥测策略等能够具备充分的扩展性,进行了较多抽象,形成了很多概念模型(数量堪比Kubernetes),想要全局理解掌握和直接使用成本偏大。
对应解决方案上,轻舟团队主要从以下两个方面进行优化:
随着Service Mesh架构的成熟,Service Mesh相关功能、性能及运维配套的完善,集团重点业务的逐步落地,相信会有越来越多的集团业务加入到演进接入中,我们离Service Mesh会越来越近。
参考资料:
相关阅读推荐:
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/1817/viewspace-3158880/ ,如需转载,请注明出处,否则将追究法律责任。