Polaris 和 dubbogo 全面对接,让微服务更简单

作者:邓正威

背景概述

什么是 Polaris

Polaris 是腾讯开源的服务治理平台,致力于解决分布式和微服务架构中的服务管理、流量管理、配置管理、故障容错和可观测性问题,针对不同的技术栈和环境提供服务治理的标准方案和最佳实践。

 title=

什么是 dubbogo

dubbogo 是一款高性能 Go 语言微服务 RPC 框架,在 Dubbo 多语言生态中扮演重要角色,是编写 Go 语言微服务的最佳选择之一。开发者可以使用 dubbogo 框架高效地编写 RPC 服务,并支持与dubbogo  、gRPC 服务跨语言互通;并且 dubbogo 本身提供的丰富服务治理特性,可以实现诸如服务发现、负载均衡、流量调度等服务治理诉求。

 title=

为什么要对接

分布式和微服务架构中的服务管理、流量管理、配置管理、故障容错和可观测性问题,如何去解决、选用什么组件来解决、组件之间是否会存在冲突等等,相信已经让不少开发者难以招架。在 dubbogo 用户中,需要解决这些微服务架构中的问题,通常都会部署以下组件

  • Nacos(Zookeeper):解决服务管理、配置管理以及元数据管理
  • Sentinel:解决流量管理、故障容错
  • Prometheus、Skywalking:解决可观测性

可以发现,要解决这些问题不得不部署多个组件,并且每个组件都有各自的管控平台,数据联动性差,难以有一个全局的视角让用户可以很好的管理微服务。

Polaris 是一支持多语言多框架的云原生服务治理平台,具备服务管理、流量管理、故障容错、配置管理和可观测性五大功能,用户不需要在为选择什么组件而操心,直接在 Polaris 享受一站式服务治理平台所带来的便利。为此, Polaris 社区和 dubbogo 社区合作,将 Polaris 服务治理能力,与 dubbogo 框架相结合,便于 Go 应用开发者快速低门槛的进行微服务开发。

如何对接 Polaris

Polaris 有统一控制面和标准,数据面提供多语言sdk的实现给框架做集成。服务管理、流量管理、故障容错、配置管理和可观测性五大功能可直接通过 Polaris 的数据面直接接入,各个语言框架无需重复实现,统一了各个语言以及框架的服务治理能力。

因此,要完成 dubbo 与Polaris的集成,只需要使用 Polaris 提供的数据面 Polaris-Go SDK,通过 dubbogo 的 Extension 机制进行注入,无需额外进行服务治理逻辑的开发。

技术架构

Polaris 通过实现 dubbogo 相关 Extension 插件,完成了功能的注入,用户只需要在配置中进行功能开启即可使用,无需进行代码改造。

从用户数据流的维度,当用户在 dubbogo 中启用 Polaris 的服务治理能力后,业务流量实际处理流程如下:

 title=

从架构分层的维度,北极星 SDK,插件,与 dubbogo 之间通过以下方式进行整合:

  • 基于 Registry/ServiceDiscovery 的 dubbogo 扩展点,引入 Polaris 的服务注册能力

 title=

  • 基于 Registry/ServiceDiscovery 的 dubbogo 扩展点,引入 Polaris 的服务发现能力

 title=

  • 基于 PriorityRouter 的 dubbogo 扩展点,引入 Polaris 的动态路由能力

 title=

  • 基于 TpsLimiter 的 dubbogo 扩展点,引入 Polaris 的访问限流能力

 title=

如何使用

当前 dubbogo 与 Polaris 服务治理能力对接情况(基于 dubbogo v3.0.4-rc1 版本)

 title=

服务注册

当前 Polaris 已实现了 dubbogo 原生的服务注册扩展点,因此原本的 dubbogo 服务注册逻辑不需要进行任何调整,只需要在 dubbogo.yaml 配置文件中新增 protocol 为 polaris 的注册中心配置即可。

业务代码(dubbogo 原生使用方式)

func init() {
  config.SetProviderService(&UserProvider{})
  hessian.RegisterPOJO(&User{})
}

type UserProvider struct {}

func (u *UserProvider) GetUser(ctx context.Context, req *User) (*User, error) {
  rsp := User{"A001", "Alex Stocks", 18, time.Now()}
  return &rsp, nil
}

func main() {
  if err := config.Load(); err != nil {
    panic(err)
  }

  initSignal()
}

dubbogo.yaml 配置文件

dubbo:
  registries:
    polaris-1:
      protocol: polaris 
      address: ${北极星服务端IP}:8091

