Go语言微服务框架重磅升级:dubbo-go v3.2.0 -alpha 版本预览

本文涉及的产品
注册配置 MSE Nacos/ZooKeeper,118元/月
服务治理 MSE Sentinel/OpenSergo,Agent数量 不受限
云原生网关 MSE Higress,422元/月
简介: 随着 Dubbo3 在云原生微服务方向的快速发展,Dubbo 的 go 语言实现迎来了 Dubbo3 版本以来最全面、最大幅度的一次升级,这次升级是全方位的,涉及 API、协议、流量管控、可观测能力等。

作者:王宇轩, Apache Dubbo Committer

随着 Dubbo3 在云原生微服务方向的快速发展,Dubbo 的 go 语言实现迎来了 Dubbo3 版本以来最全面、最大幅度的一次升级,这次升级是全方位的,涉及 API、协议、流量管控、可观测能力等。
总的来说,新版本的 dubbo-go:

  • 全面升级 Triple 协议,兼容 gRPC、标准 HTTP 客户端,提供简单明了的 API 用于编写 RPC server 与 client,解决组件间的基本通信问题。
  • 针对微服务场景,提供了完善的服务治理能力,这包括配置管理、可观测性、流量管控规则、生态集成与适配等的全面升级。


全新升级的 Triple 协议


基于 dubbo-go 实现的 Triple 协议,你可以轻松编写浏览器、gRPC 兼容的 RPC 服务,并让这些服务同时运行在 HTTP/1 和 HTTP/2 上。


如上图所示,你可以使用 "http+json" 的标准形式访问 dubbo-go 发布的后端 triple 服务,基于这一特性, 我们可以在 dubbo 客户端在浏览器页面、移动设备上访问后端服务,使用标准 cURL 工具访问服务,也可以让比如 Spring 体系的应用轻松的调通 Dubbo 服务。


由于 Triple 协议完全兼容 gRPC 协议,Dubbo 后端服务有可以直接调通标准的 gRPC 服务,它们之间可以无缝的互通,不论是 unary 还是 streaming 通信模式。


发布一个 triple rpc 服务

为了体验升级后的 triple 协议,我们接下来会尝试启动一个 dubbo-go server,并发布一个基于 triple 协议的服务。创建一个新的 server 并启动 server,它将在指定的端口监听 triple 协议请求。

func main() {
  srv, err := server.NewServer(
    server.WithServerProtocol(
      protocol.WithTriple(),
      protocol.WithPort(50051),
    ),
  )
  if err != nil {
    panic(err)
  }
  if err := greettriple.RegisterGreetServiceHandler(srv, &api.GreetTripleServer{}); err != nil {
    panic(err)
  }
  if err := srv.Serve(); err != nil {
    panic(err)
  }
}


cURL 访问服务Triple 服务启动完成之后,最简单方式是使用 HTTP/1.1 POST 访问服务,参数则作以标准 JSON 格式作为 HTTP 负载传递。如下是使用 cURL 命令的访问示例:

curl \
    --header "Content-Type: application/json" \
    --data '{"name": "Dubbo"}' \
    http://localhost:50051/greet.GreetService/Greet

Triple 协议的一项重大升级是支持标准 http 工具直接访问,通过 cURL 可以极大的降低 dubbo-go 服务的测试验证、前端接入成本。


简单明了的 API


Dubbo Go SDK 支持使用 IDL 或编程语言特有的方式定义服务,并提供一套轻量的 API 来发布或调用这些服务。在上一节的示例中,我们已经看到了部分 dubbo-go API 的使用方式,接下来,让我们更仔细全面的看一下新版本的 API 设计。


RPC Server 与 Client对于一些 RPC 通信的场景,开发者只需要使用 dubbo-go 编写一个最简单的 RPC server 或者 RPC client,这在新版本 dubbo-go 中只需要几行代码即可完成。通常,我们会使用 Protocol Buffer (IDL) 来定义一个 Dubbo 服务。

syntax = "proto3";
package greet;
message GreetRequest {
  string name = 1;
}
message GreetResponse {
  string greeting = 1;
}
service GreetService {
  rpc Greet(GreetRequest) returns (GreetResponse) {}
}

使用 Protocol Buffers Compiler 从 IDL 生成 stub 代码(篇幅关系,我们不在此展示,具体请参见官网 dubbo-go 快速开始)。接下来,我们实现 greettriple.GreeterClient 接口并提供自定义服务实现。

