前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >一文快速了解Proxyless Service Mesh的进化

一文快速了解Proxyless Service Mesh的进化

作者头像
春哥大魔王
发布2023-03-22 18:11:32
8710
发布2023-03-22 18:11:32
举报
Service Mesh已经在云原生领域火了很多年。

最近一段时间,proxyless service mesh也逐步进入了大家的视野,比如gRpc、Dubbo都引入了proxyless service mesh方案。

那什么是proxyless service mesh呢?它又有什么价值呢?

我们结合一个具体case 的发展史了解下 Proxyless 的进化史。

一个典型的service mesh长这样:

每个App的Pod里面,有一个独立的Sidecar进程,App之间的通信都通过Sidecar进程转发。

整个架构中,有一个全局的控制面,常见的是Istio,下发配置到每个Sidecar,控制具体请求的转发策略。

而一个典型的Proxyless Service Mesh架构长这样:

由集成到App进程的rpc框架负责服务之间的通信。

控制面下发配置到每个rpc框架,rpc框架按照配置进行具体的请求转发。

比如 gRpc和Istio之间的通信是由Istio Agent来代理的。

通过以上两个典型架构对比,可以发现proxyless和proxy模式的区别。

架构是演进出来的。

目前越来越多的应用架构开始接受Proxy模式了,尽管看起来Proxy模式中间带来了额外的资源开销,但经过多年的优化,性能得到了很大的提升。

但如果一个非常复杂的拓扑,哪怕每次转发只消耗0.2ms的延迟,所有边上都增加一点点延迟,最终整体产生的延迟也是很大的,对系统的稳定性和性能产生影响。

于是架构开始了从Proxy模式向Proxyless模式演进。

Envoy从Istio拿到流量转发配置,并翻译成bRpc可以识别的配置。

bRpc通过http接口从Envoy中拿到流量转发配置,并按照这份流量配置去调用其他服务。

这种模式转变带来了一些好处。

首先,业务接入Mesh,不会带来延迟(因为原来的微服务架构就是基于bRpc实现的通信),也不会增加明显的资源开销(Envoy带了的开销可以忽略不计)。

其次,业务既可以享受Mesh的便利性,比如控制面的集中配置管理、动态下发配置、无需代码的修改和配置的修改上线重启,极大提升了服务治理的效率。

你会发现,bRpc可以用到哪些服务治理能力,决定因素在于Envoy和bRpc之间翻译出策略的多少。

也就是说,大部分Istio配置的能力其实是不能被bRpc直接使用的。

那随着服务治理能力诉求的越来越多,不仅需要在Envoy中迭代,还需要在bRpc中迭代,由于两种技术栈策略的不同,导致很多代码难以复用,就会进入重复开发的老路上来。

常见的服务治理能力包括:权重路由、基于请求内容的路由、实例子集路由、流量复制、错误注入、异常实例驱逐、自定义错误码重试等。

于是,mesh架构进化到Proxyless/Proxy统一的mesh架构上来。

左边是Proxyless模式,Envoy负责把xds配置转换成bRpc能识别的配置,bRpc宿主在业务进程,从Envoy获取配置,并依照配置做流量转发。

右边是Proxy模式,Envoy负责把xds配置转换成bRpc能识别的配置,bRpc宿主在Envoy进程,从Envoy获取配置,并按配置实现流量的转发。

无论哪种模式,Envoy都负责转换配置,bRpc负责执行配置转发,这样代码可以在Proxy和Proxyless两种模式下复用。

通过Proxy和Proxyless两种模式的复用,可以实现不同语言的支持。

比如C++服务,可以与bRpc联编,实现Proxyless模式。

其他的非C++服务,比如Python、Php、Java等,可以无侵入的方式使用Proxy模式。

由于在 Envoy中Http协议是一等公民,其他协议的治理能力都相当薄弱,而过去公司大规模使用rpc通信,已经围绕于rpc沉淀了很多服务治理能力,所以考虑下掉Envoy这一层,让rpc与Istio直接通信。

bRpc直接和Istio通信,获取到xds配置后进行转换。

Proxyless模式下,bRpc宿主在业务进程中,实现对请求的转发。

