作者简介:牛学蔚(GitHub: @justxuewei):Apache Dubbo PMC,对云原生、中间件、容器等范畴有浓厚爱好,活跃在 Dubbo 和 Kata containers 两个开源项目中。

01 Go 微服务系统开展与选型

跟着微服务技能的快速开展,其在各个范畴都形成了一系列事实规范,在 Kubernetes 和容器技能加持下,云原生微服务已经成为了干流处理计划。而 Go 言语作为云原生范畴最受欢迎的开发言语,正被越来越多的企业作为微服务开发的首选言语,其中比较流行的包含 Go-micro、Go-zero、Dubbo-go 等。作为 Dubbo 微服务系统中多言语完结的一员,在 2022 年 Dubbo-go 以微服务领跑者的角色积极拥抱云原生规范,探究了 Proxyless Mesh 形态,合作适配 Pixiu 云原生网关,形成了完善的 Dubbo-go 微服务生态矩阵。

以 Dubbo-go 为中心的微服务系统在多个知名企业中成功落地和实践,结构的稳定性在实践场景下饱尝住了考验。截止本年已有 60+ 家企业在咱们的用户列表中挂号,其中较为典型案例请参阅文章《小米电商 Apache Dubbo-go 微服务实践》。小米电商选用了 Dubbo-go + Nacos + sidecar + etcd + mirpc 为中心的微服务系统,除了看中了 Dubbo-go 的互联互通和服务办理才干外,也认可 Dubbo-go 在微服务方向的沉淀和堆集。

02 Dubbo-go 简介

2.1 什么是 Dubbo-go

Apache Dubbo 是一款易用、高功用的 WEB 和 RPC 结构,一起为构建企业级微服务供给服务发现、流量办理、可观测、认证鉴权等才干、东西与最佳实践。Dubbo3 从设计上不绑定编程言语,社区现在供给了 Java、Go、Rust、Node.js 等多言语完结,在未来,咱们计划为所有干流言语供给对等的微服务开发体会。

Dubbo 结构作为国内最具影响力的开源微服务开发结构之一,拥有十分高的重视度和活跃度,在 GitHub 上拥有 3.8 万+ stars。Dubbo 项目于 2017 年捐赠给 Apache 基金会,在阅历了短短 15 个月孵化后顺利毕业,在 Apache 基金会办理的悉数项目中重视度排名第三(前两名分别是 echarts 和 superset),Dubbo-go 作为 Dubbo 多言语生态的重要一员,很好的兼容 Dubbo 生态的一起供给面向 Go 言语系统的微服务开发体会。

Dubbo-go(项目地址 github.com/apache/dubbo-go)作为 Dubbo 多言语生态的重要组成部分,现在完全兑现了 Dubbo3 架构的中心才干,并且在云原生年代,凭借 Go 言语无需重量级虚拟机、静态编译以及废物收回的特性,取得了广泛重视,其运用规划也逐渐扩大。从特性上来说,Dubbo-go 现在支撑 HTTP/2、TCP、gRPC 协议通信、服务发现、流量管控、装备办理、全链路追、可视化观测等许多新特性,Dubbo3 已是众多用户生产环境首选的微服务结构(用户列表);在生态建造方面,Dubbo-go 适配了包含 Zookeeper、Nacos、Sentinel、Zipkin、Kubernetes、Prometheus、云原生 API 网关项目 Dubbo-pixiu、异步网络库 Dubbo-getty、Hessian2 等生态项目。

2022 年 Dubbo-go 社区以生态互联、开发者体会、稳定性为切入点,不断优化系统架构,社区荣获多个开源奖项:

  • Dubbo 生态被评为 2021 年我国 20 大最活跃社区之一
  • Dubbo-go 入围 2021 年“科创我国”榜单。
  • Dubbo-go 开源社区被 OSCHINA 评为“2022 年度 OSCHINA 优异开源技能团队”。

2.2 重要特性

通信协议: 遵从 Dubbo 中心架构设计,Dubbo-go 在完结上不绑定通信协议,现在支撑 HTTP/2、TCP (Dubbo2)、JSONRPC、gRPC、HTTP 等多种通信协议,开发者可以依据运用场景灵敏的选择通信协议。