type GreeterServer struct {
}
func (s *GreeterServer) SayHello(ctx context.Context, in *greet.HelloRequest) (*greet.User, error) {
  return &greet.User{Name: "Hello " + in.Name, Id: "12345", Age: 21}, nil
}

以下是一个简单的 RPC server 示例,执行协议信息,并注册服务到 server 中:

func main() {
  srv, err := server.NewServer(
    server.WithServer_Protocol(
      protocol.WithTriple(),
      protocol.WithPort(50052),
    ),
  )
  if err != nil {
    panic(err)
  }
  if err := greettriple.RegisterGreetServiceHandler(srv, &api.GreetTripleServer{}); err != nil {
    panic(err)
  }
  if err := srv.Serve(); err != nil {
    panic(err)
  }
}

如前面 Triple 协议一节所述,你可以使用 cURL 直接测试以上 server 服务运行正常。与此同时,对应的 RPC client 示例如下:

func main() {
  // for the most brief RPC case
  cli, err := client.NewClient(
    client.WithURL("tri://127.0.0.1:50052"),
  )
  if err != nil {
    panic(err)
  }
  svc, err := greettriple.NewGreetService(cli)
  if err != nil {
    panic(err)
  }
  common.TestClient(svc)
}


微服务开发如果你正在开发微服务应用,那么除了 RPC 通信之外,你通常还需要为应用配置一些服务治理能力,比如 retistry 注册中心、配置中心、可观测能力等。以下展示了如何使用 dubbo-go 开发一个微服务应用。首先,创建一个代表微服务的应用 Server,将服务注册给它,添加注册中心等服务治理配置。

func main() {
  // configure global configurations and common modules
  ins, err := dubbo.NewInstance(
    dubbo.WithName("dubbo_test"),
    dubbo.WithRegistry(
      registry.WithZookeeper(),
      registry.WithAddress("127.0.0.1:2181"),
    ),
    dubbo.WithProtocol(
      protocol.WithTriple(),
      protocol.WithPort(50052),
    ),
  )
    // create a server with registry and protocol set above
  srv, err := ins.NewServer()
  if err != nil {
    panic(err)
  }
    // register a service to server
  if err := greettriple.RegisterGreetServiceHandler(srv, &api.GreetTripleServer{}); err != nil {
    panic(err)
  }
    // start the server
  if err := srv.Serve(); err != nil {
    panic(err)
  }
}

其中,Instance 是我们在新版本中引入的全局配置,你可以将所有微服务全局配置在这里进行初始化。这里,我们设置了微服务通信协议 protocol 和注册中心 registry,如以下代码片段所示:

ins, err := dubbo.NewInstance(
    dubbo.WithName("dubbo_test"),
    dubbo.WithRegistry(
        registry.WithZookeeper(),
        registry.WithAddress("127.0.0.1:2181"),
    ),
    dubbo.WithProtocol(
        protocol.WithTriple(),
        protocol.WithPort(50052),
    ),
)

接下来的操作就非常简单明了了,我们创建一个 server,将服务注册给它并启动,如下所示。如果有更多的服务,则可以依次注册到 server 后再启动。

// create a server with registry and protocol set above
srv, err := ins.NewServer()
// register a service to server
if err := greettriple.RegisterGreetServiceHandler(srv, &api.GreetTripleServer{}); err != nil {
    panic(err)
}
// start the server
if err := srv.Serve(); err != nil {
    panic(err)
}

以上就是一个微服务应用的基本开发过程,如果你的微服务应用要调用一些远程 Dubbo 服务,那么你只需要参照以下方式创建一个 client 就行了。

下面的代码示例创建了一个 client,紧接着生成了一个 GreetService 远程服务代理,之后,就可以像调用本地方法一样调用远端 Dubbo 服务了。client 将基于注册中心实现 server 实例的自动发现并自动为流量应用负载均衡策略。

func main() {
  // configure global configurations and common modules
  ins, err := dubbo.NewInstance(
    dubbo.WithName("dubbo_test"),
    dubbo.WithRegistry(
      registry.WithZookeeper(),
      registry.WithAddress("127.0.0.1:2181"),
    ),
  )
  // configure the params that only client layer cares
  cli, err := ins.NewClient()
  if err != nil {
    panic(err)
  }
  svc, err := greettriple.NewGreetService(cli)
  if err != nil {
    panic(err)
  }
  resp, err := svc.Greet(context.Background(), &greet.GreetRequest{Name: "triple"})
  if err != nil {
    return err
  }
  logger.Infof("TRIPLE unary call resp: %s", resp.Greeting)
}