Proxy模式下,bRpc作为一个独立的Sidecar进程,对请求进行转发。

这样整个架构彻底甩掉了Envoy,让ServiceMesh可以轻装上阵。

这样,仍然只需要开发一套策略,通过Proxy模式和Proxyless模式适用到不同的开发语言,无需为每个语言开发对应的SDK(配置在Istio,bRpc只需要做规则的翻译和请求的转发,很是轻量级)。

至此,相信你已经了解了什么是Proxyless ServiceMesh了,也知道为什么在Sdk Agent和ServiceMesh之外会衍生出Proxyless模式了。

那Proxyless带来的优势是什么呢?

看几个例子。

比如要实现一致性哈希负载均衡。

在Rpc时代,可以在Rpc框架中的协议头追加一个请求码:requst_code,放置请求哈希码。这样Rpc框架可以根据这个request_code将请求调度到同一个后端。

在ServiceMesh模式下,负载均衡是在Sidecar中做的,Sidecar想要获取到这个请求的request_code,就需要修改Rpc框架,让框架从业务进程请求中截取request_code并透传给Sidecar。

不同协议传递request_code方式不一样,比如http协议可以在header传递,rpc协议还需要修改请求头协议。

这样每个协议都需要修改协议逻辑代码。

所以在Proxy模式下,传参的实现成本 = (Rpc框架发送参数 + Sidecar接收参数) * 协议数量。

而Proxyless模式下(就是bRpc和Istio直接通信的方式,无需Envoy这种Sidecar转发),参数本来在Rpc框架能拿到的,所以传参的成本趋近于0。

类似其他的服务治理场景,比如请求级别超时控制、请求级别路由参数等,Proxyless模式都完胜。

还有一种场景,就是基于rpc请求的结果,回调业务代码实现不同的干预策略。

比如用户想自定义重试策略,rpc框架在访问一次后端服务后,调用用户代码逻辑,判断是否需要重试。

大概长这个样子。

在Proxy模式下,会如何实现这个重试回调方案呢?

方案一:将业务代码中自定义重试策略放到Sidecar中,但每个业务的重试策略都不具备通用性,放在Sidecar里,这种通用的基础设施显然不合适。

方案二:Sidecar提供一种扩展机制,比如WASM,用户将自定义重试策略实现为WASM,以配置方式下发给Sidecar执行。但将原有代码改造成WASM的成本比较高,这会明显降低业务接入Mesh的意愿。

方案三:业务进程暴露一个服务接口,Sidecar调用这个接口,实现对是否重试的判断。这样是非常WatchDog的思想,不仅增加了业务进程和Sidecar之间的交互次数,增加了延迟,也增加了问题出现的概率。

总之,在Proxy模式下,以上几种方法都看起来是非常笨重的方法,把一件简单的事情复杂化了。

而在Proxyless模式下,由于回调重试能力,本身已经集成在了Rpc框架里了,所以对于这个场景需求的实现成本是0。

类似的自定义负载均衡策略、自定义NamingService策略等,Proxyless都完胜。

我们再看一个动态分片场景。

在搜索、推荐类业务中,多分片是很典型的一个场景,因为一个服务实例不足以承载全量数据,只能通过分片方式,每个实例承载一部分数据。

客户端在查询此类服务时,需要根据请求信息,将请求路由到持有不同分片数据的实例上,获取到分片数据后,再聚合推送到客户端。

有时由于请求的潮汐情况,分片会发生扩缩容,分片数就会发生变化,为了保证流量的平滑迁移,就会存在不同分片数量的分组。

由于不同数据属性特点不同,数据量级不同,所以每个数据分片之后分片数量也不同。

以上两种情况,都需要对请求做动态分组,以确定调用哪个分组的服务。

在动态分片场景下,rpc是以下这种方式交互的。

因为业务需要根据最终选定的分组和分片数拼接业务请求,所以rpc交互分为两个阶段。

如果是Proxy模式,基本上没有好的方法,因为需要在Sidecar做大量的策略定制,但这些又不通用,导致很难实现。

而Proxyless模式中,第二阶段是可以沿用的(就是获得拼接请求参数和请求结果的过程),第一阶段获取分组、分片策略是可以通过Istio做配置下发到rRpc的。