服务注册: 支撑 Client-based 服务发现机制,支撑注册中心适配如 Nacos、Consul、Zookeeper 等。Dubbo3 的服务发现机制诞生于阿里巴巴超大规划微服务电商集群实践场景,其在功用、可伸缩性、易用性等方面的体现大幅领先于业界大多数干流开源产品。

装备中心: Dubbo 装备中心可完结运用装备的长途托管,支撑装备变更的实时感知,现在支撑 Nacos、Apollo(携程开源)、ZooKeeper 等作为装备中心。

负载均衡: Dubbo 供给了多种负载均衡战略,如随机负载均衡战略、一致性哈希负载、依据权重的轮询、最小活跃度优先、自适应负载均衡 P2C 等。

流量操控: Dubbo 的流量管控规矩可以依据运用、服务、办法、参数等粒度精准的操控流量走向,依据此可灵敏的完结超时时刻调整、敞开访问日志、金丝雀发布、参数路由、同区域优先、按份额流量分发等。除此之外,经过接入 Hystrix、Sentinel 等,Dubbo-go 还支撑自适应限流、限流熔断等。

分布式事务: 支撑 Seata-golang 分布式事务结构,完结了 AT 方式和 TCC 方式分布式事务的调用,AT 方式相较 TCC 方式对代码的入侵性更小、需要开发的接口更少,但 AT 方式对事务操作的数据持有大局锁,TCC 模型功用更好。

链路追寻: 支撑依据 Jaeger、ZipKin 的链路追寻才干。

方针可视化: 支撑运用 Prometheus 搜集结构方针和用户方针。

可扩展性: Dubbo-go 供给了灵敏的 extension 扩展机制,用户可随时依据自己的需求灵敏扩展服务发现、负载均衡、装备中心、流量管控规矩、全链路追寻等中间件。

03 曩昔一年咱们做了什么

3.1 高雅上下线

在微服务场景下,事务是以容器的方式对外供给服务,k8s 可以方便的对 Pod 进行翻滚晋级,在旧版别被替换的时分应该到达无损下线的作用,即容器不能被毁掉直到没有正在处理的恳求。假如其不能被正确完结,关于承载高流量的在线服务来说,在更新期间可能会导致很多的恳求报错,乃至可能触发报警,其影响是巨大的。高雅上下线功用是 Dubbo-go 3.0 正式版别发布后的第一个严重增强,王晓伟同学(GitHub: @XiaoWeiKIN)奉献了全流程的高雅上下线才干。

Go 语言体系下的微服务框架选型:Dubbo-go

Dubbo 经典的调用流程如上图所示,这儿面包含了服务供给者(Provider)、服务顾客(Consumer)以及注册中心(Registry)三个要害组件,一个服务可以被调用,首先需要供给者准备服务并对外露出端口(进程 0),然后供给者需要将调用信息注册到注册中心中(进程 1),顾客则会经过异步订阅的方法获取最新的供给者数据(进程 2),注册中心在有新数据后会主动推送给顾客(进程 3),此刻顾客已经有本次调用的悉数信息了,最终顾客发送调用恳求(进程 4),这样就完结了整个调用链路。

在单体运用中,上述逻辑十分清晰和简略,但是在大规划微服务集群中,这个逻辑的每一个细节都需要被细心推敲后,才干确保上下线的进程中调用不出错。

Go 语言体系下的微服务框架选型:Dubbo-go

高雅上线的方针是处理服务上线调用报错的问题,主要针对微服务场景下的调用依赖问题。在 Dubbo 生态中,Service 表明一个服务,可以被露出并被其他服务调用,Reference 表明引证,可以简略的理解为下流服务。一个典型调用结构如上图所示,该服务对外露出一个接口,一起引证了下流的 N 个服务。该服务在上线的时分应该严厉遵从以下流程,首先确保下流服务的引证被成功初始化,之后再初始化 Service 对外露出服务,最终再向注册中心注册服务。高雅上线相对来说逻辑比较简略,只需要严厉遵从初始化进程的依赖关系就能确保上线进程中服务可以被正常调用。