企业级服务治理能力


动态配置
除了 API 模式之外,Dubbo-go 支持基于配置文件驱动的编码方式,这对于一些更大规模的微服务开发场景非常适用。在这种模式下,我们将 registry、protocol 等组件配置,甚至包括服务声明等都放在 dubbogo.yml 文件中,框架会在启动过程中完成配置文件加载。以下是一个基于 dubbogo.yml 的微服务应用的开发示例:

其中,server.go 定义如下:

func main() {
  greettriple.SetProviderService(&GreeterServiceImpl{})
  if err := dubbo.Load(); err != nil {
    panic(err)
  }
}

dubbogo.yml 示例内容如下:

dubbo:
  application: # 应用信息,服务启动后会将相关信息注册到注册中心,可被客户端从 url 中识别
    name: myApp
  registries:
    nacos:
      protocol: nacos # 注册中心选择 nacos 
      address: 127.0.0.1:8848 # nacos ip
      group: DEFAULT_GROUP # nacos group, 默认 DEFAULT_GROUP
      namespace: 9fb00abb-278d-42fc-96bf-e0151601e4a1 # nacos namespaceID, should be created before. 默认public
      username: abc
      password: abc
  protocols:
    dubbo:
      name: tri
      port: 20000
  provider:
    services:
      UserProviderWithCustomGroupAndVersion: # 接口三元组:接口名、版本号、分组。client 和 server 需要保持一致。
        interface: org.apache.dubbo.UserProvider.Test # 接口名必填
        version: myInterfaceVersion # 默认为空
        group: myInterfaceGroup # 默认为空

可以看到相比于之前的 API 编码方式,这里的 server.go 只有两行代码,dubbo.Load() 会完成所有配置的自动组装并启动相关组件,我们只需要在启动应用时指定 export DUBBO_GO_CONFIG_PATH=$ABSOLUTE_PATH/conf/dubbogo.yml 即可。


可观测性

自 3.2.0 版本开始,dubbo-go 重点升级了内置 metrics 指标采集能力,提供 RPC 调用(RT、QPS、调用量、请求成功数、请求失败数、并发请求数等)、注册中心、元数据中心、配置中心交互统计等丰富的内置采集埋点,支持多维度的指标聚合。


dubbo-go 内置 metrics 指标导出到 Prometheus + Grafana 体系的能力,以下是 dubbo-go v3.2.0 示例在 Grafana 的监控效果图,具体示例我们将与随后发布在 dubbo-go-samples/metrics。

流量管控
Dubbo 提供了丰富的流量管控策略:

  • 地址发现与负载均衡,地址发现支持服务实例动态上下线,负载均衡确保流量均匀的分布到每个实例上。
  • 基于路由规则的流量管控,路由规则对每次请求进行条件匹配,并将符合条件的请求路由到特定的地址子集。


服务发现保证调用方看到最新的提供方实例地址,服务发现机制依赖注册中心 (Zookeeper、Nacos、Istio 等) 实现。在消费端,Dubbo 提供了多种负载均衡策略,如随机负载均衡策略、一致性哈希负载、基于权重的轮询、最小活跃度优先、P2C 等。


Dubbo 的流量管控规则可以基于应用、服务、方法、参数等粒度精准的控制流量走向,根据请求的目标服务、方法以及请求体中的其他附加参数进行匹配,符合匹配条件的流量会进一步的按照特定规则转发到一个地址子集。以下是 dubbo-go 流量管控规则可以实现的一些具体管控场景示例:

  • 基于权重的比例流量分发
  • 灰度验证
  • 金丝雀发布
  • 按请求参数的路由
  • 同区域优先
  • 超时时间调整
  • 重试
  • 限流降级

以下是一个基于 dubbo-go 实现的全链路灰度示例:

以下是一个基于 dubbo-go 实现的按比例流量转发示例:

关于 dubbo-go 流量管控,我们以一个商城系统提供了一个完整的 demo 示例,感兴趣的读者可以参考详细信息:

  • 流量管控规则详情[1]
  • 流量管控商场示例解读[2]


生态

dubbo-go 总体上遵循框架内核+插件的的设计理念,左侧的框架内核定义了 dubbo-go 作为微服务框架的一些核心概念,右侧的插件部分则提供了核心概念扩展实现。

