云原生微服务治理技术朝无代理架构的演进之路
作者:杨奕 华为云技术规划专家
微服务治理技术发展趋势
对于云原生的归纳,业界从来没有停止过演进。但是总体来讲,微服务和容器化基本上是两个永恒不变的话题。今天这篇文章重点来谈谈微服务架构的演进。
微服务这个词,比较公认的官方正式介绍来自 Martin Fowler 在2014年发布的 Microservices 一书。但是实际上,其解决的服务解耦的问题,最早可以追溯到SOA (Service-Oriented Architecture,面向服务的架构)。下面这种图 (参考链接 ) 比较好的诠释了服务的演进历程。从最早的SOA,到本世纪10年代的微服务,到最后的云原生微服务架构的Servicemesh,核心都是为了解决在企业的复杂业务场景下,让各服务以解耦方式各自独立快速迭代。
图例1:服务架构的演进历程:SOA -> 微服务框架 -> 云原生
总体来讲,微服务的迭代发展到目前为止,分为三个阶段。
• SOA:该阶段针对政企场景的烟囱式架构,通过集中式中心网关方式,解决异构应用之间的快速集成问题。该阶段,服务治理功能集中在中心网关上,性能和可靠性上也都有较大问题。
• 微服务框架:主要针对大规模高并发场景,通过去中心网关、做厚客户端的方式,使得企业内部应用可快速解耦和横向扩容,以满足业务快速发展需求。该阶段,服务治理功能一般通过SDK,部署在业务程序上,辅以注册中心和配置中心进行服务管理。虽然性能和可靠性得到解决,但是服务治理逻辑和业务逻辑存在一定程度耦合,在应用生命周期迭代上存在一定问题。
• 云原生 Service Mesh:将更多的服务治理能力沉淀到云平台上,应用只关注业务逻辑,服务治理和应用彻底解耦,应用快速迭代得到解放。该阶段,服务治理功能以代理边车方式沉淀到容器内,应用时在运行时挂载边车即可,具体的服务治理控制逻辑由云平台(如图中 Kubernetes/Service Mesh)承接。
在以上架构图中,SOA不是本文重点。关于SOA到微服务的演进,感兴趣可以参考文章 《 SOA 和微服务的区别》 一文。本文以下章节重点介绍其他的 微服务框架 和 云原生 Service Mesh 这两个阶段的微服务治理架构特点。
微服务框架 架构
如前文所述,微服务的的名词比较正式被普及可归公于 Martin Fowler 在2014年撰写的 Microservices 一书。但是实际上,国内的微服务起源反而更早。比较出名的是是阿里早期的HSF和Dubbo。正如“ Dubbo 和 HSF 在阿里巴巴的实践:携手走向下一代云原生微服务 ”一文中所述,阿里最早在2008年就开始了微服务方面的实际尝试,虽然可能在当时,其团队并未真正意识到自己开发的其实是下一代微服务架构。
”Dubbo 项目诞生于 2008 年,起初只在一个阿里内部的系统使用;2011 年,阿里 B2B 决定将整个项目开源 ,仅用了一年时间就收获了来自不同行业的大批用户;2014 年,由于内部团队调整,Dubbo 暂停更新;2017 年 9 月,Dubbo 3 重启开源,在 2019 年 5 月由 Apache 孵化毕业,成为第二个由阿里巴巴捐献至 Apache 毕业的项目。“ |
文摘1:Dubbo阿里内部的演进历史
在海外,虽然RPC框架类组件尘出不穷,但是真正将服务治理纳入一体,而且几乎成为事实标准的,当属 Spring Cloud 。虽然项目是2016年才开始正式发布,但论流行程度,不光在世界范围论堪称一哥,在中国国内,风头也几乎盖过Dubbo。
图例2:Dubbo 和 SpringCloud 在国内的搜索热度。蓝色是Dubbo,红色是SpringCloud
Dubbo和SpringCloud的具体发展历程,这里不多做介绍,大家可以翻翻其他相关介绍。这里重点突出一个两套框架的一个共同特点,无论是Dubbo,以及后来的SpringCloud,都不光是一套RPC框架。其除了方便研发直接基于RPC模式开发微服务架构的业务以外,自身还有很多扩展点,方便服务治理开发人员以独立Jar包方式进行服务治理功能的单独开发。比如:Dubbo比较耳熟能详的是自身的基于SPI扩展点机制来实现服务治理;而SpringCloud则是通过SpringBoot机制,通过开发者开发starter包来实现服务治理。两者基本都能做到服务治理功能对业务代码解耦。例如SpringCloud,对于引入新的服务治理功能,很多时候对于开发者来说只需要引入一个starter的pom依赖。不过这也引入一个问题,任何服务治理的功能升级,虽然对于业务代码来说只是更新配置文件,但是毕竟还是动了业务代码,这也给服务治理功能的升级带来潜在阻力。随着业务规模增长,该问题也会被指数级放大。
基于以上问题,需要指出一个极其重要的但是容易被忽略大家忽略的事实,就是微服务治理能否在一个大厂内能否大规模铺开使用,很重要的因素是服务治理能否和业务在软件开发和发布上解耦。阿里之所以微服务内部推广和演进比较顺利,笔者认为很大原因是阿里内部采用的微服务框架HSF很早集成了Pandora 容器 这项技术。这个不起眼的技术,其实起了一个至关重要的作用:服务治理功能和业务功能在代码上彻底解耦,治理功能的jar包可以在不改变业务代码情况下单独发布;且在此基础上实现了治理功能和业务功能类隔离,防止类冲突。
图例3:据阿里巴巴 微服务 实践 一文介绍,通过Pandora,业务和中间件逻辑发布得到完全解耦。
阿里内部的Pandora容器技术,虽然在外曝光度不高。但是在阿里的服务治理领域起到了至关重要的作用。正是因为有了Pandora,阿里的业务开发人员才能做到 "治理功能万千重,我自岿然不动"。阿里历史上每年双11前几个月,在业务近乎无感情况下,微服务框架批量搞几次大版本升级,也基本就能满足每年大促的服务治理需求。
而其他如采用SpringCloud技术栈的大厂,在没有类似Pandora容器的隔离技术情况下,随着业务规模增长,服务治理能力的演进将越来越痛苦。每发布一个重要版本或重要补丁,服务治理团队就需要思考如何去说服上千个业务方进行SDK升级,就成了一件让人非常头疼的事。因此,服务治理功能如何和业务功能在架构上如何解耦,就成了后来微服务治理一个刚需。这也是后续Istio等边车服务治理方案兴起的一大原因。
云原生 Proxy (边车代理) 服务治理架构
在CloudNative时代的服务治理架构中,Service-mesh因为其对应用的无侵入性,成为了云原生服务治理的一个经典流派。而在Service-mesh流派中,Istio又是其中一个代表作。Istio的兴起,其实核心是因为解决了两个问题。
• 多语言架构下的服务治理功能统一。无论是java、go、c++等语言,只要通讯协议一致,理论上都可以通过边车进程来进行服务治理。
• 通过代理进程方式,实现治理功能对业务代码的非侵入,架构上和业务充分解耦。
图例4:Istio 社区 中火了5年的书店demo程序,集 python、ruby、node.js、java 等各类开发语言
关于Istio的功能和架构介绍,网上文章多如牛毛,本文就不赘述了。但是这里核心讲下Istio在实践中遇到的几个问题。
• 非侵入的兼容性。本来非侵入是istio的主打优势,但是社区版的istio有个核心问题,就是是基于gRPC协议构建的。这就使得istio在国内落地时,面对国内dubbo治理框架是个事实标准之一的情况,显得有点水土不服。这在大多数云厂商的istio商业版中对Dubbo的各种“蹩脚”支持可见一斑。虽然dubbo社区也在主动朝3.0开始演进,兼容gRPC协议,但是其成熟度仍尚存很长距离。
• 服务治理,功能也很丰富,但是有缺陷。在长长的xDS协议的功能列表中,从服务注册发现,到限流降级,到混沌工程,可谓玲珑满面。但是基于Proxy边车的服务治理方案中,一大硬伤是Proxy边车进程毕竟是个和业务无关的进程,本身无法侵入到业务进程,因此任何需要在业务进程透传标识的场景全部都不支持。典型比如分布式链路Tracing ID的透传,还比如一些全链路灰度发布的路由标的透传,等。以上两个问题,都可参考 Proxyless Service Mesh 在百度的实践与思考 一文中有详细阐述。
图例5:百度在 Proxy Service Mesh 实践中因为边车无法侵入进程,所遇到的问题
• 架构上,由于采用了单独进程,无论是性能和运维上,和SDK流派相比还是有差距。一方面,在各种基准性能测试中,额外的响应时间稳定增加1.7ms以上,参见istio Performance and Scalability 。另外一方面,在落地时,sidecar conatiner的规格设置也是个令人头疼的问题:vcpu和内存设得小了,性能不够;设得大了,浪费资源;按应用各自性能特点设置,又造成额外管理成本。
图例6:Istio社区中最新发布的性能测试。测试现实,增加边车,性能损耗至少增加1.5ms
基于以上各种原因,原生的istio的落地实践中,都多少处于叫好不叫座的尴尬境界。接下来就Proxy边车治理方案的问题,说说为啥最近Proxyless边车治理方案开始逐渐异军突起。
云原生 Proxyless (无代理) 服务治理 架构
Proxyless服务治理,原本出处是 gRPC Proxyless Service Mesh . 原文本意是基于gRPC,结合xDS协议,做了一个服务治理框架。gRPC Proxyless Service Mesh的提出,笔者认为,本质上是因为proxy治理架构的各种各样的问题,导致istio团队重新思考适基于现成的xDS协议,把服务治理的大部分功能重新做到了框架内部。从架构上看起来gRPC Proxyless Service Mesh更像是走了一次微服务框架流派的历史倒车,把业务和治理框架耦合在了一起。
图例7:左边是 gRPC Proxyless Service Mesh 最新发表的架构图,右侧是 Dubbo 几乎10年前的架构图,是不是何其相似
那么有没有一种 Proxyless 边车方案,既能具备边车方案的各种解耦优点,又能一定程度上克服Proxy带来的问题呢?答案是 Javaagent。
Javaagent的字节码增强技术很早就有。真正发挥商业价值的地方其实是在2015年前后的所谓APM元年,其被大量使用在APM领域。但是这个javaagent这个技术在服务治理领域火起来的,也是最近两年的事。这里面主要发生两件值得一提的事:
• Apache Skywalking 这个开源APM工具,作为国内Apache的顶级项目,把javaagent技术在国内好好普及了一把。最终结果是各个互联网中小厂商基本上java进程上都挂了一个skywalking javaagent的同时,该技术都普遍接受。 (笔者见过不少政企和互联网厂商,甚至挂了一个skywalking javaagent的同时,又挂了一个基于skywalking修改的javaagent,其使用场景涵盖各种服务治理场景。)
• 基于对javaagent技术的接受基础上,以Java技术栈为主的各类互联网大厂和云厂商开始内外大量使用Javaagent技术做服务治理和相关商业化产品。总体上讲,之前业界对javaagent做服务治理基本上都持观望态度。现在基本上也不质疑了,大家现在思考的问题都变成了怎么把javaagent在服务治理领域如何发挥到极致。
为啥javaagent技术这么火?这是因为其相比传统SDK和Servicemesh技术:
• 非侵入架构:这点和Sidecar架构类似,治理能力开箱即用,业务方代码务虚改造,上车成本极低。而且相比传统边车技术,没有额外进程,运行态和开发态的差异进一步降低。
• 治理功能和业务代码升级解耦:相比SDK升级动辄需要去各业务方推广,非侵入这块这块能力确实比SDK实际体验好太多。试想一下,治理功能快速迭代的同时,业务方只需晚上滚动重启一下即可获得新的治理功能,这对服务治理团队和业务团队都是一种生产力的解放。
• 相比传统边车方案,性能更好,资源消耗更低 :毕竟传统边车方案动辄2ms以上的延时增加,以及额外的进程资源开销,对业务都是不小的负担。而javaagent这块由于采用和SDK雷同的AOP服务治理方式,性能几乎和SDK持平。
• 治理场景多样:实践证明,在场景上,Javaagent > SDK > 边车架构。Javaagent的场景比边车方案多,这个好理解,毕竟Javaagent可以注入到用户进程中,完成很多流量标透传的场景,这块是边车架构无法做到的。但是Javaagent为何场景比SDK方案还要多?这是因为一般如Dubbo, SpringCloud等治理方案,其默认需要对应的RPC函数提供相应的函数埋点。但是很多服务治理场景,如流量录制回放,对应的一些远程调用,如Redis调用,本身并不提供函数埋点,因此通过SDK来拦截流量进行录制和回访就无从谈起。而基于Javaagent的字节码增强技术则没有这个限制。
图例8:(原创首发)Javaagent对其他服务治理对比的优势
当然,Javaagent的服务治理技术也并非银弹。
• Javaagent最大的问题是服务治理场景只能用于Java。如果您所在公司,主流开发预言是非Java类,那么还是放弃吧。但是如果您所在公司,主流开发语言是java, 但是有很多长尾应用语言是其他语种怎么办?这里开发者可以考虑 传统边车 + javaagent 方案,javaagent负责主流的Java语言微服务的服务治理,而传统边车方案负责其他多语言的服务治理。至于两者的服务治理打通,业界也有很多方案,如Javaagent同时对接基本的xDS协议,也可以完成两者服务的打通。
• 这里也稍微提个不大不小的问题,就是当多个javaagent对同一个类进行增强的时候,有时候会产生增强冲突的异常。其实这块很多场景是因为各类javaagent开发不规范的原因,是完全可以避免的。相关详细的问题就不展开了,大家如果敢兴趣的话,可以去看下相关文章 记一次多个 JavaAgent 同时使用的 类增强 冲突问题及分析 。这里就摘出要文章核心摘要:
"严格遵守字节码增强的使用要求和限制。
无论是Byte Buddy、Javassist还是ASM,底层实现都离不开JDK1.5之后引入的Instrumentation接口。既然官方接口的设计理念是reTransformClasses()增强类时不能新增、删除或者重命名字段和方法,不能更改方法的签名,也不能更改类的继承关系,那作为JavaAgent的框架开发者,应该不要做出超越上述限制的设计,否则极易导致JavaAgent之间的兼容性问题出现。不仅仅是这个接口,JavaAgent框架的开发者也需要遵循所有的字节码增强的底层接口的设计理念,毕竟有规则才有秩序。" |
文摘2:"记一次多个JavaAgent同时使用的类增强冲突问题及分析" 文中对避免Javaagent冲突的建议。
华为云的sermant开源项目
用javaagent做服务治理很香,但是实际上手怎么搞? 华为云在早期接触的很多客户场景中,发现很多架构团队都是拿已有的开源的 javaagent 相关的项目上手魔改做自己的服务治理能力。但是做着做着很快发现了几个问题。
• 我们目标的服务治理功能很多,但是一般开源项目如pinpoint, skywalking等增强的点就那么一个,比如如果在服务调用增强点上实施了链路追踪逻辑以后,再加其他比如限流降级功能,就需要在Plugin中写很多限流降级逻辑,这些代码逻辑会和已有的开源项目的原生治理逻辑纠缠不清。
• 很多服务治理功能本身逻辑可能比较重,有其自身的三方依赖依赖库。但是世面上已有的Javaagent,并不支持针对组件级别的类隔离机制。
• 服务治理场景有很多通用逻辑,除了方便快速的对特定函数接口做增强以外,还包括可替换的实时配置中心,基于RPC的Tag透传,通用的Metrics上报机制。能否把这些能力都沉淀出来,以SDK API方式暴露给开发者直接使用,这样可以极大提高服务治理的开发效率。
以上几个原因,促使我们思考是否应该做一个新的javaagent服务治理项目,来解决以上问题。这就是sermant项目由来。我们希望通过Sermant项目,
• 服务治理功能以插件形式装载到javaagent中,不同插件间可以做到对同一个业务函数增强点进行不同增强,且互不冲突。最终所有服务治理统一到一个javaagent中,降低资源损耗。。
• 服务治理插件之间同时需要做到类隔离,以降低不通版本的三方库依赖造成的类加载冲突风险。
• javaagent本身能提供一层厚度适中的framework能力,帮助插件快速开发服务治理能力。项目之初,我们提出至少三个目标需要尝试实现:
• 实时配置中心抽象。无论用ZooKeeper, Nacos, 还是Servicecomb,都不影响插件使用统一framework提供的实时配置的能力。以此做到实时配置连接收敛。
• payload数据透传能力。我们希望framework提供SDK,无论是tracing id透传,还是全链路灰度标透传,都能基于数据透传能力快速开发治理功能。
• 监控能力。按照规范开发的插件最后都能在后端平台上对所有的javaagent和其加载的plugin做统一监控。
图例9:Sermant 的框架、插件架构
路走对了,就不怕远。到今天,在公司内外生态伙伴的贡献下,Sermant名下已有各类服务治理插件已多达数十种,场景覆盖包括 服务注册发现改造、服务契约查询、服务血缘关系发现、服务双注册、配置治理、流量录制回放、限流降级、优雅上下线、全流量标签路由、同机房调用优先、故障注入、性能监控、等等。我们同时将规划更多的框架层能力,以辅助增强Sermant服务治理总体能力,进一步降低插件开发难度。这包括:插件动态插拔能力,应用无需重启应用,即可在线升级服务治理功能;插件增强顺序动态调配,对于同一个函数增强点,不同插件可以按需调整顺序,如性能监控插件在限流降级插件之前生效,以保证服务治理逻辑正确;等等。
如果您对以上细节感兴趣,我们诚挚欢迎你来社区使用 Sermant 。
图例10:Sermant 的社区介绍
欢迎使用Sermant
Sermant社区当前快速成长中,当前开源代码仓地址:https://github.com/huaweicloud/Sermant
Sermant目前部分服务治理功能已在华为云产品中提供商业化服务,华为云用户可在 微服务引擎 CSE 中使用相关功能: https://www.huaweicloud.cn/product/cse.html
政企客户亦可在最新的HCS产品中使用相关Sermant功能。该功能在ROMA-Factory已支持部分场景的PoC。
文章引用:
[1]Microservices:
https://www.martinfowler.com/articles/microservices.html
[2]《SOA和微服务的区别》:https://bbs.huaweicloud.cn/blogs/315752
[3]Microservices:https://www.martinfowler.com/articles/microservices.html
[4]Dubbo和HSF在阿里巴巴的实践:携手走向下一代云原生微服务:https://www.infoq.cn/article/6dgaucctd2uibzycfgax
[5]开源:https://www.infoq.cn/theme/108
[6]Spring Cloud:https://spring.io/projects/spring-cloud
[7]Pandora 容器https://www.infoq.cn/article/kgxytjb2cr7hgukmjg0p
[8]阿里巴巴微服务技术实践:https://www.infoq.cn/article/kgxytjb2cr7hgukmjg0p
[9]Istio社区:https://istio.io/latest/docs/examples/bookinfo/
[10]Proxyless Service Mesh在百度的实践与思考:http://dockone.io/article/2434761
[11]Performance and Scalability:https://istio.io/latest/docs/ops/deployment/performance-and-scalability
[12]gRPC Proxyless Service Mesh:https://istio.io/v1.12/blog/2021/proxyless-grpc/
[13]gRPC Proxyless Service Mesh:https://cloud.google.com/blog/products/networking/traffic-director-supports-proxyless-grpc
[14]Dubbo:https://dubbo.apache.org/zh/docs/v3.0/concepts/registry-configcenter-metadata/
[15]Apache Skywalking:https://github.com/apache/skywalking
[16]记一次多个JavaAgent同时使用的类增强冲突问题及分析:https://bbs.huaweicloud.cn/blogs/382800
[17]Sermant:https://sermant.io/
- 点赞
- 收藏
- 关注作者
评论(0)