前言
在已落幕的 QCon 全球软件开发大会·北京站《云原生微服务架构新趋势》专场,业界大佬们针对以基础设施和业务分离为核心目标,多运行时 /Dapr 等概念/项目被提出已有 2 年有余,它们是否真正解决了我们面临的问题?业务的反馈如何?是一个明确的新趋势吗?另一边,微服务治理标准化是否可行? Proxyless 是正确的路线吗? Java 如何适配云原生微服务架构?等问题进行了热烈讨论。腾讯云中间件团队技术专家单家骏针对以上问题也带来了精彩分享,议题是《面向异构技术栈和基础设施的服务治理标准化。》
本次分享主要从以下5个小节进行,首先从企业级服务架构入手,介绍异构技术设施和技术栈在现代企业架构所存在的必要性及对服务治理所带来的挑战,接下来介绍针对这些挑战的解决方案--服务治理标准化建设,最后分享标准化方案的生态建议。
背景
企业级服务治理金字塔
本次分享主题和服务治理有关,而服务治理主要是为企业应用服务的,因此我们先看一下企业应用架构的组成。
当我们需要开发一套系统,首先要进行架构选型,架构选型的两大影响因素是组织架构和业务复杂度。如果组织人员比较少(10人以下)而且业务可能只有1-2个模块,那么就可以直接选择单体集群架构。如果团队中人员比较多,而且业务模块比较复杂,那么可以使用分布式或微服务架构,按业务模块进行服务的划分,各模块之间通过分布式消息调用进行解耦,达到并行开发、数据隔离、故障隔离的目的。
确定了架构形态后,我们需要进行系统开发,开发系统需要选型合适的技术栈,也就是语言和框架。一般来说,业务的匹配度以及开发效率是技术栈选型的影响因素,比如前端一般使用 JS,后台类可能使用 C++,Java,Go 这些;相同的可以开发后端应用的语言,用户往往愿意选择生态更丰富,开发效率更高的语言。
业务实现后,需要解决部署的问题。部署的基础设施一般有容器化和虚拟机,决定这方面的影响因素往往是成本,包括资源成本和运维成本。另外上云的话,基于合规以及和云厂商 argu 的考虑,企业往往也会采用混合云(比如金融类业务需要部署在金融区),或者多云方案。
业务部署完成后,我们需要对业务平滑上下线及高质量运营。这时候我们要有对应的灰度策略。同时上线运行后,我们也要有一定的手段控制业务出现故障时的影响范围,以及对故障进行及时的监控及告警,这时候就需要我们对服务进行治理。只有业务能够高质量发布及运营,才能创造商业价值。
影响服务治理的,往往是下面的两个支撑要素,技术栈和基础设施。
什么是多技术栈
技术栈主要涉及的是开发业务所需的语言和框架,从业务的模块架构来看,最简单的业务系统,都包含2个模块,Web 前端以及后端。而对于复杂点的业务,比如像 AI 中台,包含 Web 服务、后台业务(比如用户认证、数据增删查改)、基础服务(比如存储、缓存、日志等系统),还有AI相关的服务,比如用户分析,智能推送等。每部分模块都会有最适合的语言和框架,这时候,多技术栈就是解决复杂系统开发效率最好的手段,而且也是企业架构的常态,会长期存在。
什么是异构基础设施
首先看基础设施,先忽略 Serverless 的场景,对新业务以及愿意做容器化改造的业务,优选的是容器,因为容器可以获得更好的资源利用率和部署效率。而对于一些强依赖系统底层的业务,比如音视频的业务,或者是简单的单体应用,往往不需要去做容器化,纯虚拟机部署就解决。而对于中间这部分容器化的过度阶段或者只能部分容器化的业务,则会出现异构基础设施容器化和虚拟机共存。
对服务治理的挑战
回过头来,我们看看异构基础设施和多技术栈,对服务治理会产生什么样的挑战:
服务发现模型不一致
不同的 PaaS 都有自己的服务模型及服务发现机制,比如 K8s 会基于 etcd+coredns 进行服务定义和集群内发现,自建的 PaaS 也会有自己定义的服务模型。部署在不同的 PaaS 上的应用需要通信,则需要使用统一的服务模型。业界一般有以下的解决方案:
解决方案 | 存在问题 |
---|---|
使用外置全局 DNS 进行服务发现 | DNS 默认会有缓存时延,会导致节点变更不及时。 |
使用 LB +全局 DNS 进行服务发现 | 能解决缓存问题,但是由于中间多了一个 LB,所以主调方没法做负载均衡,长链接场景下,会有负载不均的情况。 |
使用外置注册中心 | 不同注册中心的服务模型也存在差异,如果要互通或者迁移需要做额外的处理。 |
服务治理规则模型不一致
不同的服务治理套件都有自己的规则,同时服务框架本身也带有部分治理功能。而不同框架之间的配置,以及功能完整性都会存在差异。比如熔断,像 hystrix 的熔断,是当错误率出现阈值时候,切断访问资源的所有流量。而有些框架,熔断是弹性的熔断,就是错误率达到阈值后,会减少流量的接入并非全切断。针对这些问题,业界一般有以下的解决方案:
解决方案 | 存在问题 |
---|---|
业务系统使用统一的服务框架 | 1. 存量系统,存在较大改造工作量;2. 一套框架可能适合不了所有的业务场景。 |
使用 Sidecar,将服务治理能力下沉 | 1. 接管流量存在性能损耗;2. 非 K8S 场景使用运维比较复杂。 |
解决方案:服务治理标准化
为了解决上面的这些问题,linux 基金会旗下的下一代基金会,联合各开源社区及企业,共建服务治理标准化,主要包含两部分:
第一,是建议一套中立通用的服务治理标准,包括功能及接口的定义。
第二,只有定义的话,别人也无法直接使用,因此还需要有一套匹配的标准实现,解决重复开发和功能下沉的问题。
基于这个理念,由北极星社区牵头设计了一套标准化方案:
关键的目标是可以做到与基础设施和技术栈无关,同时也可以兼容存量系统及接口,用户可无缝接入,平滑迁移。
第一层是治理面,负责服务治理规则的下发,数据管理及全局功能实现。主要分为服务管理、流量管理、故障容错、访问控制、可观测性五部分。
第二层是数据面,数据面是服务治理功能的标准实现,提供多语言 SDK、以及 JavaAgent 这2种不需要额外 Sidecar 的形态,以及提供 Sidecar 的标准实现,支持 Proxy 接入的场景。
第三层是服务框架,是直接面向应用的组件,框架可以通过集成数据面组件的方式来快速接入服务治理,也自己按照标准化的定义来进行功能的实现。
接下来我们介绍这几部分的功能:
服务管理
服务管理包含服务定义及健康检查两部分。
首先是服务定义,服务定义基于两个思路来设计,第一个是最简和可扩展,第二个是和现有生态能够无缝互通。所以我们服务模型是基于命名空间-服务-实例这3层的模型,每一层模型通过元数据来保证可扩展性,与现有的 K8S 以及其他注册中心的服务模型保证兼容及可转化。
第二是健康检查,需要支持常见的应用通过心跳等方式维护自身的健康状态,同时也要支持由第三方的 PaaS 平台进行管理应用的健康状态。
流量管理
流量管理包含了主调方的出流量管理,以及被调方的入流量管理。比如对于灰度的场景,10%流量发送到灰度分组,那么首先 SDK 会按百分比的方式对流量进行染色,加上请求标签,接下来,会通过请求路由根据请求标签,匹配出灰度分组的实例列表。最后再通过负载均衡算法,筛选出目标实例。而在被调方,则会根据自己的系统容量,对请求进行限流判断,对于超过 QPS 配额的流量, 可以进行拒绝或者排队。
故障容错
接下来是故障容错,故障容错包含针对故障发生时的重试机制,以及故障达到阈值后的熔断机制。
重试是个很重要的能力,所有的重试都是在系统处理请求出错后进行的,没有处理好的重试会有放大系统故障的风险。所以,SPEC 中约定了两个关键的重试要素:第一个需要解决的是应该重制的请求,该如何重试。比如对于链路层的错误,是应该重制的,重试加上退避策略使得重试更有效果,一般会有指数级时延退避,随机退避等策略。第二个需要解决的是不应该重试的请求,如何进行抑制。比如说,对于单点实例的重试,是要避免的,每次重试应该重试到不同的实例。还有就是对于链路级的重试,要做到只在出现故障的服务进行重试,上游不需要重试。
故障后除了重试,我们也需要熔断,熔断也会有2种场景,一种是针对硬件出现故障或者新上线的应用部分接口出现BUG的情况,这种场景需要主调方对所调用的资源的流量全熔断一段时间再尝试恢复。第二种情况并不是出现故障,而是出现过载了,这样的话,最合理的熔断方式是部分熔断,维持在刚好不过载的水位,对额外的低优先级请求进行丢弃。
访问控制
最后我们讲一下访问控制,对于一些安全性较高的业务,比如金融类业务,需要解决服务资源的访问安全问题。主要包括对身份的认证,以及确认身份后对其访问的资源进行鉴权。
首先要保证每个来访者都是合法的,需要对来源请求进行身份认证,认证通过后才接纳。
来访者是合法的,但不保证他有权限访问到他需要的资源,因此管理员需要对资源进行授权,同时对请求访问的资源进行权限校验,确保不会出现访问越权。
默认实现 --- PolarisMesh
刚刚介绍的都是功能怎么做的一个规范,但是为减少用户的接入成本,我们还需要一个默认实现。下面我们介绍下标准化的默认实现--北极星(https://github.com/polarismesh)。
PolarisMesh(北极星)是腾讯开源的生产级的服务治理组件,一体化的治理平面提供了服务管理、流量管理、故障容错和配置管理的功能,基于标准化的接口定义,下发治理规则与服务配置数据到数据平面。而数据平面则提供服务治理的功能实现,同时也支持 SDK, Java Agent,Sidecar 等多种接入方式,可以在虚拟机、容器等任意的环境,实现服务数据的互通,大家都共享同一份治理配置和实现,无需做额外的重复开发。
看到这里可能大家就会问,业界已经有 XDS 了,而且 XDS 本身可以实现控制面于数据面之间的服务治理协议的交互,为啥不直接用 XDS 呢,这里之前也考虑过,但是基于实践上遇到了的一些问题最终还是放弃,这里初步列举了一些原因和对比,主要是以下这几点差异性。尽管存在差异,北极星的服务治理定义,可以和 XDS 兼容,同样可以支持 XDS 的客户端(比如Envoy、Grpc-xds)的接入。
Xds Specification | Polaris Specification | |
---|---|---|
概念模型 | 当前 XDS 主要还是源于 Envoy 的数据模型,治理协议分散在 LDS、 CDS、RDS、EDS 中,与网关的技术模型比较贴近,存在一定理解成本。 | 以服务为中心的治理模型、所有的流量管理、故障容错、鉴权都围绕服务进行,按功能和场景维度来划分模型。 |
功能对比 | XDS 当前只覆盖了服务治理的基本功能,在一些细节功能以及场景化的覆盖上还存在不足,比如支持主调规则、分布式限流的策略等。 | 提供了更具体的服务治理基础能力和标准实现,未来会场景化进行进一步封装(比如多环境路由、灰度等)。 |
性能优化 | XDS 默认标准实现是基于全量和增量下发规则,在规则较大的情况下,存在启动缓慢问题。 | 默认支持按需下发规则,规则的下发只会在首次使用功能时候进行。 |
标准实现 | 默认只提供 Envoy 的标准全功能数据面实现,对非 Sidecar 场景支持不够友好 | 提供多语言 SDK,Sidecar、JavaAgent 等多种数据面实现。 |
兼容性 | - | 提供 XDS 的适配能力,支持使用 XDS 的数据面组件也接入。 |
生态建设
服务治理标准化需要先与框架生态进行融合,才能更好的提供能力供应用开发者使用。
北极星与业界多个主流框架生态进行了扩展整合,确保开发者可以无需修改或者少量应用代码即可接入标准化的服务治理能力。
当前已实现对接服务框架如下:
框架 | 已对接功能 | Github地址 |
---|---|---|
Spring Cloud | 服务发现、配置管理、熔断降级、流量管理、可观测性 | https://github.com/Tencent/sp... |
cloudwego/kitex | 注册发现、熔断降级、流量管理 | https://github.com/kitex-cont... |
kratos | 注册发现、配置管理、流量管理 | https://github.com/go-kratos/... |
dubbogo | 服务发现、熔断降级、流量管理 | https://github.com/apache/dub... |
未来规划
服务治理标准化建设,未来会从两个方向进行进一步的迭代和完善:
标准化规则的建设上:
会进一步完善当前提供的服务治理能力,如可观测性,同时为更好的解决用户实际场景化的问题,则需要多个原子化功能组装使用,比如灰度发布需要组合使用染色、路由、可观测性等能力,存在一定使用成本。未来会封装场景化的规则,通过场景化规则自动联动多个原子能力工作,降低使用成本。
生态建设上:
会进一步提供对多语言的支持(比如 Nodejs/.net 等)。同时加强与框架社区合作,在继续完善当前已对接的生态组件的基础上,支持更多主流的框架生态的对接。
写在最后
服务治理标准化协议已经发布了1.0.0版本,欢迎大家提出宝贵意见,并可基于北极星及对接的生态组件进行体验:
Specification:https://github.com/nextarch/S...
PolarisMesh:https://github.com/polarismesh
Spring Cloud生态:https://github.com/Tencent/sp...
cloudwego/kitex生态:https://github.com/kitex-cont...
kratos生态:https://github.com/go-kratos/...
dubbo/dubbogo生态:
https://github.com/apache/dub...
https://github.com/apache/dub...
https://github.com/apache/dub...
https://github.com/apache/dub...
https://github.com/apache/dub...
https://github.com/apache/dub...
欢迎加入交流群一起共建:
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。