高雅下线是高雅上下线的难点,触及到了信号监听、反注册、等候已有恳求完结调用等逻辑。在需要毁掉容器的时分,kubelet 会向容器发送 SIGTERM 信号,Dubbo-go 会进入高雅下线流程,此刻容器并不会马上被毁掉。即将下线的供给者首先会履行反注册,即向注册中心中删除自己的信息,顾客可以经过订阅取得这个信息,这个进程需要一定的时刻。换句话说,在顾客取得这个删除信息之前,流量还是有可能会流向该供给者,此刻供给者应该回绝这部分恳求。当然除了下线期间的新恳求外,还有残留的来自上游的恳求以及自己调用下流的恳求,咱们分别为这两种情况设置一个计数器,当两个计数器都被清零时,可以以为该供给者是“洁净”的。Dubbo-go 的战略是回绝新恳求,等候已放行的旧恳求。最终,毁掉协议并封闭监听,该容器就可以被安全的去除。

在发动高雅上下线后,集群内无错误恳求,成功率保持在100%。

Go 语言体系下的微服务框架选型:Dubbo-go

3.2 新一代柔性服务

在去年发布 Dubbo-go 3.0 版别的时分,柔性服务初次作为一个重要特性被提出。时隔一年,咱们带来了全新晋级的新一代柔性服务,在新版别中咱们将爬山算法替换为峰值干预算法,在经过屡次测验后新算法行为可控性更高、功用更优异,这部分作业由来自北京邮电大学的张业鹏同学(GitHub: @CoolIceV)奉献。

柔性服务是一种更智能的负载均衡算法。传统负载均衡算法大多是依据顾客视角,它们共同的局限性是无法依据服务供给者的当时状态动态调整分流战略,如 RR、hash 等算法。这些算法总是以尽可能公正的概率分配流量,但在实践中公正不等于负载均衡。

爬山算法是一种容量预估的算法,服务供给者需要将一些要害信息回传给顾客,比方时延、恳求排队数量、预估容量等,顾客运用 P2C 算法选择一个负载最低的作为本次恳求的供给者。这些数据实效性要求十分高,假如这些数据是被迫传递的,那么很难确保实效性,假如这些数据是被主动勘探的,那么在一个大型集群下感知成本十分高。依据上述问题,咱们选择了更可控的峰值干预算法。

顾客部分中,咱们运用了改良版的 P2C 算法,采集的方针包含恳求数(requests)、成功数(accepts)、恳求时延(rtt)。与原完结计划不同的是,该版别采用了更合理的滑动窗口(SlidingWindowCounter)和指数移动均匀(EMA)两种带有时序性的模块进行采集。

SlidingWindowCounter 会保存时长为核算周期 T 的数据,整个周期内的数据被分割为若干个 Bucket,每个Bucket 保存计数时长内的数据,当时所处的 Bucket 会跟着时刻前从而向后移动。

Go 语言体系下的微服务框架选型:Dubbo-go

EMA 利用指数移动均匀算法进行滑润、减小颤动,适用于核算时延型的方针,核算公式:

Go 语言体系下的微服务框架选型:Dubbo-go

以下为一个客户端恳求 3 个服务端的测验结果,3 个服务端装备不同,分别为 1 核 1GB、2 核 2GB、3 核 3GB。兰青色虚线代表开始运用上述负载均衡算法,可以看到敞开前每个服务端接收到的恳求数简直相同,敞开之后流量会依据供给者的规范进行智能分流。

Go 语言体系下的微服务框架选型:Dubbo-go

供给者依据一个 AutoConcurrencyLimiter 组件限流,在恳求到达时会判别已承受的恳求是否超越最大处理量,假如超越了就会直接返回失利,限流导致的失利会影响负载均衡时的成功率,从而影响该实例被恳求的可能性。与常规限流组件不同的是,该组件会依据采样情况主动调整服务的最大处理量,不需要手动装备,而且添加了 CPU 负载作为发动开关,可以减少被错误限流的数量。

该组件主要重视 QPS、无负载时延(NoLoadLatency)和最大并发量(maxConcurrency),一起有一个用户指定的超参数 exploreRatio,表明探究最大并发量的程度。更新规矩是

  • 运用总恳求数(包含未被采样的数据)核算 QPS,新 QPS 更大时直接替换,更小则运用指数移动均匀进行滑润处理。
  • 运用采样数据核算均匀处理时延来估算 NoLoadLatency,均匀时延变小才会更新,并运用指数移动均匀进行滑润处理。
  • 添加探究因子启发式核算 maxConcurrency, 在采样时延或 QPS 在探究答应的范围之内时会逐渐增大 exploreRatio,否则用指数移动均匀的方法进行滑润处理

