作者 | 于雨
起源 | 阿里巴巴云原生公众号
本文源自 2020 年 12 月 20 日作者在云原生社区 meetup 第二期北京站演讲《Apache Dubbo-go 在云原生时代的实际与摸索》的局部内容,如果对演讲残缺内容感兴趣请拜访:
https://www.bilibili.com/video/av245840877
自从以 2013 年开源的 docker 为代表的的容器技术和以 2014 年开源的 K8s 为代表的容器编排技术登上舞台之后,相干技术从业人员从认知和体感上承受,云原生时代真的到来了。
当然也有很多资深技术人员认为,云原生时代要从 2010s 时以 OpenStack 为代表的虚机编排时代开始。当然,也有人说其实云原生技术诞生很早,能够从巨型机时代在巨型机上虚构出若干小型机开始追溯。
在云原生时代,不变镜像作为核心技术的 docker 定义了不可变的单服务部署状态,对立了容器编排状态的 k8s 则定义了不变的 service 接口,二者联合定义了服务可依赖的不可变的基础设施。有了这种齐备的不变的根底设置,就能够定义不可变的中间件新形态 — 云原生中间件。
云原生时代的中间件,蕴含了不可变的缓存、通信、音讯、事件(event) 等根底通信设施,利用只需通过本地代理即可调用所需的服务,无需关怀服务能力起源。
微服务框架
从最早的单体利用时代到分布式技术时代,风行的是微服务技术。微服务时代各大公司都积淀出了具备代表性的一些服务通信框架,如 Google 的 gRPC,阿里的 Dubbo 和 HSF,百度的 bRPC 等等。多个服务通信框架之间的竞争,基本上是在大公司之间进行角力。
站在使用者的角度,当然期待一个网络框架在进化过程中可能放弃向前兼容性,多个框架之间放弃互通性。
1. 服务框架的向后兼容性
通信框架的根底是通信协议和序列化协定,其中很重要的问题就是新版本协定对旧版本的向后兼容性。在一个组织中个别都应用对立的通信框架,但事实中可能因为各种起因,同一个框架的序列化协定或者通信协议的向后兼容能力差,会导致应用不同版本通信框架的各个服务之间的异构化。如采纳了 pb v2 和 pb v3 的通信框架不兼容,不遑多让的 Thrift 0.8.x 与 Thrift 0.9.x 之间也不兼容。
不过 Protobuf v3 或者 Protobuf v2 的各个子版本之间的向前和先后兼容性还是不错的,但还是有一些弱鸡公司的外部序列化协定无论是否采纳 TLV 模式,其协定各个版本的之间还是无奈兼容,进而导致各个子版本的服务框架互相异构,最终导致应用了不同版本的服务框架的业务背上大量包袱无奈疾速演进,有些新版本的业务中存在各种神逻辑可能不是为了兼容旧版本的业务逻辑,而是为了兼容旧版本框架的通信协议。
2. 多框架之间的互通性
一个常识是,组织规模收缩到足够大的水平后,不可能有一个通用的框架实用于所有的场景,一些大经济实体随着业务体质变大,业务类型变得庞杂,不可避免地存在一些反复的轮子,这些宏大规模的组织因为其规模效应,任何一个实用于特定场景的框架只有能在外部找到若干落地利用场景就足以让其开发保护老本变得可累赘且收益甚大。
公司外部各个分公司之间可能存在不同服务框架导致各个服务之间通信异构化越来越重大,如阿里外部早前存在异构的 Dubbo 和 HSF(目前阿里外部 HSF 和 Dubbo 曾经开始交融,HSF 曾经采纳 Dubbo 作为内核以 Dubbo 插件的模式存在),如当下的阿里的 HSF 和各个收来的新公司之间的网络通信,其间通信可能不得不借助于 Proxy 模式的通信网关。
每个服务框架各个子版本之间须要放弃向后兼容,各个服务框架之间的兼容可能须要网关代理。
3. 多语言框架之间的互联
除了序列化协定、通信框架的异构外,还普遍存在着因为各个不同语言技术栈之间差别导致的异构:每种语言都有个各自的序列化协定和通信框架。如 Java 世界就存在着 Spring Cloud 和 Dubbo 两大服务治理框架,Spring Cloud 尚无多语言版本实现,相比之下 Dubbo 的多语言工作稍好一些。
4. 买通打平不同的技术体系
同一实体外部不同公司之间有两三个不同服务框架的状况曾经算是很好了,大公司组织外部能够容忍适量的反复造轮子,但大量的反复造轮子就过犹不及了。据说有巨头外部不同部门之间存在各自的 RPC 服务框架,其总体服务框架超 100+!
随着国内互联网行业倒退因为头部效应趋向性显著,在大鱼吃小鱼的时代背景下,大公司与收买来的公司之间的技术体系异构也是云原生时代中间件面临的一个问题,二者之间因为业务规模不同带来的服务注册核心、配置核心、语言技术栈、服务鉴权、缓存和存储等诸多技术不对立。有的刚收来的公司甚至应用了大公司的竞争对手的云平台,这就又带来了平台级的差别,诸如此类的异构问题不一而足。
借助网络代理技术,能够初步疾速买通不同技术体系之间的异构差别。
5. 通信代理的必要性
除了南北向通信的网络接入层代理外,微服务时代应用同一通信框架的各个服务实体之间间接进行通信,很少据说各个服务实体之间通过代理 Proxy 进行通信,其根由是各个通信实体之间通信框架同构。
或者说,网络通信代理被各个强悍的通信框架给消化掉,以 Proxyless SDK 的模式存在,如服务发现、服务路由、容灾限流、负载平衡等性能都存在于各个服务框架的 SDK 中。
但随着多协定多语言等各种因素导致的各个框架之间的各种同化,大家广泛置信:没有什么差别不是一层 Proxy 解决不了的。
6. Service Mesh
2016 年之后衰亡的 Service Mesh 技术辨别为 Proxy Service Mesh 和 Proxyless Service Mesh,至于二者之间的差别可参见本文 2019 年的一篇文章 Service Mesh 状态刍议。目前比拟风行的 Service Mesh 技术模式是 Proxy Service Mesh,其比拟有代表性的组件有数据面的 envoy 和管制面的 Istio。
一些 Service Mesh 技术文档声称,将服务框架的序列化协定、通信能力、服务治理能力积淀到服务网格的代理(如 envoy 这类数据面 sidecar)中,可有如下收益:
- 服务框架 SDK 会变的十分轻量,甚至齐全积淀到 sidecar 中。
- 多语言、多协定和多种通信形式之间的差别将被磨平。
- 对立流量管制,晋升零碎的弹性。
- 对立监控设施,进步可观测性。
- 对立平安可信认证,晋升安全性。
- 降级过程业务无感,做到平滑降级,晋升可靠性。
- 晋升业务版本迭代速度。
- 疾速买通不同技术治理体系之间的差别。
- 在 Mesh 和 非 Mesh 模式之间疾速切换。
有人可能据此误以为 Service Mesh 技术可将业务和服务框架的复杂性毁灭于有形,将 Istio + sidecar 模式为代表的服务网格能够定义为 Service Mesh 的终极状态。
Sidecar 与中间件
Proxy Service Mesh 的数据面的 sidecar 仅具备通信能力,业务利用和 sidecar 之间依然存在一个 gap:微服务时代利用所应用的中间件零碎的能力须要积淀到 sidecar 中。
1. Sidecar 的能力
Proxy Service Mesh 中 sidecar 的一个典型代表是 envoy,其本质是一个具备通信能力的 local proxy,具备如下数据面能力:
- 流量管制
- 序列化协定转换
- 通信协议转换
- 数据路由管制
实际上,envoy 仅仅是提供了这些能力的接口,至于具体的序列化协定转换、通信协议转换插件等工作还是须要相干的基础设施开发人员去做的。
除了序列化协定和通信协议转换,中间件的其余能力向 Proxy 下沉的过程中,都须要做大量的 envoy filter 层面的工作。绝对于 Proxyless 模式的 Service Mesh,Proxy Service Mesh 老本没有任何变动,其对业务的侵入性也没有加重更多。
2. 协定下沉
如果说 Proxyless Service Mesh 状态下的 SDK 降级须要业务层面做很多革新,Proxy Service Mesh 状态下的业务从 Proxyless 向 Proxy 状态降级过程中革新老本也不堪称不小。如果通信协议采纳了 Protobuf V3,Proxy Serivce Mesh 状态下的业务降级协定时可能做到平滑降级:只降级 Proxy 不必降级业务服务实体。但事实是一些公司外部的公有协定基本做不到向后兼容,其老本就是降级协定时服务网格的 Proxy 和业务实体一起降级,至于冀望的平滑降级就很难做到了。
诸般问题的外围是 Local Proxy 没有对立通信协议和序列化协定,仅仅重视于流量劫持。
3. 有状态的利用
Service Mesh 技术的一些爱好者假如服务实体是一个无状态的服务,其代理也当然是一个无状态的 sidecar,而后宣传 Service Mesh 时代的各种红利。
至于那些有状态的利用,大公司有人有钱消耗巨量人日老本后,把状态转移到 Proxy 中去,让利用无状态,但业务无感知的平滑降级是就难做到了。这个老本对大经济实体来说当然是可累赘且收益甚大的,但不是一些中小厂家所能接受的,他们在踩完各种坑后,可能神奇的发现他们基本没有实力实现有状态的 sidecar。
4. 复杂性守恒
总结一番,基于 sidecar 搭建一个 Proxy Service Mesh 可能存在如下工作:
- 不同序列化协定转换
- 不同通信协议之间的转换
- 同一序列化协定多版本之间的转换
- 公有和公开通用的序列化协定之间的转换
- 对单体时代或者微服务时代的业务进行革新降级
- 业务利用和 sidecar 同时降级带来的额定经营保护
- 有状态的 Sidecar 的开发测试与保护
- 利用和代理的优雅退出和平滑降级
- 不同技术体系之间的互通
- Mesh 模式和非 Mesh 模式之间的切换
面对这些难度层层递进的工作,中小厂家很有可能就会退缩到微服务技术体系。其最基本的起因是:同等级别的业务状态下,技术复杂性守恒,总成本守恒。一如微服务技术至于单体技术:各个繁多服务都被拆分的足够简略,但单体技术的复杂性转换为了巨量服务之间的复杂性。
另一种 Mesh
以 Service Mesh 技术为代表的的云原生技术体系根植于以 K8s 为代表的的云原生基础设施之上。
1. 协定标准化
云原生中间件 Proxy 的下一站除了被动地去兼容各种协定,更应该被动的去对立序列化协定,如本身间接反对 Protobuf v3 协定,业务也采纳这种可保障向后兼容的协定即可。
除了被动地去兼容各种通信框架做互联互通,能够更被动地向事实上的通信框架 gRPC 或者通信协议 HTTP 聚拢。gRPC 有各种语言的 SDK 库。各种语言本身会被动提供 HTTP 通信协议库,且 HTTP2.0 向后兼容 HTTP 1.1。例如微软的 Dapr,就间接提供 gRPC 和 HTTP 两种通信协议的 API,下层业务须要做的是抉择其中一种通信协议的 API 进行开发。
2. Service Proxy
一些的云原生时代的事实上的规范通信设施有:2008 年开源的 protobuf v2 和 2014 年开源的 protobuf v3 对立了序列化协定;2016 年 gRPC 公布 v1 之后逐步成了跨语言首选的通信库。
除了序列化协定和通信协议,微服务时代的中间件体系大略有如下技术栈:
- RPC,其代表是 Dubbo/Spring Cloud/gRPC 等。
- 限流熔断等流控,如 hystrix/sentinel 等。
- Cache,其代表是 Redis。
- MQ,其代表有 kafka/rocketmq 等。
- 服务跟踪,如兼容 Opentracing 规范的各种框架。
- 日志收集,如 Flume/Logtail 等。
- 指标收集,如 prometheus。
- 事务框架,如阿里的 seata。
- 配置下发,如 apollo/nacos。
- 服务注册,如 zookeeper/etcd 等。
- 流量管制,如 hystrix/sentinel 等。
- 搜寻,如 ElasticSearch。
- 流式计算,如 spark/flink。
把各种技术栈对立到一种事实上的技术标准,能力反推定义出不可变的中间件设施的终态。把下面这些事实上的中间件梳理一番后,整体工作即是:
- 对立定义各服务的规范模型
- 定义这些规范模型的可适配多种语言的 API
- 一个具备通信和中间件规范模型 API 的 Proxy
- 适配这些 API 的业务
上图定义一种不同于 istio + Envoy 的另一种可能的 Proxy Service Mesh 进化门路。该 Service Mesh 模型下的 sidecar 不仅仅是一个 Local Proxy,更应该是一个提供各个中间件技术栈规范能力的 Service Proxy。
Service Proxy 可能是一个集状态治理、event 传递、音讯收发、分布式追踪、搜寻、配置管理、缓存数据、旁路日志传输等诸多性能于一体的 Proxy,也可能是别离提供局部服务的多个 Proxy 的汇合,但对上提供的各个服务的 API 是不变的。
3. Application Mesh
或者更进一步,能够把 Service Proxy 拆分为两个 Proxy:
- 依然以现有的以劫持网络流量的 sidecar 模式存在的 Local Proxy。
- 另一个专门提供各个 Service API 的 Application Proxy。
Application Proxy 能够是一个独立存在的过程或者容器,也能够是一个可被利用调用嵌入式的 SDK 库。无论是 Proxy 模式还是 Proxyless 模式,这都是一种新形态的 Service Mesh,可被称之为 Application Mesh。
Application Proxy 能够依赖于 Local Proxy,亦可不依赖。如人们常说的三级缓存其实也是一种 Application Mesh 状态,从过程内的 local cache 到本机(容器、虚拟机 or 物理机)cache proxy 始终回溯到 cache cluster,利用只须要从 local cache 处获取数据即可。
当然,Application Mesh 亦可不依赖于特定的基础设施平台,包含 k8s,本文就不展开讨论了。
除了 Service Mesh 技术带来的收益,Application Mesh 具备如下更多的收益:
- 更好的扩展性与向后兼容性
基于规范的 API,其服务的不变性失去极大改善,不变性能够确保中间件的向后兼容与更好的扩大能力。基于规范 API,第三方服务商能够在云厂商提供的基础设施之上扩大出更多状态的中间件设施。
- 与语言无关
对立序列化协定和通信协议后,无特定语言依赖是很天然的事件。支流语言都会反对 HTTP 协定,gRPC 库本身可能提供支流语言的反对。无特定语言绑定带来的另一个间接益处是更好的可移植性。
- 与云平台无关
通过规范的服务让利用做到无云平台依赖,对立了中间件技术栈的平台提供的技术能力雷同的,云平台使用者没有被云服务提供商绑架的危险。
- 利用与中间件更彻底地解耦
通过标准协议和规范 API 让利用与中间件彻底解耦,让开发者在开发阶段对新类型 Proxy 的有感,做到业务上线后业务对 Proxy 及其底层零碎的降级过程无感知,即更好地平滑降级。
- 利用开发更简略
基于规范 API,利用开发者甚至能够用单体时代的服务框架开发分布式应用,晋升利用版本迭代速度。
- 更快的启动速度
状态从利用转移到代理后,能够通过提前预热代理,让利用刹时批量启动。
将来的收益
任何技术都不是没有代价的。诚如微服务技术带来了服务数量的剧增,Service Mesh 技术带来了吞吐的升高和延时的减少,但下一站的云原生中间件状态会带来的是另一种新的价值状态,相比而言这个代价是能够承受的。
1. 业务价值
就其通俗的技术价值而言,做到根底中间件技术的对立后,即可做到无关语言,无关各个具体的中间件实体。加重业务开发人员累赘,使其专一于业务逻辑,做到真正的疾速迭代与平滑降级,晋升研发效率的同时升高各种老本。
2. 云平台无关
新形态带来的商业价值就是无云平台依赖,各平台间相互之间的竞争就不会停留在某种独有的核心技术劣势上,而是在同一技术体系下一直升高服务老本,提供更好的用户体验、更强的服务能力与更亲民的价格。
可能且违心实现这种终态 proxy 的组织当然不是各中小型业务厂家,所以对立了这些规范服务 API 的 Proxy 之下的应该是提供这些规范服务的各大云厂商。越早向对立服务模型聚拢的云厂商越快得利,越置信本人公有服务能力的云厂商越孤立。
3. 初创公司的机会
基于大厂提供的基础设施,能够孕育出一个独立的 service proxy 生态:一些第三方的初创厂家专职提供云原生中间件解决方案。
基于新形态的中间件计划,Low Code 或者 No Code 技术能力更好落地。单体时代的 IDE 能力更进一步 — 分布式时代的 IDE,基于各种状态中间件的规范 API 之对这些中间件的能力进行组合,以 WYSIWYG 形式开发出分布式应用。
4. 突破大厂外部藩篱
对一些大厂组织外部而言,可借助真正状态的 Service Mesh 技术栈能够对立大经济实体外部技术栈,突破人为的各种异构隔离,晋升研发运维效率和物理资源利用效率,升高整体人力与资源的交付运维老本。
5. 走向新时代
以对立技术状态的 Service Mesh 为根底的云原生中间件技术体系真正发动起来,在其之上的 Serverless 才有更多的落地场景,宽广中小企业能力分享云原生时代的技术红利,业务开发人员的编码工作就会越来越少,编程技术也会越来越智能 – 从手工作坊走向大规模机器自动生产时代。
欢送对 apache/dubbo-go 我的项目有趣味的同学欢送钉钉搜寻群号:31363295,退出交换群。
作者简介
于雨(github @AlexStocks),dubbogo 社区负责人,一个有十多年服务端做着基础架构和中间件研发一线工作教训的程序员,陆续参加和改良过 Redis/Pika/Muduo/dubbo-go/Sentinel-go 等出名我的项目,目前在蚂蚁金服可信原生部从事容器编排和 service mesh 工作。
举荐浏览:《Dubbo 3.0 前瞻之对接 Kubernetes 原生服务》