调整完 dubbogo.yam 配置文件后,启动服务,可以在北极星控制台直接观察到服务实例

 title=

服务发现

dubbogo 在进行服务调用时,会先通过 Polaris Registry 的 Extension 获取到服务的实例列表,然后转换为 dubbogo invoker,最终完成 dubbogo 服务调用。

当前 Polaris 已实现了 dubbogo 原生的服务发现扩展点,因此原本的 dubbogo 服务调用无需调整业务代码,仅需要在 dubbogo.yaml 中新增 protocol 为 polaris 的注册中心配置即可。

业务代码(dubbogo 原生使用方式)

func main() {
    var userProvider = &UserProvider{}
    config.SetConsumerService(userProvider)
    hessian.RegisterPOJO(&User{})
    if err := config.Load(); err != nil {
        panic(err)
    }

    user, err := userProvider.GetUser(context.TODO(), &User{Name: "Alex001"})
    if err != nil {
        panic(err)
    }
    logger.Infof("response result: %v\n", user)
}

dubbogo.yaml 配置

dubbo:
  registries:
    polaris-1:
      protocol: polaris 
      address: ${北极星服务端IP}:8091

动态路由

动态路由可以实现基于 dubbo 的请求消息内容来对请求调度到不同的实例分组,比如将带了某些 user 标签的请求调度到灰度分组。

当前支持针对 dubbo 消息的以下内容进行路由调度:

 title=

假定一个场景,希望 uid 为 user-1 的请求,路由到版本为 2.0.0 的实例上,其他则路由到版本为 1.0.0 的实例上,那可以为 dubbogo 服务设置两条路由规则。

注意:在使用 PolarisMesh 的动态路由能力时,需要先启用 PolarisMesh 在 dubbogo 中的注册发现功能

业务代码(dubbogo 原生使用方式)

func (s *Service) GetUser(uid string) {
  atta := make(map[string]interface{})
  atta["uid"] = uid
    // 通过这种方式往 attachement 传入路由条件
  reqContext := context.WithValue(context.Background(), constant.DubboCtxKey("attachment"), atta)
  for i := 0; i < 5; i++ {
    time.Sleep(200 * time.Millisecond)
    user, err := userProvider.GetUser(reqContext, &User{Name: "Alex001"})
    if err != nil {
      logger.Errorf("error: %v\n", err)
    }
    logger.Infof("response: %v\n", user)
  }
}

测试路由规则

 title=

兜底路由规则

 title=

访问限流

访问限流可以实现基于 dubbo 的请求消息内容来对请求进行访问限流,比如对 dubbogo 中的 GetUser 方法,对请求参数 Name 为 Alex 的请求进行限流,速率为 10/s。

当前支持针对 dubbo 消息的以下内容进行路由调度:

 title=

限流规则

 title=

在 Polaris 配置限流规则后,需要在 dubbogo 中启用 Polaris 的 TpsLimiter,具体开启配置参考如下

注意:在使用 PolarisMesh 的动态路由能力时,需要先启用 PolarisMesh 在 dubbogo 中的注册发现功能

业务代码

func (s *Service) Test() {
  var successCount, failCount int64
  for i := 0; i < 10; i++ {
    time.Sleep(50 * time.Millisecond)
      // 服务提供者会根据请求参数 User.Name 的值来进行限流
    if user, err := userProvider.GetUser(context.TODO(), &User{Name: "Alex03"}); err != nil {
      failCount++
      logger.Infof("error: %v\n", err)
    } else {
      successCount++
      logger.Infof("response: %v\n", user)
        }
  }
  logger.Infof("successCount=%v, failCount=%v\n", successCount, failCount)
}

dubbogo.yaml 配置文件

dubbo:
  ...
  provider:
    services:
      UserProvider:
        interface: org.apache.dubbo.UserProvider.Test
        tps.limiter: polaris-limit  # 配置 tps.limiter 为 polaris-limiter 即可

未来规划

当前 Polaris 的服务注册发现、动态路由、访问限流三大能力已经和 dubbogo 做了集成,后续 PolarisMesh 社区会继续和 dubbogo 社区进行合作,将 Polaris 的服务熔断、节点熔断、可观测性以及配置中心的能力融入到 dubbogo 中,让用户能够在 dubbogo 中使用 Polaris 一站式的服务治理功能。

除了能在 dubbogo上使用 Polaris 的一站式服务治理能力外,Polaris 社区还提供了 其他语言框架的接入,因此相关开发者也能够享受到 Polaris 一站式服务治理带来的技术红利。

附录

Polaris 项目:

https://github.com/polarismes...