框架内核 可分为 4 个层次,从上到下依次为:

  • API 层dubbo-go 同时支持基于 IDL、interface/struct 的服务契约定义,兼顾跨语言与易用性诉求;支持基于纯 yaml 文件的微服务配置模式;提供了同步、异步、单次(unary)、流式(streaming) 等 RPC 通信与编码模型。
  • 服务治理层dubbo-go 内置了多维度的服务治理能力抽象,确保满足微服务开发与集群治理的核心诉求,这包括地址发现(Service Discovery)、负载均衡(Load Balancing)、可观测指标(Metrics)、流量管控(Traffic Management)、全链路追踪(Tracing)等。
  • RPC 协议层dubbo-go 实现的最核心的 RPC 协议是 - triple 协议,triple 可同时工作在 http1/2 之上 (支持 CURL 直接访问),兼容 gRPC;从设计上,dubbo-go 还提供了多协议发布服务的支持,你可以在一个进程内同时发布 triple、dubbo2、rest、jsonRPC 等多种不同通信协议的服务。
  • 传输层支持 HTTP1/2、TCP 传输层,兼顾性能与通用性,同时支持多种序列化方式。


插件体系极大的丰富了 dubbo-go 功能与生态,社区内置提供了大量的内置扩展实现,同时,开发者可以非常容易的根据需求增加扩展实现。以下是一些典型的插件定义:

  • Protocoldubbo-go 基于 protocol 插件内置提供了 triple、dubbo2、rest 等协议支持,通过扩展 protocol 可以为 dubbo-go 扩展更多协议。
  • Service Discovery支持 Nacos、Zookeeper、Polaris 等主流注册中心集成。
  • Traffic Managementdubbo-go 支持 Dubbo 体系定义的流量规则,可以实现在运行期动态的调整服务行为如超时时间、重试次数、限流参数等,通过控制流量分布可以实现 A/B 测试、金丝雀发布、多版本按比例流量分配、条件匹配路由、黑白名单等。
  • Metrics提供 RPC 调用(RT、QPS、调用量、请求成功数、请求失败数、并发请求数等)、注册中心、元数据中心、配置中心交互统计等丰富的内置采集埋点,支持多维度的指标聚合。
  • Logging提供通用的日志采集接口定义,内置 Zap、Logrus 支持。
  • Tracing提供分布式链路追踪能力,通过此插件扩展可接入 Zipkin、Jaeger、Skywalking 等链路追踪系统。


总结


dubbo-go 3.2.0 的首个 alpha 版本将于 11 月底发布,本文是发版前的抢先预览,感兴趣的读者也可以访问源码尝鲜:https://github.com/apache/dubbo-go/tree/feature-triple/protocol/triple/internal


接下来,我们将持续推进 3.2.0 版本迭代并计划与 2 月份发布正式稳定版本,详细 Roadmap 请关注项目仓库:https://github.com/apache/dubbo-go


社区期待 Go 语言相关开发者的加入,可搜索关注 “apachedubbo” 微信公众号并回复 “dubbogo” 接受邀请,加入官方社群组织。


电子书免费下载本书为 CoC Asia 2023(原ApacheCon) RPC & Service Mesh 专题分享实录,通过摘取 Community Over Code Asia 2023(原 ApacheCon Asia)的 RPC & Service Mesh专题的精彩内容,我们以 Apache Dubbo 为中心展开,给大家带来开源微服务技术方向发展、云原生微服务选型、企业实践分享的精彩内容!


相关链接:

[1] 流量管控规则详情

https://cn.dubbo.apache.org/zh-cn/overview/core-features/traffic/

[2] 流量管控商场示例解读

https://cn.dubbo.apache.org/zh-cn/overview/tasks/traffic-management/