分布式服务可观测性实现。

在分布式场景下,通过Trace建立服务入口流量和出口流量之间的串联。

这种服务可观测性最好的方法就是深入服务内部,甚至代码逻辑调用时延,需要很强的业务代码入侵。

但如果有了sidecar,这种方式做起来反而不那么容易了,因为sidecar对业务代码来说是黑盒,很难侵入的定制埋点,他的粒度是粗的,是请求的request、response维度的,很难做到代码片段维度的。

之前的文章提到过,ServiceMesh是一种服务治理的理想态,但现在的ServiceMesh解决方案还没有达到理想态。

参见:Service mesh有啥意义?

首先,ServiceMesh的本质肯定不是Sidecar,Sidecar确实解决了很多服务治理的痛点,比如支持多语言、应用解耦,这样可以让遗留系统快速变为一个ServiceMesh架构。

但需要考虑 ServiceMesh给用户带来了什么价值。

很简单,如果用户自己觉得没有价值,即使接入成本是0,大概率也不会接入。

那用户关注什么价值呢?

  1. 我的服务可用性是否提升了?
  2. 服务治理能力(包括超时重试、限流熔断策略)是否可以被低成本使用上?
  3. 服务时延是否降低了?这种降低不是单个实例和sidecar边的延迟,而是整体时延的降低。
  4. 服务的可观测性,链路的黄金指标观测、调用链路追踪能力等。
  5. 灵活的流量调度策略,比如灰度发布、跨机房切流等调度策略。
  6. 安全性,比如TLS、各种认证鉴权机制,提升调用的安全性。
  7. 管理便利性,通过控制面可以集中管理,动态下发配置生效。

因此,ServiceMesh的价值,是让服务间通信更可靠、更快、更安全、更透明、更灵活的管理基础设施。

那具体是Proxy还是Proxyless模式不重要,需要从实际业务场景出发,满足业务需求。

再聊一下对于 ServiceMesh 认知上的一些误区。

ServiceMesh的本质是配置中心吗?

ServiceMesh概念出来之后,很明显的一点变化就是引入了配置中心,通过这种方式弱化了Sidecar的复杂度,降低了服务接入Mesh的成本。

很多人认为Proxyless模式不就是Rpc框架+配置中心吗?Proxy模式不就是7层代理+配置中心吗?

但ServiceMesh中的控制面不能简单的看做是配置中心,配置中心仅仅做到配置的下发,而不感知配置的实际含义。

是不是很难理解?

比如Istio代表的控制面,实际上是定义了ServiceMesh的能力标准,比如各种负载均衡策略。

即使Rpc的配置中心把所有ServiceMesh的控制面能力都实现了,但没有统一协议和配置格式的话,不同框架的配置方式就会变得五花八门,通信协议相互割裂,也就算不上ServiceMesh了。

所以ServiceMesh背后是一组服务间通信的能力标准,这些标准实现了,才称得上是ServiceMesh。

当前ServiceMesh架构,最初Envoy+Istio的组合是首选。

但随着大家的觉醒,或者发现自己原有的服务治理问题不能低成本迁移到Mesh上,或者Mesh不能解决自己所有的问题时,ServiceMesh 的发展就有了新的变化。

控制面Istio还是首选,但在数据面则是百花齐放,这主要是由于不同业务场景特点和过去的基建特点决定的。

有的业务重灵活性、有的重性能、有的重可靠性、有的重安全性,也就有了不同的数据面方案。

同时一些成熟的Rpc框架,也不甘于做一个瘦客户端,还需要继续发扬Proxyless精神,变为一个Proxyless ServiceMesh 方案,让自己的价值体现在更多的服务治理场景中。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-12-23,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 春哥talk 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
服务网格
服务网格(Tencent Cloud Mesh, TCM),一致、可靠、透明的云原生应用通信网络管控基础平台。全面兼容 Istio,集成腾讯云基础设施,提供全托管服务化的支撑能力保障网格生命周期管理。IaaS 组网与监控组件开箱即用,跨集群、异构应用一致发现管理加速云原生迁移。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档