Go 语言体系下的微服务框架选型:Dubbo-go

最终可以供给给用户一个可以经过 cgroup v1 进行 CPU 约束,当当时供给者 CPU 负载过高的时分,会无条件回绝全部新恳求。CPU 约束是一种最坏情况下的兜底战略。

以下为 1 个客户端恳求一个服务端的测验结果,该测验跟着时刻推移,QPS 会逐渐增大,如蓝线所示。可以看到当CPU 负载(橙线)过高时,有恳求被限流(黄线),随后即便 QPS 再增大,CPU 负载、恳求成功数均已相对稳定。

Go 语言体系下的微服务框架选型:Dubbo-go

3.3 Dubbo Mesh

本年 Dubbo Go 社区发布了 Dubbo Mesh [1] 架构的完好完结,可以以 Proxyless Mesh 的方式参加 Istio 服务网格,敞开了 Go 言语系统下的微服务新形态。

Istio 在架构层面分为操控平面(control plane)和数据平面(data plane),其中操控平面是一个名为 istiod 的进程,网络署理是 envoy 。Istiod 简体 Kubernetes 资源(resources)获取服务信息,比方 Service、Endpoint 等,将这些信息经过 xDS 协议发送给坐落数据平面的 envoy。Envoy 作为一个独立署理进程以边车(sidecar)方式运转,该进程与事务进程共同参加同一个网络,劫持事务流量并转发到正确的位置。

服务网格可以屏蔽复杂的服务办理细节,让开发者可以专注于事务完结。Istio 经过边车的方式完结了事务逻辑的无侵入性,下降了系统之间的耦合性,带来开发便利的一起也引入了转发时延、额定资源耗费的问题。但是 Istio 作为云原生年代的标杆产品,其架构方式和思路就有十分大的学习意义,针对上述提到的 Proxy Mesh 的弊端,咱们提出了一套依据 Dubbo-go 的 Proxyless Mesh 微服务办理方式。

Proxyless Mesh 是无署理服务网格,由 Google 提出后,多个开源产品在这个方向进行了探究和实践。其中心思路是用 SDK 代替独立署理进程,SDK 作为数据平面接收来自操控平面的操控信息,负责服务之间的通信和办理作业。

Dubbo-go 为了融入 Istio 系统,将扩展出来的注册发现流程进行了特殊改造。除了复用 Istio 供给的 EDS、CDS 主机发现的才干之外,添加了接口名到主机名的映射,作为源数据注册在了操控平面上。客户端在建议调用前持有接口名,经过查询 istiod 上的元数据信息,拿到接口名到主机名到映射,转化为主机名;再经过 EDS、CDS 和路由,完结主机名到下流端点实例的转化。完结服务发现流程。

3.4 互联互通的新典范:Polaris 和 Dubbo-go 全面对接

Dubbo-go 从发布伊始,一直十分重视与各个开源产品之间的互联互通,本年咱们完结了与 Polaris 全面对接,这部分作业由社区邓正威同学(GitHub: @jasondeng1997)和春少同学(GitHub: @chuntaojun)奉献。

Polaris 是一款开源的服务办理平台,致力于处理分布式和微服务架构中的服务办理、流量办理、装备办理、故障容错和可观测性问题,针对不同的技能栈和环境供给服务办理的规范计划和最佳实践。在经典 Dubbo-go 运用场景下,用户需要自行布置注册中心、可观测服务、流量办理等组件,而 Polaris 内置了服务办理、流量办理、故障容错、装备办理和可观测性五大功用,可以协助用户快速下降微服务开发门槛。

Polaris 有一致的操控平面,需要为 Dubbo-go 结构适配相应的数据平面 SDK,用户只需要在 Dubbo-go 中敞开 Polaris,结构将主动经过 extension 机制进行注入,开发者无需其他额定的开发作业。从用户数据流的维度,当用户在 dubbogo 中启用 Polaris 的服务办理才干后,事务流量实践处理流程如下:

Go 语言体系下的微服务框架选型:Dubbo-go

当时 Polaris 已完结了 Dubbo-go 原生的服务注册扩展点,因此本来服务注册逻辑不需要进行任何调整,只需要在 dubbogo.yaml 装备文件中新增 polaris 协议的注册中心装备即可,如下所示。

