乐趣区

关于阿里云:Go-语言体系下的微服务框架选型Dubbogo

作者简介:牛学蔚(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)奉献了全流程的优雅高低线能力。

Dubbo 经典的调用流程如上图所示,这外面蕴含了服务提供者(Provider)、服务消费者(Consumer)以及注册核心(Registry)三个要害组件,一个服务可能被调用,首先须要提供者筹备服务并对外裸露端口(步骤 0),而后提供者须要将调用信息注册到注册核心中(步骤 1),消费者则会通过异步订阅的形式获取最新的提供者数据(步骤 2),注册核心在有新数据后会被动推送给消费者(步骤 3),此时消费者曾经有本次调用的全副信息了,最初消费者发送调用申请(步骤 4),这样就实现了整个调用链路。

在单体利用中,上述逻辑十分清晰和简略,然而在大规模微服务集群中,这个逻辑的每一个细节都须要被认真斟酌后,能力保障高低线的过程中调用不出错。

优雅上线 的指标是解决服务上线调用报错的问题,次要针对微服务场景下的调用依赖问题。在 Dubbo 生态中,Service 示意一个服务,可能被裸露并被其余服务调用,Reference 示意援用,能够简略的了解为上游服务。一个典型调用构造如上图所示,该服务对外裸露一个接口,同时援用了上游的 N 个服务。该服务在上线的时候应该严格遵循以下流程,首先保障上游服务的援用被胜利初始化,之后再初始化 Service 对外裸露服务,最初再向注册核心注册服务。优雅上线相对来说逻辑比较简单,只须要严格遵循初始化过程的依赖关系就能保障上线过程中服务可能被失常调用。

优雅下线 是优雅高低线的难点,波及到了信号监听、反注册、期待已有申请实现调用等逻辑。在须要销毁容器的时候,kubelet 会向容器发送 SIGTERM 信号,Dubbo-go 会进入优雅下线流程,此时容器并不会立即被销毁。行将下线的提供者首先会执行反注册,即向注册核心中删除本人的信息,消费者能够通过订阅取得这个信息,这个过程须要肯定的工夫。换句话说,在消费者取得这个删除信息之前,流量还是有可能会流向该提供者,此时提供者应该回绝这部分申请。当然除了下线期间的新申请外,还有残留的来自上游的申请以及本人调用上游的申请,咱们别离为这两种状况设置一个计数器,当两个计数器都被清零时,能够认为该提供者是“洁净”的。Dubbo-go 的策略是回绝新申请,期待已放行的旧申请。最初,销毁协定并敞开监听,该容器就可能被平安的摘除。

在启动优雅高低线后,集群内无谬误申请,成功率放弃在 100%。

3.2 新一代柔性服务

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

柔性服务是一种更智能的负载平衡算法。传统负载平衡算法大多是基于消费者视角,它们独特的局限性是无奈依据服务提供者的以后状态动静调整分流策略,如 RR、hash 等算法。这些算法总是以尽可能偏心的概率调配流量,但在实践中偏心不等于负载平衡。

爬山算法是一种容量预估的算法,服务提供者须要将一些要害信息回传给消费者,比方时延、申请排队数量、预估容量等,消费者应用 P2C 算法抉择一个负载最低的作为本次申请的提供者。这些数据实效性要求十分高,如果这些数据是被动传递的,那么很难保障实效性,如果这些数据是被被动探测的,那么在一个大型集群下感知老本十分高。基于上述问题,咱们抉择了更可控的峰值干涉算法。

消费者局部中,咱们应用了改良版的 P2C 算法,采集的指标包含申请数(requests)、胜利数(accepts)、申请时延(rtt)。与原实现计划不同的是,该版本采纳了更正当的滑动窗口(SlidingWindowCounter)和指数挪动均匀(EMA)两种带有时序性的模块进行采集。

SlidingWindowCounter 会保留时长为统计周期 T 的数据,整个周期内的数据被宰割为若干个 Bucket,每个 Bucket 保留计数时长内的数据,以后所处的 Bucket 会随着工夫后退而向后挪动。

EMA 利用指数挪动均匀算法进行平滑、减小抖动,实用于统计时延型的指标,计算公式:

以下为一个客户端申请 3 个服务端的测试后果,3 个服务端配置不同,别离为 1 核 1GB、2 核 2GB、3 核 3GB。兰青色虚线代表开始应用上述负载平衡算法,能够看到开启前每个服务端接管到的申请数简直雷同,开启之后流量会依据提供者的规格进行智能分流。

提供者基于一个 AutoConcurrencyLimiter 组件限流,在申请达到时会判断已承受的申请是否超过最大处理量,如果超过了就会间接返回失败,限流导致的失败会影响负载平衡时的成功率,进而影响该实例被申请的可能性。与惯例限流组件不同的是,该组件会依据采样状况主动调整服务的最大处理量,不须要手动配置,而且减少了 CPU 负载作为启动开关,能够缩小被谬误限流的数量。

该组件次要关注 QPS、无负载时延(NoLoadLatency)和最大并发量(maxConcurrency),同时有一个用户指定的超参数 exploreRatio,示意摸索最大并发量的水平。更新规定是

  • 应用总申请数(蕴含未被采样的数据)计算 QPS,新 QPS 更大时间接替换,更小则应用指数挪动均匀进行平滑解决。
  • 应用采样数据计算均匀解决时延来估算 NoLoadLatency,均匀时延变小才会更新,并应用指数挪动均匀进行平滑解决。
  • 减少摸索因子启发式计算 maxConcurrency, 在采样时延或 QPS 在摸索容许的范畴之内时会逐渐增大 exploreRatio,否则用指数挪动均匀的形式进行平滑解决

最初能够提供给用户一个能够通过 cgroup v1 进行 CPU 限度,当以后提供者 CPU 负载过高的时候,会无条件回绝所有新申请。CPU 限度是一种最坏状况下的兜底策略。

以下为 1 个客户端申请一个服务端的测试后果,该测试随着时间推移,QPS 会逐渐增大,如蓝线所示。能够看到当 CPU 负载(橙线)过高时,有申请被限流(黄线),随后即便 QPS 再增大,CPU 负载、申请胜利数均已绝对稳固。

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 的服务治理能力后,业务流量理论解决流程如下:

以后 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、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、https://baijiahao.baidu.com/s?id=1751764790109427167&wfr=spid…

3、https://github.com/apache/dubbo-go-samples/tree/master/tls

4、https://github.com/apache/dubbo-go-samples

退出移动版