相关实践学习
基于MSE实现微服务的全链路灰度
通过本场景的实验操作,您将了解并实现在线业务的微服务全链路灰度能力。
相关文章
|
7天前
|
JavaScript Java Go
探索Go语言在微服务架构中的优势
在微服务架构的浪潮中,Go语言以其简洁、高效和并发处理能力脱颖而出。本文将深入探讨Go语言在构建微服务时的性能优势,包括其在内存管理、网络编程、并发模型以及工具链支持方面的特点。通过对比其他流行语言,我们将揭示Go语言如何成为微服务架构中的一股清流。
|
1月前
|
XML JSON API
ServiceStack:不仅仅是一个高性能Web API和微服务框架,更是一站式解决方案——深入解析其多协议支持及简便开发流程,带您体验前所未有的.NET开发效率革命
【10月更文挑战第9天】ServiceStack 是一个高性能的 Web API 和微服务框架,支持 JSON、XML、CSV 等多种数据格式。它简化了 .NET 应用的开发流程,提供了直观的 RESTful 服务构建方式。ServiceStack 支持高并发请求和复杂业务逻辑,安装简单,通过 NuGet 包管理器即可快速集成。示例代码展示了如何创建一个返回当前日期的简单服务,包括定义请求和响应 DTO、实现服务逻辑、配置路由和宿主。ServiceStack 还支持 WebSocket、SignalR 等实时通信协议,具备自动验证、自动过滤器等丰富功能,适合快速搭建高性能、可扩展的服务端应用。
95 3
|
4天前
|
监控 Go API
Go语言在微服务架构中的应用实践
在微服务架构的浪潮中,Go语言以其简洁、高效和并发处理能力脱颖而出,成为构建微服务的理想选择。本文将探讨Go语言在微服务架构中的应用实践,包括Go语言的特性如何适应微服务架构的需求,以及在实际开发中如何利用Go语言的特性来提高服务的性能和可维护性。我们将通过一个具体的案例分析,展示Go语言在微服务开发中的优势,并讨论在实际应用中可能遇到的挑战和解决方案。
|
5天前
|
Go 数据处理 API
Go语言在微服务架构中的应用与优势
本文摘要采用问答形式,以期提供更直接的信息获取方式。 Q1: 为什么选择Go语言进行微服务开发? A1: Go语言的并发模型、简洁的语法和高效的编译速度使其成为微服务架构的理想选择。 Q2: Go语言在微服务架构中有哪些优势? A2: 主要优势包括高性能、高并发处理能力、简洁的代码和强大的标准库。 Q3: 文章将如何展示Go语言在微服务中的应用? A3: 通过对比其他语言和展示Go语言在实际项目中的应用案例,来说明其在微服务架构中的优势。
|
24天前
|
Cloud Native Go API
Go语言在微服务架构中的创新应用与实践
本文深入探讨了Go语言在构建高效、可扩展的微服务架构中的应用。Go语言以其轻量级协程(goroutine)和强大的并发处理能力,成为微服务开发的首选语言之一。通过实际案例分析,本文展示了如何利用Go语言的特性优化微服务的设计与实现,提高系统的响应速度和稳定性。文章还讨论了Go语言在微服务生态中的角色,以及面临的挑战和未来发展趋势。
|
25天前
|
运维 Go 开发者
Go语言在微服务架构中的应用与优势
本文深入探讨了Go语言在构建微服务架构中的独特优势和实际应用。通过分析Go语言的核心特性,如简洁的语法、高效的并发处理能力以及强大的标准库支持,我们揭示了为何Go成为开发高性能微服务的首选语言。文章还详细介绍了Go语言在微服务架构中的几个关键应用场景,包括服务间通信、容器化部署和自动化运维等,旨在为读者提供实用的技术指导和启发。
|
28天前
|
Dubbo Java 应用服务中间件
Dubbo学习圣经:从入门到精通 Dubbo3.0 + SpringCloud Alibaba 微服务基础框架
尼恩团队的15大技术圣经,旨在帮助开发者系统化、体系化地掌握核心技术,提升技术实力,从而在面试和工作中脱颖而出。本文介绍了如何使用Dubbo3.0与Spring Cloud Gateway进行整合,解决传统Dubbo架构缺乏HTTP入口的问题,实现高性能的微服务网关。
|
29天前
|
负载均衡 Go API
探索Go语言在微服务架构中的应用与优势
在这篇技术性文章中,我们将深入探讨Go语言(又称为Golang)在构建微服务架构时的独特优势。文章将通过对比分析Go语言与其他主流编程语言,展示Go在并发处理、性能优化、以及开发效率上的优势。同时,我们将通过一个实际的微服务案例,详细说明如何利用Go语言构建高效、可扩展的微服务系统。
|
1月前
|
安全 Go 云计算
探索Go语言在微服务架构中的应用与优势
在本文中,我们将深入探讨Go语言(又称为Golang)在构建微服务架构中的独特优势。文章将分析Go语言的并发模型、简洁的语法以及高效的编译速度,以及这些特性如何使其成为微服务架构的理想选择。我们将通过一个简单的微服务示例,展示Go语言在实际开发中的表现,并讨论其在性能和可维护性方面的优势。
|
30天前
|
消息中间件 监控 Go
Go语言在微服务架构中的优势与实践
【10月更文挑战第10天】Go语言在微服务架构中的优势与实践