dubbogo 项目:

https://github.com/apache/dub...

dubbogo polaris example:

https://github.com/apache/dub...

北极星服务注册文档:

https://polarismesh.cn/docs/%E4%BD%BF%E7%94%A8%E6%8C%87%E5%8D%97/%E6%8E%A7%E5%88%B6%E5%8F%B0%E4%BD%BF%E7%94%A8/%E6%B3%A8%E5%86%8C%E4%B8%AD%E5%BF%83/%E6%9C%8D%E5%8A%A1%E5%88%97%E8%A1%A8/

北极星访问限流文档:

https://polarismesh.cn/docs/%E4%BD%BF%E7%94%A8%E6%8C%87%E5%8D%97/%E6%8E%A7%E5%88%B6%E5%8F%B0%E4%BD%BF%E7%94%A8/%E6%9C%8D%E5%8A%A1%E7%BD%91%E6%A0%BC/%E8%AE%BF%E9%97%AE%E9%99%90%E6%B5%81/

北极星服务路由文档:

https://polarismesh.cn/docs/%E4%BD%BF%E7%94%A8%E6%8C%87%E5%8D%97/%E6%8E%A7%E5%88%B6%E5%8F%B0%E4%BD%BF%E7%94%A8/%E6%9C%8D%E5%8A%A1%E7%BD%91%E6%A0%BC/%E5%8A%A8%E6%80%81%E8%B7%AF%E7%94%B1/

作者:

邓正威:apache/dubbo-go committer

廖春涛(春少):PolarisMesh 社区 PMC,apache/dubbo-go committer

赵新(花名 于雨):dubbogo 社区负责人

微信或钉钉扫描下方对应二维码,立刻进群交流~

 title=


阿里巴巴云原生
关注云原生技术趋势,输出最优质云原生内容
957 声望
256 粉丝
0 条评论
推荐阅读
多层网关已成过去,网关多合一成潮流,网关改造正当时丨Higress 正式发布 1.0 版本
K8s 通过 Ingress / Gateway API 将网关标准化,逐步将安全网关、流量网关、微服务网关内聚,解决从单体到微服务到云原生多层网关的复杂度,合久必分,分久必合,多层网关已成过去,网关多合一成潮流,成为 K8s ...

阿里云云原生阅读 149

突破难关:Docker镜像和容器的区别以及构建的最佳实践
Docker 可谓是开启了容器化技术的新时代,现在无论大中小公司基本上都对容器化技术有不同程度的尝试,或是已经进行了大量容器化的改造。伴随着 Kubernetes 和 Cloud Native 等技术和理念的普及,也大大增加了业务...

张晋涛4阅读 1.1k

封面图
Apache APISIX 结合 Authing 实现集中式身份认证管理
Apache APISIX 是一个动态、实时、高性能的 API 网关,提供负载均衡、动态上游、灰度发布、服务熔断、身份认证、可观测性等丰富的流量管理功能。Apache APISIX 不仅支持插件动态变更和热插拔,而且拥有众多实用的...

API7_技术团队1阅读 2.5k

Kubernetes Gateway API 深入解读和落地指南
Kubernetes Gateway API 是 Kubernetes 1.18 版本引入的一种新的 API 规范,是 Kubernetes 官方正在开发的新的 API,Ingress 是 Kubernetes 已有的 API。Gateway API 会成为 Ingress 的下一代替代方案。Gateway A...

Rainbond2阅读 433

Apache APISIX 助力便利充电创领者小电,实现云原生方案
原文链接业务背景小电作为国内共享充电宝服务平台,目前还处于初创阶段。从运维体系、测试环境等方面来讲,当下产品的业务主要面临了以下几个问题:VM 传统模式部署,利用率低且不易扩展开发测试资源抢占多套独立...

API7_技术团队1阅读 1.6k

5大主流方案对比:MySQL千亿级数据线上平滑扩容实战
在项目初期,我们部署了三个数据库A、B、C,此时数据库的规模可以满足我们的业务需求。为了将数据做到平均分配,我们在Service服务层使用uid%3进行取模分片,从而将数据平均分配到三个数据库中。

码猿技术专栏2阅读 635

Higress GitHub star 突破 1k,来自社区开发者和用户的寄语
不知不觉间,Higress 从去年11 月云栖大会宣布开源,已经过去了 5 个月的时间。这期间,Higress 一共完成了 136 个 PR 的合并,发布了 9 个 Release,收获了 25 位社区 Contributor。在这里向 Higress 一路同行的...

阿里云开发者阅读 3.6k

957 声望
256 粉丝
宣传栏