dubbo:
  registries:
    demo:
      protocol: polaris
      address: {polaris-ip}:8091

其中polaris-ip表明北极星服务端 IP 地址,此刻 Dubbo-go 结构就接入了 Polaris 服务办理结构。Polaris 还供给了流量办理、故障容错等许多内容,碍于篇幅约束这儿就不逐个展开了,假如有爱好请参阅 《互联互通的新典范:Polaris 和 Dubbo-go 全面对接》[2]。

3.5 TLS 安全通信支撑

在本年咱们为 Dubbo 协议、Triple 协议和 gRPC 协议完结了 TLS 安全通信功用,微服务之间可以以可信的方法调用,该部分由社区张立斌同学(GitHub: @ZLBer)奉献。

TLS 的前身是 SSL,被用于通信加密,可以确保传输内容不被其他主机查看和篡改,已经被广泛的运用于 HTTPS 等技能中。在敞开 TLS 之前,需要生成所需要的证书和秘钥,咱们假设其保存在 x509 目录中。启用 TLS 不需要对事务逻辑进行修改,只需要设置相应的 Dubbo-go 装备文件 dubbogo.yaml 即可。

顾客装备文件:

dubbo:
  consumer:
    references:
      UserProvider:
        url: tri://localhost:20000
        protocol: tri
        serialization: json
        interface: com.apache.dubbogo.samples.rpc.extension.UserProvider
  tls_config:
      ca-cert-file: x509/server_ca_cert.pem
      tls-cert-file: x509/client2_cert.pem
      tls-key-file: x509/client2_key.pem
      tls-server-name: dubbogo.test.example.com

供给者装备文件:

dubbo:
  protocols:
    triple:
      name: tri
      port: 20000
  provider:
    services:
      UserProvider:
        serialization: json
        interface: com.apache.dubbogo.samples.rpc.extension.UserProvider
  tls_config:
    ca-cert-file: x509/client_ca_cert.pem
    tls-cert-file: x509/server2_cert.pem
    tls-key-file: x509/server2_key.pem
    tls-server-name: dubbogo.test.example.com

在正确敞开 TLS 之后,供给者会输出一条 “Server initialized the TLSConfig configuration” 日志,顾客会输出一条 “Client initialized the TLSConfig configuration” 日志。更具体的运用实例请参阅 tls 示例 [3]。

04 展望 2023

2022 年是极不简单的一年,感谢咱们的信赖,也十分感谢社区中每位同学的奉献。展望 2023 咱们将会继续打磨结构,在优先保证稳定性的前提下继续提高易用性,打造一流的 Go 言语微服务结构。

4.1 Dubbo 开源全体规划

Go 语言体系下的微服务框架选型:Dubbo-go

  • 官网与文档体会全面提高
  • Go、Node.js、Rust 等多言语系统建造
  • 全面提高全体可观测性
  • Dubbo Admin 一站式服务运维管控平台
  • Dubbo Mesh 走向老练
  • 提高 HTTP 开发体会,补全 Web 互通
  • 打造 gRPC over Dubbo 最佳实践
  • 完善的认证鉴权系统

4.2 面向 Go 开发者全面运用体会提高

Dubbo-go 根底功用建造已经较为完善,一起在最近几年中咱们继续在 dubbo-go-samples 目录完善示例代码 [4],可以协助用户愈加快速的上手项目。与此一起,Dubbo-go 文档内容还较为匮乏,代码示例只能让结构跑起来,但是这儿面的运用和完结细节还需要在文档中进一步被具体阐述,让用户知其然,更知其所以然。除了文档建造作业外,社区对开发者东西的建造作业高度重视,在 2023 年,咱们计划在 dubboctl 东西中集成更多命令,为用户供给快速创建微服务、支撑了 Hessian2 生成器、新建 Dubbo-go 项目等许多特性。在 2023 年咱们将会进一步提高文档和东西的建造作业,除了强大的功用之外,成为真正面向 Go 开发者的轻量、易用的结构。

参阅链接:

1、Dubbo-go-Mesh 敞开新一代 Go 微服务形态

2、baijiahao.baidu.com/s?id=175176…

3、github.com/apache/dubb…

4、github.com/apache/dubb…