You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@dubbo.apache.org by li...@apache.org on 2022/06/08 07:43:53 UTC
[dubbo-website] branch master updated: Ftr: add golang docs (#1099)
This is an automated email from the ASF dual-hosted git repository.
liujun pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/dubbo-website.git
The following commit(s) were added to refs/heads/master by this push:
new 67859affe2 Ftr: add golang docs (#1099)
67859affe2 is described below
commit 67859affe27ad384299fd80e1bfd0c0e5364743d
Author: Laurence <45...@users.noreply.github.com>
AuthorDate: Wed Jun 8 15:43:49 2022 +0800
Ftr: add golang docs (#1099)
---
content/zh/docs3-building/golang-sdk/_index.md | 3 +-
.../zh/docs3-building/golang-sdk/concept/_index.md | 19 +
.../golang-sdk/concept/config/_index.md | 7 +
.../golang-sdk/concept/config/basic_concept.md | 38 +
.../golang-sdk/concept/mesh/_index.md | 6 +
.../concept/mesh/proxyless_service_mesh.md | 111 +++
.../golang-sdk/concept/more/3.0_feature.md | 71 ++
.../golang-sdk/concept/more/_index.md | 6 +
.../golang-sdk/concept/more/app_and_interface.md | 65 ++
.../golang-sdk/concept/more/architecture.md | 19 +
.../golang-sdk/concept/rpc/_index.md | 6 +
.../golang-sdk/concept/rpc/generic.md | 155 ++++
.../golang-sdk/concept/rpc/multi_language.md | 20 +
.../golang-sdk/concept/rpc/protocol.md | 108 +++
.../concept/service_management/_index.md | 18 +
.../concept/service_management/adaptive_lb.md | 29 +
.../service_management/aop_and_extension.md | 110 +++
.../service_management/graceful_shutdown.md | 27 +
.../concept/service_management/registry.md | 89 +++
.../concept/service_management/visualization.md | 9 +
.../docs3-building/golang-sdk/quickstart/_index.md | 6 +
.../golang-sdk/quickstart/install.md | 47 ++
.../golang-sdk/quickstart/quickstart_triple.md | 122 +++
.../zh/docs3-building/golang-sdk/refer/_index.md | 5 +
.../golang-sdk/refer/compatible_version.md | 15 +
.../zh/docs3-building/golang-sdk/refer/config.md | 122 +++
.../zh/docs3-building/golang-sdk/refer/ecology.md | 46 ++
.../golang-sdk/refer/use_dubbogo_cli.md | 429 +++++++++++
.../zh/docs3-building/golang-sdk/samples/_index.md | 5 +
.../golang-sdk/samples/adaptive-service.md | 28 +
.../golang-sdk/samples/config-center-dynamic.md | 152 ++++
.../golang-sdk/samples/custom-filter.md | 116 +++
.../golang-sdk/samples/custom-logger.md | 88 +++
.../golang-sdk/samples/exception_response.md | 117 +++
.../docs3-building/golang-sdk/samples/generic.md | 102 +++
.../golang-sdk/samples/go_java_interactive.md | 848 +++++++++++++++++++++
.../docs3-building/golang-sdk/samples/grpc_cli.md | 21 +
.../golang-sdk/samples/mesh_router.md | 144 ++++
.../docs3-building/golang-sdk/samples/metrics.md | 207 +++++
.../golang-sdk/samples/pixiu-nacos-triple.md | 71 ++
.../docs3-building/golang-sdk/samples/registry.md | 110 +++
.../golang-sdk/samples/samples_repo.md | 173 +++++
.../golang-sdk/samples/service-discovery.md | 56 ++
.../golang-sdk/samples/start-check.md | 29 +
.../docs3-building/golang-sdk/sourcecode/_index.md | 6 +
.../golang-sdk/sourcecode/protocol.md | 24 +
.../golang-sdk/sourcecode/registry.md | 52 ++
.../zh/docs3-building/golang-sdk/tasks/_index.md | 6 +
.../docs3-building/golang-sdk/tasks/cli/_index.md | 5 +
.../golang-sdk/tasks/cli/app_template.md | 86 +++
.../golang-sdk/tasks/config/_index.md | 5 +
.../golang-sdk/tasks/config/config_api.md | 100 +++
.../golang-sdk/tasks/config/remote_config.md | 47 ++
.../golang-sdk/tasks/debug/_index.md | 5 +
.../golang-sdk/tasks/debug/dubbogo_cli.md | 147 ++++
.../golang-sdk/tasks/debug/grpc_cli.md | 77 ++
.../docs3-building/golang-sdk/tasks/mesh/_index.md | 5 +
.../zh/docs3-building/golang-sdk/tasks/mesh/app.md | 426 +++++++++++
.../docs3-building/golang-sdk/tasks/mesh/build.md | 32 +
.../golang-sdk/tasks/mesh/ingress.md | 8 +
.../golang-sdk/tasks/mesh/traffic_management.md | 417 ++++++++++
.../golang-sdk/tasks/pixiu/_index.md | 5 +
.../golang-sdk/tasks/pixiu/http_triple.md | 79 ++
.../golang-sdk/tasks/registry/_index.md | 5 +
.../golang-sdk/tasks/registry/multi_registry.md | 118 +++
.../golang-sdk/tasks/registry/nacos.md | 80 ++
.../docs3-building/golang-sdk/tasks/rpc/_index.md | 5 +
.../golang-sdk/tasks/rpc/call_grpc.md | 16 +
.../golang-sdk/tasks/rpc/call_java.md | 847 ++++++++++++++++++++
.../golang-sdk/tasks/rpc/choose_protocol.md | 233 ++++++
.../docs3-building/golang-sdk/tasks/rpc/context.md | 16 +
.../docs3-building/golang-sdk/tasks/rpc/error.md | 124 +++
.../docs3-building/golang-sdk/tasks/rpc/generic.md | 102 +++
.../golang-sdk/tasks/rpc/rpc_metrics.md | 51 ++
.../docs3-building/golang-sdk/tasks/rpc/timeout.md | 61 ++
.../golang-sdk/tasks/rpc/tps_limiter.md | 105 +++
.../golang-sdk/tasks/service_management/_index.md | 5 +
.../golang-sdk/tasks/service_management/aop.md | 67 ++
.../tasks/service_management/graceful_shutdown.md | 10 +
.../golang-sdk/tasks/visualization/_index.md | 5 +
.../golang-sdk/tasks/visualization/logger.md | 6 +
.../golang-sdk/tasks/visualization/metrics.md | 8 +
.../tasks/visualization/opentelementry.md | 6 +
.../golang-sdk/tasks/visualization/tracing.md | 5 +
84 files changed, 7380 insertions(+), 2 deletions(-)
diff --git a/content/zh/docs3-building/golang-sdk/_index.md b/content/zh/docs3-building/golang-sdk/_index.md
index 937577306c..25fcee02c3 100755
--- a/content/zh/docs3-building/golang-sdk/_index.md
+++ b/content/zh/docs3-building/golang-sdk/_index.md
@@ -4,5 +4,4 @@ type: docs
title: "Golang"
linkTitle: "Golang"
weight: 3
----
-
+---
\ No newline at end of file
diff --git a/content/zh/docs3-building/golang-sdk/concept/_index.md b/content/zh/docs3-building/golang-sdk/concept/_index.md
new file mode 100644
index 0000000000..271fab6929
--- /dev/null
+++ b/content/zh/docs3-building/golang-sdk/concept/_index.md
@@ -0,0 +1,19 @@
+---
+type: docs
+title: "概念"
+linkTitle: "概念"
+description: Dubbo-go 框架概念
+weight: 1
+---
+
+# Dubbo-go 概念
+
+
+
+Apache/Dubbo-go ([github.com/apache/dubbo-go](https://github.com/apache/dubbo-go))
+
+是一款分布式 RPC 框架;是 Apache/Dubbo 的 Go 语言实现。旨在为开发者提供便利的微服务应用开发体验。
+
+Dubbo-go 架起 Java 和 Go 语言之间的桥梁,与 gRPC/Dubbo/SpringCloud 生态互联互通,依赖 Go 语言生态发掘云原生时代的技术红利。
+
+
diff --git a/content/zh/docs3-building/golang-sdk/concept/config/_index.md b/content/zh/docs3-building/golang-sdk/concept/config/_index.md
new file mode 100644
index 0000000000..49da993239
--- /dev/null
+++ b/content/zh/docs3-building/golang-sdk/concept/config/_index.md
@@ -0,0 +1,7 @@
+---
+type: docs
+title: "配置"
+linkTitle: "配置"
+weight: 4
+---
+
diff --git a/content/zh/docs3-building/golang-sdk/concept/config/basic_concept.md b/content/zh/docs3-building/golang-sdk/concept/config/basic_concept.md
new file mode 100644
index 0000000000..41c96867af
--- /dev/null
+++ b/content/zh/docs3-building/golang-sdk/concept/config/basic_concept.md
@@ -0,0 +1,38 @@
+---
+type: docs
+title: 配置基本概念
+keywords: 配置基本概念
+---
+
+## 1. 框架配置
+
+Dubbo-go 框架需要依赖配置进行启动。配置中包含了开发者希望使用框架的各种能力。
+
+### 配置格式
+
+yaml
+
+### 配置路径
+
+默认从 `../conf/dubbogo.yaml ` 加载框架配置
+
+可通过指定环境变量:DUBBO_GO_CONFIG_PATH=$(your_config_path)/dubbogo.yaml 来修改配置文件路径。
+
+### 配置根结构
+
+位于 [dubbo.apache.org/dubbo-go/v3/config/root_config.go: RootConfig](https://github.com/apache/dubbo-go/blob/e00cf8d6fb2be3cd9c6e42cc3d6efa54e10229d3/config/root_config.go#L50)
+
+框架加载时,任何形式的配置都会被解析成 RootConfig,在 RootConfig.Init 方法中加载。
+
+## 2. 配置API
+
+开发者可以使用 API 的形式构建配置,从而启动框架。该方法较适合 dubbo-go 作为第三方组件引入的情况。
+
+详情见任务[【配置API】](../../tasks/config/config_api/)
+
+## 3. 配置中心
+
+开发者可以将配置放置在配置中心,从而便于配置的管理和修改。
+
+详情见任务[【远程配置】](../../tasks/config/remote_config/)
+
diff --git a/content/zh/docs3-building/golang-sdk/concept/mesh/_index.md b/content/zh/docs3-building/golang-sdk/concept/mesh/_index.md
new file mode 100644
index 0000000000..767ee41ac2
--- /dev/null
+++ b/content/zh/docs3-building/golang-sdk/concept/mesh/_index.md
@@ -0,0 +1,6 @@
+---
+type: docs
+title: "服务网格"
+linkTitle: "服务网格"
+weight: 5
+---
\ No newline at end of file
diff --git a/content/zh/docs3-building/golang-sdk/concept/mesh/proxyless_service_mesh.md b/content/zh/docs3-building/golang-sdk/concept/mesh/proxyless_service_mesh.md
new file mode 100644
index 0000000000..63d7cd64e1
--- /dev/null
+++ b/content/zh/docs3-building/golang-sdk/concept/mesh/proxyless_service_mesh.md
@@ -0,0 +1,111 @@
+---
+type: docs
+title: 无代理服务网格
+keywords: 无代理服务网格
+---
+
+## 1. 什么是 Proxyless Service-Mesh (无代理服务网格) ?
+
+### 1.1 Service Mesh 简析
+
+Istio 是当今最流行的开源服务网格。它由控制平面和数据平面构成,其架构如下,图片摘自 [istio官网](istio.io)
+
+
+
+位于图中下半部分的控制平面负责配置、服务信息、证书等资源的下发。位于上半部分的数据平面关注业务之间的通信流量;传统服务网格通过代理的方式拦截所有的业务网络流量,代理需要感知到控制平面下发的配置资源,从而按照要求控制网络流量的走向。
+
+在 Istiod 环境中,其控制平面是一个名为 istiod 的进程,网络代理是 envoy 。istiod 通过监听 K8S 资源 例如Service、Endpoint 等,获取服务信息,并将这些资源统一通过 XDS 协议下发给位于数据平面的网络代理。envoy 是一个独立的进程,以 sidecar(边车)的形式伴随业务应用 Pod 运行,他与应用进程共用同一个主机网络,并通过修改路由表的方式,劫持业务应用的网络流量。
+
+Service Mesh 可以解决微服务场景下的众多问题,随着集群规模的扩大与业务复杂度的增长,基于原生 k8s 的容器编排方案将会难以应付,开发人员不得不面对巨大的服务治理挑战。而 Service Mesh 很好地解决了这一问题,它将服务治理需求封装在了控制平面与代理中,业务开发人员只需要关注于业务逻辑。在应用部署之后,只需要运维人员通过修改配置,即可实现例如故障恢复、负载均衡、灰度发布等功能,这极大地提高了研发和迭代效率。
+
+Istio 的 sidecar 通过容器注入的形式伴随业务应用进程的整个生命周期,对于业务应用是毫无侵入的,这解决了业务应用可迁移、多语言、基础架构耦合等问题。但这也带来了高资源消耗、请求时延增长的问题。
+
+Service 为服务治理提供了一个很好的思路,将基础架构与业务逻辑解耦,让应用开发人员只需关注业务。另一方面,由于 sidecar 的弊端,我们可以考虑使用 sdk 的形式,来替代 sidecar 支撑起数据平面。
+
+### 1.2 Proxyless Service-Mesh
+
+无代理服务网格,是近几年提出的一个新的概念,isito、gRPC、brpc 等开源社区都在这一方向进行了探索和实践。无代理服务网格框架以 SDK 的形式被业务应用引入,负责服务之间的通信、治理。来自控制平面的配置直接下发至服务框架,由服务框架代替上述 sidecar 的功能。
+
+
+
+服务框架(SDK)的主要能力可以概括为以下三点:
+
+1. 对接控制平面,监听配置资源。
+2. 对接应用,为开发者提供方便的接口。
+3. 对接网络,根据资源变动,响应流量规则。
+
+### 1.3 Proxyless 的优缺点
+
+优点:
+
+- 性能:无代理模式的网络调用为点对点的直接通信,网络时延会比代理模式小很多。
+- 稳定性:proxyless 的模式是单进程,拓扑简单,便于调试,稳定性高。
+- 框架集成:市面上已有众多 sdk 模式的服务框架,切换至 mesh 后便与复用框架已有能力
+- 资源消耗:没有 sidecar,资源消耗低
+
+缺点:
+
+- 语言绑定:需要开发多种语言的 sdk
+- 可迁移性低:无法通过切换 sidecar 的形式来无侵入地升级基础设施。
+
+总体来讲,Proxyless 架构以其高性能、高稳定性的特点,更适合与生产环境使用。
+
+## 2. Dubbo-go 与 Proxyless Service-Mesh
+
+### 2.1 Dubbo-go 在 Proxyless Service-Mesh 场景的设计
+
+#### 服务注册发现
+
+Dubbo-go 本身拥有可扩展的服务注册发现能力,我们为 service mesh 场景适配了注册中心的实现。开发人员可以将 dubbo-go 应用的信息注册在 istiod 控制平面上。客户端应用可以查询已经注册的接口数据,完成服务发现过程。
+
+
+
+1. 开发人员使用 dubbogo-cli 工具创建应用模板,发布 Deployment / Service 到集群中。
+2. 服务端拉取全量 CDS 和 EDS ,比对本机IP,拿到当前应用的的主机名。并将本应用的所有接口名到主机名的映射,注册在Istiod上面。
+3. 客户端从 istiod 拉取全量接口名到主机名的映射,缓存在本地。当需要发起调用时,查询本地缓存,将接口名转换为主机名,再通过CDS 和 EDS 拉取到当前 cluster 所对应的全量端点。
+4. 全量端点经过 Dubbo-go 内置的 Mesh Router,筛选出最终的端点子集,并按照配置的负载均衡策略进行请求。
+
+开发人员全程只需要关注接口即可,完全无需关心主机名和端口信息。即服务端开发者只需要实现pb接口,使用框架暴露出来;客户端开发者只需要引入pb接口,直接发起调用即可。
+
+#### 流量治理
+
+Dubbo-go 拥有路由能力,通过 xds 协议客户端从 istiod 订阅路由配置,并实时更新至本地路由规则,从而实现服务的管理。Dubbo-go 兼容 istio 生态的流量治理规则,可以通过配置 Virtual Service 和 Destination Rule,将打标的流量路由至指定子集,也可以在灰度发布、切流等场景进行更深入地使用。
+
+#### 云原生脚手架
+
+dubbogo-cli 是 Apach/dubbo-go 生态的子项目,为开发者提供便利的应用模板创建、工具安装、接口调试等功能,以提高用户的研发效率。
+
+详情可以参阅 [【dubbogo-cli 工具】](../../refer/use_dubbogo_cli/)
+
+## 3. Dubbo-go-Mesh 的优势
+
+### 3.1 接口级服务发现
+
+前文介绍到了通过接口级服务注册发现的优势,即开发人员无需关心下游主机名和端口号,只需要引入接口存根,或实现接口,通过框架启动即可。
+
+### 3.2 高性能
+
+我们在 k8s 集群内部署 istio 环境,分别测试了 sidecar 模式的 gRPC 服务调用和 Proxyless 模式的 dubbo-go 应用服务调用。发现 proxyless 在请求耗时方面比 sidecar 模式少一个数量级,即性能提升十倍左右。
+
+### 3.3 跨生态
+
+Dubbo-go 是一个横跨多个生态的服务框架。
+
+- mesh 生态
+
+ 开发人员可以使用 Dubbo-go 进行应用开发的同时,使用 istio 生态所提供的强大能力。
+
+- gRPC 生态
+
+ - Dubbo-go 支持与 gRPC 服务互通,HTTP2 协议栈。
+ - Dubbo-go 默认使用 pb 序列化方式,高性能。
+
+- Dubbo 生态
+
+ - 多语言优势,可以实现 go-java 应用互通。
+ - 兼容 pixiu 网关,方便地进行服务的暴露和协议转换。
+ - 使用 Dubbo-go 生态组件。
+
+## 4. 任务
+
+您可以跟随[【Dubbo-go Mesh 任务】](../../tasks/mesh/build/)来体验 Dubbo-go 服务网格能力。
diff --git a/content/zh/docs3-building/golang-sdk/concept/more/3.0_feature.md b/content/zh/docs3-building/golang-sdk/concept/more/3.0_feature.md
new file mode 100644
index 0000000000..f17fd2da2e
--- /dev/null
+++ b/content/zh/docs3-building/golang-sdk/concept/more/3.0_feature.md
@@ -0,0 +1,71 @@
+---
+type: docs
+title: dubbo-go 3.0 新特性
+keywords: dubbo-go 3.0 新特性
+---
+
+
+
+## 1. Triple 协议
+
+### 1.1 概述
+
+
+
+- 通信层面
+
+ Triple 协议,也称为Dubbo3协议,是基于HTTP2 + gRPC协议,增加特定字段和逻辑的扩展协议,保证了和**原生gRPC协议互通**。在此基础之上,Triple 新协议将更原生地支持 **Dubbo 服务治理能力**。并支持**流式RPC调用**。
+
+ 简单来说,可以理解为 Triple = gRPC + Dubbo
+
+- 序列化
+
+ Triple 协议使用高效的**PB序列化方式**,并在此基础之上增加序列化协议的**可扩展支持**。
+
+- 用户开发习惯:
+
+ Triple 服务在开发前需要**预定义.proto文件**,对于习惯在编码前先定义IDL的Go语言开发者带来便捷。不同于符合java编程习惯的,定义JavaClassName用于描述接口的 Dubbo-go 1.x版本。
+
+- 跨语言互通性:
+
+ 可与 Dubbo-Java 实现**跨语言互通**。
+
+
+## 2. 应用级服务发现
+
+### 2.1 简介
+
+
+
+在服务注册阶段,服务端实例将应用级别的注册信息,主要包含从应用名到实例IP的映射注册到注册中心。在服务发现阶段,客户端实例,通过注册中心获取到需要请求的服务实例IP。进入服务自省阶段,服务自省过程为通过应用信息获取接口信息的过程。如上图,包含两种模式:
+
+1. remote模式:通过元数据中心(例如 zk )获取应用到接口元数据的映射
+2. local模式:直接通过服务端获取应用到接口元数据的映射(通过 Dubbo 协议针对 Metadata Service 发起 RPC 调用)
+
+经过服务自省后,客户端正式向对应实例发起调用。这样做最明显的好处是减少了注册中心的数据量,即注册中心只保存了应用级别的数据。
+
+用户在使用 Dubbo-go 3.0的应用级服务发现能力时,可以仿照示例,直接在配置文件中配置服务自省模式和元数据中心信息,引入依赖,开启应用级别服务发现。
+
+### 2.2 应用级服务发现介绍文章
+
+[应用级服务发现解析](https://baijiahao.baidu.com/s?id=1669266413887039723&wfr=spider&for=pc)
+
+## 3. Mesh 路由规则
+
+用户可定义路由文件:
+
+virtual_service.yaml
+
+
+
+以及 dist_rule.yml
+
+
+
+框架可根据路由文件针对特定的请求进行流量转发。
+
+## 4. 相关文章
+
+阿里云官方介绍文章:[《Dubbo 3.0 - 开启下一代云原生微服务》](https://developer.aliyun.com/article/770964?utm_content=g_1000175535)
+
+
diff --git a/content/zh/docs3-building/golang-sdk/concept/more/_index.md b/content/zh/docs3-building/golang-sdk/concept/more/_index.md
new file mode 100644
index 0000000000..bfc7f560b7
--- /dev/null
+++ b/content/zh/docs3-building/golang-sdk/concept/more/_index.md
@@ -0,0 +1,6 @@
+---
+type: docs
+title: "更多"
+linkTitle: "更多"
+weight: 6
+---
diff --git a/content/zh/docs3-building/golang-sdk/concept/more/app_and_interface.md b/content/zh/docs3-building/golang-sdk/concept/more/app_and_interface.md
new file mode 100644
index 0000000000..a887becc4c
--- /dev/null
+++ b/content/zh/docs3-building/golang-sdk/concept/more/app_and_interface.md
@@ -0,0 +1,65 @@
+---
+type: docs
+title: Dubbo的应用和接口
+keywords: 基本概念
+description: Dubbo的应用和接口
+---
+
+## Dubbogo 服务层级
+
+Dubbogo 服务层级为两个级别:分别是应用级别(App Level)和接口级别(Interface Level),该服务分层与**框架配置**结构息息相关。
+
+如下图所示,可以看到,应用级别的组件以浅红色标注,接口级别的组件以浅蓝色标注:
+
+
+
+## 1. 应用级别组件
+
+应用级别组件的特点:被当前应用的所有接口级别组件共用。
+
+应用级别的主要组件如下:
+
+- 应用信息模块
+
+ 包含应用维度相关信息,包括应用名、版本号、数据上报方式等
+
+- Consumer 模块
+
+ Consumer 模块负责客户端相关信息,包括一个或多个引用(Reference)结构,以及超时、客户端过滤器(consumer filter)等相关信息。
+
+- Provider 模块
+
+ Provider 模块负责服务端相关信息,包括一个或多个服务(Service)结构、服务端过滤器(provider filter)等相关信息。
+
+- 注册中心(Registry)模块
+
+ 注册中心模块负责定义好所要使用的一系列注册中心,例如框架支持的ZK、Nacos、ETCD等中间件。应用级别的注册模块只负责声明,由接口级别的组件进行引用,引用时以用户自定义的注册中心ID(registryID) 作为索引。
+
+- 协议(Protocol)模块
+
+ 协议模块只存在于服务端。
+
+ 协议模块关心服务的暴露信息,例如协议名、服务监听IP、端口号等信息。协议模块属于应用级别,只负责声明,由接口级别的组件进行引用,引用时以用户自定义的协议ID(protocolID) 作为索引。
+
+- 元数据中心模块
+
+ 元数据中心类似于注册中心模块,负责声明框架需要使用的元数据中心,从而将元数据成功上报。
+
+- 配置中心模块
+- 路由模块
+- 日志模块
+- 监控模块
+
+## 2. 接口级别组件
+
+- 服务(Service)模块
+
+ 服务模块被使用于任何暴露的服务,声明接口暴露所需的信息,包括例如接口名、协议、序列化方式等,负责单个服务接口的暴露。
+
+- 引用(Reference)模块
+
+ 饮用模块被使用于需要调用的远程服务的客户端,其声明了需要请求接口所需的信息,包括例如接口名、协议、序列化方式等、负责特定协议的抽象,参与客户端的生成。
+
+## 3. 说明
+
+暴露的服务是接口级别的,一个用户定义的 Provider Struct/一个用户定义的Consumer Struct,对应一个Service/Reference 模块,一个应用可以同时存在Consumer 模块和 Provider 模块,因此可以同时存在多个Service/Reference 模块。
diff --git a/content/zh/docs3-building/golang-sdk/concept/more/architecture.md b/content/zh/docs3-building/golang-sdk/concept/more/architecture.md
new file mode 100644
index 0000000000..7324429b6e
--- /dev/null
+++ b/content/zh/docs3-building/golang-sdk/concept/more/architecture.md
@@ -0,0 +1,19 @@
+---
+type: docs
+title: 架构
+keywords: 架构
+---
+
+
+
+#### 节点说明
+
+* `Registry` : dubbo-go中负责服务注册与发现的注册中心
+* `Consumer` : 调用远程服务的服务消费方
+* `Provider` : 暴露服务的服务提供方
+
+#### 过程说明
+* `0. register` : 当服务提供方在启动的时候,会自动将自己的服务注册到注册中心
+* `1. subscribe` : 服务消费方会在启动的时候,向注册中心订阅自己所需要的服务
+* `2. notify` : 注册中心返回服务注册的信息给到服务消费方,当订阅的服务发生变更,会推送变更的数据给到消费方
+* `3. invoke` : 服务消费者根据从注册中心获得的服务地址,经过负载均衡算法选出一个合适的服务地址发起请求
diff --git a/content/zh/docs3-building/golang-sdk/concept/rpc/_index.md b/content/zh/docs3-building/golang-sdk/concept/rpc/_index.md
new file mode 100644
index 0000000000..7d75142a42
--- /dev/null
+++ b/content/zh/docs3-building/golang-sdk/concept/rpc/_index.md
@@ -0,0 +1,6 @@
+---
+type: docs
+title: "RPC"
+linkTitle: "RPC"
+weight: 2
+---
diff --git a/content/zh/docs3-building/golang-sdk/concept/rpc/generic.md b/content/zh/docs3-building/golang-sdk/concept/rpc/generic.md
new file mode 100644
index 0000000000..fda27231b5
--- /dev/null
+++ b/content/zh/docs3-building/golang-sdk/concept/rpc/generic.md
@@ -0,0 +1,155 @@
+---
+type: docs
+title: 泛化调用
+keywords: 泛化调用
+---
+
+泛化调用是一种 Dubbo-Go 的特殊调用方式,它允许中间节点在没有接口信息的情况下传递调用信息,常被用于测试、网关的场景下。泛化调用支持 Dubbo 和 Triple 协议,但是目前序列化方案只支持 Hessian。
+
+## 背景
+
+为了便于理解,这篇文档中以网关使用场景介绍泛化调用。我们先来考虑普通调用(非泛化调用)。下图包含了 consumer 和 provider 两个关键角色(后文中用 endpoint 代表一个 consumer 或一个 provider),各自都有一份关于 org.apache.dubbo.sample.User 接口的定义。假定在调用行为中需要使用 org.apache.dubbo.sample.User 接口。
+
+
+
+RPC 需要借助网络介质传输,因此数据不能以 go struct 形式传输,而必须以二进制形式传输。这就要求 consumer 端在传输前,需要将实现 org.apache.dubbo.sample.User 接口的结构体序列化为二进制格式。同样的,对于 provider 端,需要将二进制数据反序列化为结构体信息。**总之,普通调用要求接口信息在每一个 endpoint 必须有相同的定义,这样才能保证数据序列化和反序列化的结果与预期一致**。
+
+在网关场景下,网关不可能存储全部接口定义。比如一个网关需要转发 100 个服务调用,每个服务需要的接口数量为 10 个,普通调用要求把 1000 个(100 * 10)接口定义提前全部存储在网关内,这显然是难以做到的。所以有没有一种方式可以既不需要提前存储接口定义,又能正确转发调用呢?答案是肯定的,这就是使用泛化调用的原因。
+
+## 原理
+
+泛化调用本质上就是把复杂结构转化为通用结构,这里说的通用结构是指 map、string 等,网关是可以顺利解析并传递这些通用结构的。
+
+
+
+目前,Dubbo-go v3 只支持 Map 泛化方式(default)。我们以 User 接口为例,其定义如下所示。
+
+```go
+// definition
+type User struct {
+ ID string
+ Name string
+ Age int32
+}
+
+func (u *User) JavaClassName() string {
+ return "org.apache.dubbo.sample.User"
+}
+```
+
+假定调用一个服务需要一个 user 作为入参,其定义如下所示。
+
+```go
+// an instance of the User
+user := &User{
+ ID: "1",
+ Name: "Zhangsan",
+ Age: 20,
+}
+```
+
+那么在使用 Map 泛化方式下,user 会被自动转换为 Map 格式,如下所示。
+
+```go
+usermap := map[interface{}]interface{} {
+ "iD": "1",
+ "name": "zhangsan",
+ "age": 20,
+ "class": "org.apache.dubbo.sample.User",
+}
+```
+
+需要注意的是:
+
+- Map 泛化方式会自动将首字母小写,即 ID 会被转换为 iD,如果需要对齐 Dubbo-Java 请考虑将 ID 改为 Id;
+- 在 Map 中会自动插入 class 字段,用于标识原有接口类。
+
+## 使用
+
+泛化调用对 provider 端是透明的,即 provider 端不需要任何显式配置就可以正确处理泛化请求。
+
+### 基于 Dubbo URL 泛化调用
+
+基于 Filter 泛化调用对 consumer 是透明的,典型应用场景是网关。这种方式需要要求 Dubbo URL 中包含泛化调用标识,如下所示。
+
+```plain
+dubbo://127.0.0.1:20000/org.apache.dubbo.sample.UserProvider?generic=true&...
+```
+
+这个 Dubbo URL 表达的语意是:
+
+- RPC 协议为 dubbo;
+- org.apache.dubbo.sample.UserProvider 接口位于 127.0.0.1:20000;
+- 使用泛化调用(generic=true)。
+
+Consumer 端的 Filter 会自动根据 Dubbo URL 携带的配置自动将普通调用转化为泛化调用,但是需要注意的是,在这种方式下响应结果是以泛化格式返回,不会自动转化为相应的对象。举个例子,在 map 泛化方式下,如果需要返回 User 类,那么 consumer 获得的相应是一个 User 类对应的 map。
+
+### 手动泛化调用
+
+手动泛化调用发起的请求不经过 filter,所以需要 consumer 端显式地发起泛化调用,典型应用场景是测试。在 [dubbo-go-samples](https://github.com/apache/dubbo-go-samples/tree/3.0/generic) 中,为了便于测试都是采用手动调用的方式。
+
+泛化调用不需要创建配置文件(dubbogo.yaml),但是需要在代码中手动配置注册中心、reference 等信息,初始化方法被封装到 newRefConf 方法中,如下所示。
+
+```go
+func newRefConf(appName, iface, protocol string) config.ReferenceConfig {
+ registryConfig := &config.RegistryConfig{
+ Protocol: "zookeeper",
+ Address: "127.0.0.1:2181",
+ }
+
+ refConf := config.ReferenceConfig{
+ InterfaceName: iface,
+ Cluster: "failover",
+ Registry: []string{"zk"},
+ Protocol: protocol,
+ Generic: "true",
+ }
+
+ rootConfig := config.NewRootConfig(config.WithRootRegistryConfig("zk", registryConfig))
+ _ = rootConfig.Init()
+ _ = refConf.Init(rootConfig)
+ refConf.GenericLoad(appName)
+
+ return refConf
+}
+```
+
+newRefConf 方法接收三个参数,分别是:
+
+- appName: 应用名;
+- iface: 服务接口名;
+- protocol: RPC 协议,目前只支持 dubbo 和 tri(triple 协议)。
+
+在上述方法中,为了保持函数简单性,把注册中心设置为一个固定值,即使用在 127.0.0.1:2181 的 ZooKeeper 作为注册中心,在实践中可以根据实际情况自由定制。
+
+我们可以很容易的获取一个 ReferenceConfig 实例,暂时命名为 refConf。
+
+```go
+refConf := newRefConf("example.dubbo.io", "org.apache.dubbo.sample.UserProvider", "tri")
+```
+
+接着我们可以对 org.apache.dubbo.sample.UserProvider 服务的 GetUser 方法发起泛化调用。
+
+```go
+resp, err := refConf.
+ GetRPCService().(*generic.GenericService).
+ Invoke(
+ context.TODO(),
+ "GetUser",
+ []string{"java.lang.String"},
+ []hessian.Object{"A003"},
+ )
+```
+
+GenericService 的 Invoke 方法接收四个参数,分别是:
+
+- context;
+- 方法名: 在这个例子中表示调用 GetUser 方法;
+- 参数类型: GetUser 方法接收一个 string 类型的参数,如果目标方法接收多个参数,可以写为 `[]string{"type1", "type2", ...}`,如果目前方法是无参的,则需要填入一个空数组 `[]string{}`;
+- 实参: 写法同参数类型,如果是无参函数,依然要填入一个空数组 `[]hessian.Object{}` 占位。
+
+注意:在目前版本中,无参调用会出现崩溃问题。
+
+相关阅读:[【Dubbo-go 服务代理模型】](https://blog.csdn.net/weixin_39860915/article/details/122738548)
+
+相关任务[【泛化调用】](../../tasks/rpc/generic/)
diff --git a/content/zh/docs3-building/golang-sdk/concept/rpc/multi_language.md b/content/zh/docs3-building/golang-sdk/concept/rpc/multi_language.md
new file mode 100644
index 0000000000..2d3cb0bc83
--- /dev/null
+++ b/content/zh/docs3-building/golang-sdk/concept/rpc/multi_language.md
@@ -0,0 +1,20 @@
+---
+type: docs
+title: 多语言 RPC
+keywords: 多语言 RPC
+---
+
+
+
+
+## 跨语言调用
+
+随着微服务场景的大范围应用,多语言场景越来越普遍,开发人员更愿意使用更适合的语言,来实现一个复杂系统的不同模块。例如使用 C 来编写网关,使用 Go 来编写 K8S 资源 operator,使用 Java 来编写业务应用。语言与场景并不是绑定的,企业往往可以结合自身发展的技术栈、开发人员的专长,来选型合适的语言。
+
+在多语言场景中,跨语言调用能力就显得十分重要。
+
+跨语言能力本质上是 [【网络协议】](./protocol.htlm) 提供的能力。如何方便地让用户使用需要的网络协议、针对合适的跨语言场景进行开发、享受 Dubbo 生态的服务治理能力,是 Dubbo-go 服务框架所关心的。
+
+## 跨生态
+
+Dubbo-go 服务框架提供了跨生态的能力,开发人员可以使用 Dubbo-go 以及其[生态项目](../../ecology/ecology/)建立 HTTP/前端服务、Dubbo/Spring 应用、gRPC 生态应用之间的联系。
diff --git a/content/zh/docs3-building/golang-sdk/concept/rpc/protocol.md b/content/zh/docs3-building/golang-sdk/concept/rpc/protocol.md
new file mode 100644
index 0000000000..3f62c693e7
--- /dev/null
+++ b/content/zh/docs3-building/golang-sdk/concept/rpc/protocol.md
@@ -0,0 +1,108 @@
+---
+type: docs
+title: 网络协议
+---
+
+## 1. RPC 服务框架与网络协议
+
+网络协议在 RPC 场景十分重要,在微服务场景下,服务进程之间的通信依赖可以连通的网络,以及client与server 端保持一致的网络协议。网络协议是一个抽象的概念,站在 Dubbo-go 应用开发的角度,不妨把我们关注的协议分为三个维度来讨论。
+
+### 1.1 打解包协议
+
+Dubbo-go 服务框架内置的打解包协议都是基于 TCP/IP 协议栈的,在此基础之上,封装/引入了多种协议,例如 Triple(dubbo3)、Dubbo、gRPC。
+
+这一类协议重点关注 TCP 报文的封装和拆解过程,保证点对点的可靠通信。
+
+在 dubbo-go 生态中,支持多种网络往往值得这一类协议。
+
+
+
+### 1.2 序列化协议
+
+序列化协议负责将内存中的对象以特定格式序列化为二进制流。一些主流的序列化库有:具有较好可读性、应用广泛的 json 序列化方式;较高压缩效率,性能较好的 protobuf 序列化方式;适配与 Java 语言的 hessian2 序列化方式等。Dubbo-go 内置了这三种序列化方式
+
+序列化协议是需要开发者在业务开发过程中关注的,序列化协议往往需要特定的对象标注:
+
+一个由 protoc-gen-go 生成的 protobuf 序列对象的例子:
+
+```protobuf
+type HelloRequest struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
+}
+```
+
+一个可与 java 服务互通的 hessian2 序列化对象
+
+```go
+type HelloRequest struct {
+ Name string `hessian:"name"`
+}
+
+func (u *HelloRequest) JavaClassName() string {
+ return "org.apache.dubbo.sample.User"
+}
+```
+
+序列化协议与打解包协议的关系
+
+- 一种打解包协议可以适配于多种序列化协议支持:例如,您可以使用 dubbogo 的 triple 协议来传递 hessian序列化参数与 Dubbo-java 服务框架互通;传递 pb 序列化参数与原生 gRPC 服务互通;通过实现接口来自定义您的希望的序列化方式例如 json,从而传递具有较强可读性的参数。
+
+### 1.3 接口协议
+
+接口协议,是由业务开发人员开发并且维护的协议,用于描述服务接口的信息。例如接口名、方法、参数类型。
+
+以 Triple/gRPC 为例,开发人员可以使用插件,从 proto 文件中定义的接口生成存根(.pb.go 文件),存根文件内包含接口所有信息,及接口协议。
+
+在编写服务时,客户端和服务端同时引入相同的接口,即可保证客户端发起针对特定接口和方法的调用,能被服务端正确识别和响应。
+
+一个由 proto 编写的接口描述文件:
+
+```protobuf
+syntax = "proto3";
+package api;
+
+option go_package = "./;api";
+
+// The greeting service definition.
+service Greeter {
+ // Sends a greeting
+ rpc SayHello (HelloRequest) returns (User) {}
+ // Sends a greeting via stream
+ rpc SayHelloStream (stream HelloRequest) returns (stream User) {}
+}
+
+// The request message containing the user's name.
+message HelloRequest {
+ string name = 1;
+}
+
+// The response message containing the greetings
+message User {
+ string name = 1;
+ string id = 2;
+ int32 age = 3;
+}
+```
+
+接口协议与序列化协议的关系
+
+- 接口协议是抽象的概念,一种接口协议可以使用多种接口描述语言来编写,并且可以转化成多种序列化协议对象。
+
+## 2. Dubbo-go 支持的网络协议
+
+Dubbo-go 支持的网络协议和序列化方式如下:
+
+| 协议 | 协议名 (用于配置) | 序列化方式 | 默认序列化方式 |
+| --------------- | ----------------- | :------------------------: | -------------- |
+| Triple 【推荐】 | tri | pb/hessian2/msgpack/自定义 | pb |
+| Dubbo | dubbo | hessian2 | hessian2 |
+| gRPC | grpc | pb | pb |
+| jsonRPC | jsonrpc | json | json |
+
+
+
+相关阅读:[【Dubbo-go 服务代理模型】](https://developer.aliyun.com/article/878252)
diff --git a/content/zh/docs3-building/golang-sdk/concept/service_management/_index.md b/content/zh/docs3-building/golang-sdk/concept/service_management/_index.md
new file mode 100644
index 0000000000..941fb97441
--- /dev/null
+++ b/content/zh/docs3-building/golang-sdk/concept/service_management/_index.md
@@ -0,0 +1,18 @@
+---
+type: docs
+title: "服务治理"
+linkTitle: "服务治理"
+weight: 3
+---
+
+# Dubbo-go 概念
+
+
+
+Apache/Dubbo-go ([github.com/apache/dubbo-go](https://github.com/apache/dubbo-go))
+
+是一款分布式 RPC 框架;是 Apache/Dubbo 的 Go 语言实现。旨在为开发者提供便利的微服务应用开发体验。
+
+Dubbo-go 架起 Java 和 Go 语言之间的桥梁,与 gRPC/Dubbo/SpringCloud 生态互联互通,依赖 Go 语言生态发掘云原生时代的技术红利。
+
+
diff --git a/content/zh/docs3-building/golang-sdk/concept/service_management/adaptive_lb.md b/content/zh/docs3-building/golang-sdk/concept/service_management/adaptive_lb.md
new file mode 100644
index 0000000000..c273ac1921
--- /dev/null
+++ b/content/zh/docs3-building/golang-sdk/concept/service_management/adaptive_lb.md
@@ -0,0 +1,29 @@
+---
+type: docs
+title: 柔性负载均衡
+keywords: 柔性负载均衡
+description: 柔性负载均衡
+---
+
+# 柔性负载均衡
+
+
+
+柔性服务是一种去中心化的智能负载均衡组件,同时也是 Dubbo-go 3.0 版本中重磅新特性之一。柔性服务尚处于早期实验阶段,该特性将在后续版本中持续优化,与 Dubbo 社区共同探索出一套适合微服务场景的最佳实践。
+
+传统的负载均衡算法是由随机节点、RoundRobin 等算法实现,他们的局限性在于不知道当前服务提供者的负载情况,算法总是以尽可能公平的概率调用不同的服务提供者。在实践中,公平不等于高性能,集群服务性能还与服务负载、任务复杂度等多因素相关。为解决传统负载均衡算法的不足,Dubbo-go 在 3.0 版本中引入了柔性服务,实现了容量动态评估和分流功能。
+
+容量评估是柔性服务的核心,它能动态评估服务端容量水平。在容量评估的过程中,两个核心指标是 TPS 和响应时间,要平衡系统利用率和系统性能两者之间的关系,使整体处于最佳的状态。
+
+- TPS 从服务提供者的角度反映系统利用率。在系统压力未饱和前,请求数越大则系统利用率越高,但是进一步加大请求量直至系统过饱和后,出现过载的问题,导致整体效率呈下降趋势。
+- 响应时间是从服务调用者的角度反映系统性能。在系统压力未饱和前,响应时间与请求数成线性增长的关系,但是进一步加大请求量直至系统过饱和后,响应时间与请求数成指数级增长。
+
+
+
+
+柔性服务则在调用过程中收集
+
+在 Dubbo-go 3.0 版本中,支持服务柔性负载均衡。在微服务场景下,客户端会在调用过程中收集该服务下游 server 实例的硬件资源消耗情况,通过容量评估与筛选策略,选择最合适的下游实例进行调用,从而提升系统整体的性能。
+
+服务柔性将在之后的迭代中持续优化,追求与 Dubbo 社区共同探索出最佳实践。
+
diff --git a/content/zh/docs3-building/golang-sdk/concept/service_management/aop_and_extension.md b/content/zh/docs3-building/golang-sdk/concept/service_management/aop_and_extension.md
new file mode 100644
index 0000000000..0cfad72de0
--- /dev/null
+++ b/content/zh/docs3-building/golang-sdk/concept/service_management/aop_and_extension.md
@@ -0,0 +1,110 @@
+---
+type: docs
+title: AOP 与可扩展机制
+keywords: AOP 与可扩展机制
+description: AOP 与可扩展机制
+---
+
+# 组件加载与可扩展性
+
+## 1. extension 模块与 init 方法
+
+### 1.1 接口与实现
+
+golang 中的一个接口往往伴随多个实现类,dubbo-go 提供了针对接口实现类的可插拔可扩展机制。降低模块之间的耦合性,方便开发者引入、自定义组件。
+
+### 1.2 golang 中的 init 方法
+
+init 方法作为 golang 中特殊的方法,用户引入一组模块后,会在程序启动时率先执行这些模块内的init 方法,进行加载逻辑,该方法是dubbogo注册扩展组件的重要方式。
+
+### 1.3 extension 模块
+
+在框架源码中,有一个特殊的模块: common/extension ,这一模块负责缓存所有可扩展组件的实现。
+
+以负载均衡模块为例:common/extension/loadbalance.go
+
+```go
+package extension
+
+import (
+ "dubbo.apache.org/dubbo-go/v3/cluster/loadbalance"
+)
+
+var loadbalances = make(map[string]func() loadbalance.LoadBalance)
+
+// SetLoadbalance sets the loadbalance extension with @name
+// For example: random/round_robin/consistent_hash/least_active/...
+func SetLoadbalance(name string, fcn func() loadbalance.LoadBalance) {
+ loadbalances[name] = fcn
+}
+
+// GetLoadbalance finds the loadbalance extension with @name
+func GetLoadbalance(name string) loadbalance.LoadBalance {
+ if loadbalances[name] == nil {
+ panic("loadbalance for " + name + " is not existing, make sure you have import the package.")
+ }
+
+ return loadbalances[name]()
+}
+```
+
+该模块包含Get 方法和Set方法。Get 返回实例化的 LoadBalance 接口,Set 方法用于注册工厂函数,map 用于缓存工厂函数。
+
+当用户引入 _ "dubbo.apache.org/dubbo-go/v3/cluster/loadbalance/random" 时,将会加载对应模块的init函数,调用 Set 方法注册唯一key和工厂函数和到上述map中。
+
+cluster/loadbalance/random/loadbalance.go
+
+```go
+package random
+
+import (
+ "math/rand"
+)
+
+import (
+ "dubbo.apache.org/dubbo-go/v3/cluster/loadbalance"
+ "dubbo.apache.org/dubbo-go/v3/common/constant"
+ "dubbo.apache.org/dubbo-go/v3/common/extension"
+ "dubbo.apache.org/dubbo-go/v3/protocol"
+)
+
+func init() {
+ extension.SetLoadbalance(constant.LoadBalanceKeyRandom, NewRandomLoadBalance)
+}
+```
+
+至此,当所有init方法执行完毕,可以通过 extension 模块 Get 方法来获取实例化对象。
+
+### 1.4 imports 模块
+
+dubbogo 将所有内置的模块全部放置在 imports/imports.go 内,用户在使用框架时,需要引入该模块,从而使用框架提供的基础能力。
+
+```go
+import (
+ _ "dubbo.apache.org/dubbo-go/v3/imports"
+)
+```
+
+## 2. 组件加载流程
+
+1. 用户在代码中引入 _ "dubbo.apache.org/dubbo-go/v3/imports"
+
+2. 程序启动,init 函数被依次执行,注册工厂函数/实例化对象到 extension 模块。
+
+3. 框架启动,加载配置,配置中获取需要加载的模块key,根据key获取实例化对象。
+
+ 用户也可以手动调用 extension 的 Get 方法,获取实例化对象并直接使用。
+
+## 3. 自定义组件
+
+在上述介绍的基础之上,开发人员可以效仿内置模块,编写自定义扩展组件。
+
+可参考任务[【自定义服务调用中间件】](../../tasks/service_management/aop/),该例子以Filter 接口为例,基于面向切面编程的思路,提供给用户介入调用链路进行过滤的能力。
+
+## 4. 面向切面编程的设计(AOP)
+
+在 Dubbo-go 服务框架中,许多接口是基于 AOP 的思路进行设计的。例如 Invoker、Filter、LoadBalance、Router。
+
+这些接口的多种实现往往组成一组调用链,单个实现类只处理自己所关注的逻辑。
+
+相关阅读:[【AOP wikipedia】](https://en.wikipedia.org/wiki/Aspect-oriented_programming)
diff --git a/content/zh/docs3-building/golang-sdk/concept/service_management/graceful_shutdown.md b/content/zh/docs3-building/golang-sdk/concept/service_management/graceful_shutdown.md
new file mode 100644
index 0000000000..c81119c609
--- /dev/null
+++ b/content/zh/docs3-building/golang-sdk/concept/service_management/graceful_shutdown.md
@@ -0,0 +1,27 @@
+---
+type: docs
+title: 优雅上下线
+keywords: 优雅上下线
+description: 优雅上下线
+---
+
+# 优雅上下线
+
+## 简介
+
+在稳定生产的过程中,容器调度完全由 k8s 管控,微服务治理完全由服务框架或者运维人员进行维护和管理。而在发布新版本,或者阔缩容的场景下,会终止旧的容器实例,并使用新的容器实例进行替换,对于承载高流量的线上生产环境,这个替换过程的衔接如果不合理,将在短时间内造成大量的错误请求,触发报警甚至影响正常业务。对于体量较大的厂家,发布过程出现问题所造成的损失会是巨大的。
+
+因此,优雅上下线的诉求被提出。这要求服务框架在拥有稳定服务调用能力,传统服务治理能力的基础之上,应当提供服务上下线过程中稳定的保障,从而减少运维成本,提高应用稳定性。
+
+## 期望效果
+
+理想状态下优雅上下线的效果,是在一个承载大量流量的分布式系统内,所有组件实例都可以随意地扩容、缩容、滚动更新,在这种情况下需要保证更新过程中稳定的 tps 和 rt,保证不因为应用的上下线造成请求错误。
+
+ ## 使用方式
+
+Dubbo-go 应用默认开启优雅上下线能力。
+
+相关阅读:[【Dubbo-go 优雅上下线的设计与实践】](https://developer.aliyun.com/article/860775)
+
+
+
diff --git a/content/zh/docs3-building/golang-sdk/concept/service_management/registry.md b/content/zh/docs3-building/golang-sdk/concept/service_management/registry.md
new file mode 100644
index 0000000000..2fd427840c
--- /dev/null
+++ b/content/zh/docs3-building/golang-sdk/concept/service_management/registry.md
@@ -0,0 +1,89 @@
+---
+type: docs
+title: 服务注册发现
+keywords: 服务注册发现
+description: 服务注册发现
+---
+
+# 服务注册发现
+
+## 1. Dubbo 的注册中心
+
+注册中心在 RPC 场景下负责保存服务端应用的信息。
+
+服务端注册接口信息和到自身地址到注册中心,客户端从注册中心读取和订阅需要调用的地址列表。整个架构如图所示:
+
+
+
+关于 Dubbo 服务发现细节,详情可参考 [Dubbo 官网的概念介绍](https://dubbo.apache.org/zh/docs/concepts/service-discovery/)
+
+## 2. 概念
+
+Dubbo 生态中,服务发现有以下主要概念:
+
+- 应用 Application
+
+ 应用是一个 dubbo 服务进程,对应一个应用名。
+
+- 接口(服务)
+
+ 接口是一个 RPC 接口类,例如一个通过 proto 定义的 Service,再例如一个 Java Interface 类。一个 dubbo 进程可以包含多个服务/接口。
+
+- 方法
+
+ 方法在接口中定义,一个接口可以包含多个方法。
+
+- 参数列表
+
+ 参数列表在方法中定义。由于 Java 支持重载,一个方法可以包含多个参数列表。对于 Go 是一对一的关系。
+
+- 注册信息
+
+ 在“接口级服务发现”的场景下,注册信息主要包含应用名、接口列表、元数据信息、以及服务端的IP地址等。以 URL 的形式保存在注册中心,供客户端发起调用前查询。
+
+ 在“应用级服务发现”的场景下,注册信息只包含应用名、应用名到接口的映射等少量应用级别的信息,接口级别的信息作为元数据保存在元数据中心。
+
+- 元数据
+
+ 元数据指接口信息,例如接口名、包含的方法、方法对应的参数、序列化方式、协议等等信息。
+
+- 注册中心
+
+ 注册中心用于保存服务端的信息。
+
+- 元数据中心
+
+ 元数据中心用于保存服务端的元数据信息,在“应用级服务发现”场景中,作为“服务自省”阶段的依赖。
+
+Dubbo-go 最的服务网格能力,引入以下几个概念
+
+- 主机名
+
+ 主机名当前应用在 k8s 上注册的 Service 名。其他应用可以通过主机名访问本应用实例。
+
+- 端点
+
+ 端点包含实例的 IP 地址、端口。
+
+- 集群
+
+ 集群 ID 保存了从{主机名、集群子集名、端口}
+
+ 集群保存集群 ID 到所有其包含端点的映射关系。
+
+- 服务网格元数据
+
+ 服务网格元数据是接口名到主机名到映射,用于客户端查询所需接口的主机名信息。
+
+## 3. Dubbo-go 支持的注册中心类型
+
+Dubbo-go 支持的注册中心类型如下:
+
+| 注册中心 | 注册中心名(用于配置) |
+| --------- | ---------------------- |
+| Zookeeper | zookeeper |
+| Nacos | nacos |
+| Etcd | etcd |
+| Consul | consul |
+
+相关阅读:[【应用级服务发现解析】](https://developer.aliyun.com/article/764173)
diff --git a/content/zh/docs3-building/golang-sdk/concept/service_management/visualization.md b/content/zh/docs3-building/golang-sdk/concept/service_management/visualization.md
new file mode 100644
index 0000000000..99445c5a78
--- /dev/null
+++ b/content/zh/docs3-building/golang-sdk/concept/service_management/visualization.md
@@ -0,0 +1,9 @@
+---
+type: docs
+title: 可视化
+keywords: 可视化
+description: 可视化
+---
+
+# 可视化
+
diff --git a/content/zh/docs3-building/golang-sdk/quickstart/_index.md b/content/zh/docs3-building/golang-sdk/quickstart/_index.md
new file mode 100644
index 0000000000..0250d7b27e
--- /dev/null
+++ b/content/zh/docs3-building/golang-sdk/quickstart/_index.md
@@ -0,0 +1,6 @@
+---
+type: docs
+title: "快速开始"
+linkTitle: "快速开始"
+weight: 1
+---
diff --git a/content/zh/docs3-building/golang-sdk/quickstart/install.md b/content/zh/docs3-building/golang-sdk/quickstart/install.md
new file mode 100644
index 0000000000..75c75725a3
--- /dev/null
+++ b/content/zh/docs3-building/golang-sdk/quickstart/install.md
@@ -0,0 +1,47 @@
+---
+type: docs
+title: 安装 Dubbo-go 开发环境
+weight: 1
+---
+## 1. 安装Go语言环境
+
+建议使用最新版 go 1.17
+
+go version >= go 1.15
+
+[【Go 语言官网下载地址】](https://golang.google.cn/)
+
+将 $GOPATH/bin 加入环境变量
+
+## 2 安装序列化工具protoc
+
+[【protoc 下载地址】](https://github.com/protocolbuffers/protobuf/releases)
+
+## 3 安装 dubbogo-cli 以及相关插件
+
+执行以下指令安装dubbogo-cli 至 $GOPATH/bin
+
+```bash
+$ export GOPROXY="https://goproxy.cn"
+$ go install github.com/dubbogo/dubbogo-cli@latest
+$ dubbogo-cli
+hello
+```
+
+安装依赖的工具插件
+
+```bash
+$ dubbogo-cli install all
+```
+
+确保上述安装的工具位于在系统环境变量内
+
+```bash
+$ protoc --version
+libprotoc 3.14.0
+$ protoc-gen-go --version
+protoc-gen-go v1.26.0
+$ protoc-gen-go-triple --version
+protoc-gen-go-triple 1.0.8
+```
+
diff --git a/content/zh/docs3-building/golang-sdk/quickstart/quickstart_triple.md b/content/zh/docs3-building/golang-sdk/quickstart/quickstart_triple.md
new file mode 100644
index 0000000000..124546948f
--- /dev/null
+++ b/content/zh/docs3-building/golang-sdk/quickstart/quickstart_triple.md
@@ -0,0 +1,122 @@
+---
+type: docs
+title: 完成一次 RPC 调用
+weight: 2
+---
+
+
+## 1. 生成 Demo 项目
+
+使用安装好的 dubbogo-cli 工具,创建demo工程。
+
+```bash
+$ mkdir quickstart
+$ cd quickstart
+$ dubbogo-cli newDemo .
+$ tree .
+.
+├── api
+│ ├── samples_api.pb.go
+│ ├── samples_api.proto
+│ └── samples_api_triple.pb.go
+├── go-client
+│ ├── cmd
+│ │ └── client.go
+│ └── conf
+│ └── dubbogo.yaml
+├── go-server
+│ ├── cmd
+│ │ └── server.go
+│ └── conf
+│ └── dubbogo.yaml
+└── go.mod
+```
+
+可看到生成的项目中包含一个 client 项目和一个 server 项目,以及相关的配置文件。
+
+### 1.1 查看接口描述文件 helloworld.proto
+
+```protobuf
+syntax = "proto3";
+package api;
+
+option go_package = "./;api";
+
+// The greeting service definition.
+service Greeter {
+ // Sends a greeting
+ rpc SayHello (HelloRequest) returns (User) {}
+ // Sends a greeting via stream
+ rpc SayHelloStream (stream HelloRequest) returns (stream User) {}
+}
+
+// The request message containing the user's name.
+message HelloRequest {
+ string name = 1;
+}
+
+// The response message containing the greetings
+message User {
+ string name = 1;
+ string id = 2;
+ int32 age = 3;
+}
+```
+
+demo项目中,默认生成了一个接口描述文件,接口服务名为 api.Greeter, 包含两个 RPC 方法,入参为 HelloRequest,返回值为 User,两个方法分别为普通 RPC 方法和 Streaming 类型 RPC 方法。
+
+### 1.2 (*可选) 使用安装好的编译工具编译 pb 接口
+
+```bash
+$ cd api
+$ protoc --go_out=. --go-triple_out=. ./samples_api.proto
+```
+
+参数意义:`--go_out=.` 使用上述安装的 `protoc-gen-go` 插件,生成文件到当前目录,`--go-triple_out=.`使用上述安装的 `protoc-gen-go-triple` 插件,生成文件到当前目录。
+
+执行该指令后,会生成两个文件,分别是helloworld.pb (包含 proto 结构) 和 helloworld_triple.pb.go (包含 triple 协议接口)。
+
+在 demo 工程中,预先生成好了这两个文件,修改 .proto 文件后重新执行命令生成,即可覆盖。
+
+## 2. 开启一次RPC调用
+
+项目根目录执行
+
+```
+$ go mod tidy
+```
+
+拉取到最新的框架依赖:
+
+```go
+module helloworld
+
+go 1.17
+
+require (
+ dubbo.apache.org/dubbo-go/v3 v3.0.1
+ github.com/dubbogo/grpc-go v1.42.9
+ github.com/dubbogo/triple v1.1.8
+ google.golang.org/protobuf v1.27.1
+)
+
+require (
+ ...
+)
+
+```
+
+先后启动服务端和客户端: 开启两个终端,在 go-server/cmd 和 go-client/cmd 文件夹下分别执行 `go run .` , 可在客户端看到输出:
+
+```shell
+client response result: name:"Hello laurence" id:"12345" age:21
+```
+
+获得调用结果成功
+
+## 3. 更多
+
+细心的读者可以发现,以上例子编写的的服务端可以接受来自客户端的普通RPC、流式RPC调用请求。目前只编写了普通调用的Client,读者可以根据 samples 库中的例子来尝试编写流式客户端和服务端。
+
+更多samples可以参阅 [【dubbo-go-samples】](../../samples/samples_repo/)
+
diff --git a/content/zh/docs3-building/golang-sdk/refer/_index.md b/content/zh/docs3-building/golang-sdk/refer/_index.md
new file mode 100644
index 0000000000..6d7cec698f
--- /dev/null
+++ b/content/zh/docs3-building/golang-sdk/refer/_index.md
@@ -0,0 +1,5 @@
+---
+type: docs
+title: "参考"
+weight: 5
+---
diff --git a/content/zh/docs3-building/golang-sdk/refer/compatible_version.md b/content/zh/docs3-building/golang-sdk/refer/compatible_version.md
new file mode 100644
index 0000000000..29c7e5d58e
--- /dev/null
+++ b/content/zh/docs3-building/golang-sdk/refer/compatible_version.md
@@ -0,0 +1,15 @@
+---
+title: 依赖适配版本号
+type: docs
+weight: 4
+---
+
+Dubbo-go 发布新版本时更新当前依赖的的版本。
+
+| 依赖 | Dubbo-go | Triple | protoc-gen-go-triple |
+| :--: | ------------ | ------ | -------------------- |
+| | v3.0.1 | v1.1.8 | v1.0.8 |
+| | v3.0.0 | v1.1.6 | v1.0.5 |
+| | v3.0.0-rc4-1 | v1.1.3 | v1.0.2 |
+| | v3.0.0-rc3 | v1.0.9 | v1.0.0 |
+
diff --git a/content/zh/docs3-building/golang-sdk/refer/config.md b/content/zh/docs3-building/golang-sdk/refer/config.md
new file mode 100644
index 0000000000..ad0555333a
--- /dev/null
+++ b/content/zh/docs3-building/golang-sdk/refer/config.md
@@ -0,0 +1,122 @@
+---
+title: 配置项参考
+type: docs
+weight: 1
+---
+
+## 根配置
+
+## 客户端配置
+
+## 服务端配置
+
+## 注册中心配置
+
+### 使用配置 API
+
+- 客户端使用配置 API 设置注册中心
+
+可通过调用config.NewRegistryConfigWithProtocolDefaultPort方法,快速设置用于调试的注册中心,支持zookeeper(127.0.0.1:2181) 和nacos(127.0.0.1:8848)
+
+```go
+rc := config.NewRootConfigBuilder().
+ SetConsumer(config.NewConsumerConfigBuilder().
+ SetRegistryIDs("zookeeperID"). // use defined registryID
+ Build()).
+ AddRegistry("zookeeperID", config.NewRegistryConfigWithProtocolDefaultPort("zookeeper")).
+ Build()
+```
+
+全部接口:可通过调用RegistryConfigBuilder提供的丰富接口进行配置。
+
+```go
+rc := config.NewRootConfigBuilder().
+ SetConsumer(config.NewConsumerConfigBuilder().
+ SetRegistryIDs("nacosRegistryID"). // use defined registryID
+ AddReference("GreeterClientImpl",/*...*/).
+ Build()
+ AddRegistry("nacosRegistryID", config.NewRegistryConfigBuilder().
+ SetProtocol("nacos").
+ SetAddress("127.0.0.1:8848").
+ SetGroup("dubbo-go").
+ SetNamespace("dubbo").
+ SetUsername("admin").
+ SetPassword("admin").
+ SetTimeout("3s").
+ Build()).
+ Build()
+```
+
+- 服务端使用配置 API 设置配置中心
+
+简易接口 config.NewRegistryConfigWithProtocolDefaultPort
+
+```go
+rc := config.NewRootConfigBuilder().
+ SetProvider(config.NewProviderConfigBuilder().
+ AddService("GreeterProvider", /*...*/).
+ SetRegistryIDs("registryKey"). // use defined registryID
+ Build()).
+ AddRegistry("registryKey", config.NewRegistryConfigWithProtocolDefaultPort("zookeeper")).
+ Build()
+```
+
+全部接口:可通过调用RegistryConfigBuilder提供的丰富接口进行配置。
+
+```go
+rc := config.NewRootConfigBuilder().
+ SetProvider(config.NewProviderConfigBuilder().
+ AddService("GreeterProvider",/*...*/)
+ SetRegistryIDs("registryKey"). // use defined registryID
+ Build()).
+ AddRegistry("registryKey", config.NewRegistryConfigBuilder().
+ SetProtocol("nacos").
+ SetAddress("127.0.0.1:8848").
+ SetGroup("dubbo-go").
+ SetNamespace("dubbo").
+ SetUsername("admin").
+ SetPassword("admin").
+ SetTimeout("3s").
+ Build()).
+ Build()
+```
+
+###
+
+## 网络协议
+
+### 配置文件
+
+### 使用配置 API
+
+- 客户端使用配置 API 设置网络协议
+
+```go
+rc := config.NewRootConfigBuilder().
+ SetConsumer(config.NewConsumerConfigBuilder().
+ AddReference("GreeterClientImpl", config.NewReferenceConfigBuilder().
+ SetInterface("org.apache.dubbo.UserProvider").
+ SetProtocol("tri"). // set reference protcol to triple
+ Build()).
+ Build()).
+ Build()
+```
+
+- 服务端使用配置 API 设置网络协议
+
+```go
+rc := config.NewRootConfigBuilder().
+ SetProvider(config.NewProviderConfigBuilder().
+ AddService("GreeterProvider", config.NewServiceConfigBuilder().
+ SetInterface("org.apache.dubbo.UserProvider").
+ SetProtocolIDs("tripleProtocolKey"). // use protocolID 'tripleProtocolKey'
+ Build()).
+ Build()).
+ AddProtocol("tripleProtocolKey", config.NewProtocolConfigBuilder(). // define protocol config with protocolID 'tripleProtocolKey'
+ SetName("tri"). // set service protocol to triple
+ Build()).
+ Build()
+```
+
+###
+
diff --git a/content/zh/docs3-building/golang-sdk/refer/ecology.md b/content/zh/docs3-building/golang-sdk/refer/ecology.md
new file mode 100644
index 0000000000..76100c4b9d
--- /dev/null
+++ b/content/zh/docs3-building/golang-sdk/refer/ecology.md
@@ -0,0 +1,46 @@
+---
+title: Dubbogo 生态组件
+type: docs
+weight: 3
+---
+
+### Dubbo-go / Dubbo-go 3.0
+
+[github.com/apache/dubbo-go](https://github.com/apache/dubbo-go)
+
+ Apache Dubbo Go 语言实现,架起 Java 和 Golang 之间的桥梁。
+
+### Dubbo-go-pixiu
+
+[github.com/apache/dubbo-go-pixiu](https://github.com/apache/dubbo-go-pixiu)
+
+dubbo-go-pixiu 网关支持以 dubbo 协议和 http 协议调用 dubbo/dubbo-go 集群
+
+### Dubbo-getty
+
+[github.com/apache/dubbo-getty](https://github.com/apache/dubbo-getty)
+
+dubbo-getty 是一个Go语言异步网络 io 库,支持 tcp/udp/websocket 协议。
+
+### Dubbo-go-hessian2
+
+[github.com/apache/dubbo-go-hessian2](https://github.com/apache/dubbo-go-hessian2)
+
+Dubbo-go-hessian2 是一个Go语言 hessian2 序列化协议库
+
+### Dubbogo-tools
+
+[github.com/dubbogo/tools](https://github.com/dubbogo/tools)
+
+Dubbogo-tools 包括
+
+- dubbo-cli 工具
+- imports-formatter Go语言 imports 块格式化工具
+- protoc-gen-triple PB编译插件
+- protoc-gen-dubbo3grpc PB编译插件
+
+### Triple-go
+
+[github.com/dubbogo/triple](https://github.com/dubbogo/triple)
+
+Triple-go 为 Go 语言实现的 Triple (Dubbo3) 网络协议库,基于 HTTP2 协议。
\ No newline at end of file
diff --git a/content/zh/docs3-building/golang-sdk/refer/use_dubbogo_cli.md b/content/zh/docs3-building/golang-sdk/refer/use_dubbogo_cli.md
new file mode 100644
index 0000000000..426e45f39f
--- /dev/null
+++ b/content/zh/docs3-building/golang-sdk/refer/use_dubbogo_cli.md
@@ -0,0 +1,429 @@
+---
+title: 使用 dubbogo-cli 工具
+type: docs
+weight: 2
+---
+
+## 1. 安装
+
+dubbogo-cli 是 Apach/dubbo-go 生态的子项目,为开发者提供便利的应用模板创建、工具安装、接口调试等功能,以提高用户的研发效率。
+
+执行以下指令安装dubbogo-cli 至 $GOPATH/bin
+
+```
+go install github.com/dubbogo/dubbogo-cli@latest
+```
+
+## 2. 功能概览
+
+dubbogo-cli 支持以下能力
+
+- 应用模板创建
+
+ ```
+ dubbogo-cli newApp .
+ ```
+
+ 在当前目录下创建应用模板
+
+- Demo 创建
+
+ ```
+ dubbogo-cli newDemo .
+ ```
+
+ 在当前目录下创建 RPC 示例,包含一个客户端和一个服务端
+
+- 编译、调试工具安装
+
+ ```
+ dubbogo-cli install all
+ ```
+
+ 一键安装以下等工具至 $GOPATH/bin
+
+ - protoc-gen-go-triple
+
+ 用于 triple 协议接口编译
+
+ - imports-formatter
+
+ 用于整理代码 import 块。
+
+ [import-formatte README](https://github.com/dubbogo/tools#imports-formatter)
+
+
+
+- 查看 dubbo-go 应用注册信息
+
+ - 查看 Zookeeper 上面的注册信息, 获取接口及方法列表
+
+ ```bash
+ $ dubbogo-cli show --r zookeeper --h 127.0.0.1:2181
+ interface: com.dubbogo.pixiu.UserService
+ methods: [CreateUser,GetUserByCode,GetUserByName,GetUserByNameAndAge,GetUserTimeout,UpdateUser,UpdateUserByName]
+ ```
+
+ - 查看 Nacos 上面的注册信息 【功能开发中】
+
+ - 查看 Istio 的注册信息【功能开发中】
+
+- 调试 Dubbo 协议接口
+
+- 调试 Triple 协议接口
+
+## 3. 功能详解
+
+### 3.1 Demo 应用介绍
+
+#### 3.1.1 Demo 创建
+
+```
+dubbogo-cli newDemo .
+```
+
+在当前目录下创建Demo, 包含客户端和服务端,该 Demo 展示了基于一套接口,完成一次 RPC 调用。
+
+该Demo 使用直连模式,无需依赖注册中心,server端暴露服务到本地20000端口,客户端发起调用。
+
+```shell
+.
+├── api
+│ ├── samples_api.pb.go
+│ ├── samples_api.proto
+│ └── samples_api_triple.pb.go
+├── go-client
+│ ├── cmd
+│ │ └── client.go
+│ └── conf
+│ └── dubbogo.yaml
+├── go-server
+│ ├── cmd
+│ │ └── server.go
+│ └── conf
+│ └── dubbogo.yaml
+└── go.mod
+```
+
+#### 3.1.2 运行Demo
+
+开启服务端
+
+```
+$ cd go-server/cmd
+$ go run .
+```
+
+另一个终端开启客户端
+
+```
+$ go mod tidy
+$ cd go-client/cmd
+$ go run .
+
+```
+
+可看到打印日志
+
+```
+INFO cmd/client.go:49 client response result: name:"Hello laurence" id:"12345" age:21
+```
+
+### 3.2 应用模板介绍
+
+#### 3.2.1 应用模板创建
+
+```
+dubbogo-cli newApp .
+```
+
+在当前目录下创建应用模板:
+
+```
+.
+├── Makefile
+├── api
+│ ├── api.pb.go
+│ ├── api.proto
+│ └── api_triple.pb.go
+├── build
+│ └── Dockerfile
+├── chart
+│ ├── app
+│ │ ├── Chart.yaml
+│ │ ├── templates
+│ │ │ ├── _helpers.tpl
+│ │ │ ├── deployment.yaml
+│ │ │ ├── service.yaml
+│ │ │ └── serviceaccount.yaml
+│ │ └── values.yaml
+│ └── nacos_env
+│ ├── Chart.yaml
+│ ├── templates
+│ │ ├── _helpers.tpl
+│ │ ├── deployment.yaml
+│ │ └── service.yaml
+│ └── values.yaml
+├── cmd
+│ └── app.go
+├── conf
+│ └── dubbogo.yaml
+├── go.mod
+├── go.sum
+└── pkg
+ └── service
+ └── service.go
+
+```
+
+#### 3.2.2 应用模板介绍
+
+生成项目包括几个目录:
+
+- api:放置接口文件:proto文件和生成的.pb.go文件
+- build:放置镜像构建相关文件
+- chart:放置发布用 chart 仓库、基础环境chart 仓库:nacos、mesh(开发中)
+- cmd:程序入口
+- conf:框架配置
+- pkg/service:RPC 服务实现
+- Makefile:
+
+- - 镜像、helm部署名:
+
+- - - IMAGE = $(your_repo)/$(namespace)/$(image_name)
+ TAG = 1.0.0
+- HELM_INSTALL_NAME = dubbo-go-app,helm 安装名,用于 helm install/uninstall 命令。
+
+- - 提供脚本,例如:
+
+- - - make build # 打包镜像并推送
+- make buildx-publish # arm架构本地打包amd64镜像并推送,依赖 docker buildx
+- make deploy # 通过 helm 发布应用
+- make remove # 删除已经发布的 helm 应用
+- make proto-gen # api下生成 pb.go 文件
+
+-
+
+使用应用模板的开发流程
+
+> 依赖环境:make、go、helm、kubectl、docker
+
+1. 通过 dubbogo-cli 生成模板
+2. 修改api/api.proto
+3. make proto-gen
+4. 开发接口
+5. 修改 makefile 内 IMAGE 镜像名和 HELM_INSTALL_NAME 发布名
+6. 打镜像并推送
+7. 修改chart/app/values 内与部署相关的value配置, 重点关注镜像部分。
+
+```
+image:
+ repository: $(your_repo)/$(namespace)/$(image_name)
+ pullPolicy: Always
+ tag: "1.0.0"
+```
+
+8. make deploy, 使用 helm 发布应用。
+
+### 3.3 以 gRPC 协议调试 dubbo-go 应用
+
+#### 3.3.1 简介
+
+grpc_cli 工具是 gRPC 生态用于调试服务的工具,在 server 开启[反射服务](https://github.com/grpc/grpc/blob/master/doc/server-reflection.md)的前提下,可以获取到服务的 proto 文件、服务名、方法名、参数列表,以及发起 gRPC 调用。
+
+Triple 协议兼容 gRPC 生态,并默认开启 gRPC 反射服务,因此可以直接使用 grpc_cli 调试 triple 服务。
+
+#### 3.3.2 安装grpc_cli
+
+> 后续将由 dubbogo-cli 安装,目前需要用户手动安装
+
+参考[grpc_cli 文档](https://github.com/grpc/grpc/blob/master/doc/command_line_tool.md)
+
+#### 3.3.3 使用 grpc_cli 对 Triple 服务进行调试
+
+1. 查看 triple 服务的接口定义
+
+```shell
+$ grpc_cli ls localhost:20001 -l
+filename: helloworld.proto
+package: org.apache.dubbo.quickstart.samples;
+service UserProvider {
+ rpc SayHello(org.apache.dubbo.quickstart.samples.HelloRequest) returns (org.apache.dubbo.quickstart.samples.User) {}
+ rpc SayHelloStream(stream org.apache.dubbo.quickstart.samples.HelloRequest) returns (stream org.apache.dubbo.quickstart.samples.User) {}
+}
+```
+
+2. 查看请求参数类型
+
+例如开发者期望测试上述端口的 SayHello 方法,尝试获取HelloRequest的具体定义,需要执行r如下指令,可查看到对应参数的定义。
+
+```shell
+$ grpc_cli type localhost:20001 org.apache.dubbo.quickstart.samples.HelloRequest
+message HelloRequest {
+ string name = 1 [json_name = "name"];
+}
+```
+
+3. 请求接口
+
+已经知道了请求参数的具体类型,可以发起调用来测试对应服务。查看返回值是否符合预期。
+
+```shell
+$ grpc_cli call localhost:20001 SayHello "name: 'laurence'"
+connecting to localhost:20001
+name: "Hello laurence"
+id: "12345"
+age: 21
+Received trailing metadata from server:
+accept-encoding : identity,gzip
+adaptive-service.inflight : 0
+adaptive-service.remaining : 50
+grpc-accept-encoding : identity,deflate,gzip
+Rpc succeeded with OK status
+```
+
+### 3.4 以 Dubbo 协议调试dubbo-go 应用
+
+#### 3.4.1 开启 Dubbo 服务端
+
+示例:user.go:
+
+```
+func (u *UserProvider) GetUser(ctx context.Context, userStruct *CallUserStruct) (*User, error) {
+ fmt.Printf("=======================\nreq:%#v\n", userStruct)
+ rsp := User{"A002", "Alex Stocks", 18, userStruct.SubInfo}
+ fmt.Printf("=======================\nrsp:%#v\n", rsp)
+ return &rsp, nil
+}
+```
+
+服务端开启一个服务,名为GetUser,传入一个CallUserStruct的参数,返回一个User参数
+CallUserStruct参数定义:
+
+```
+type CallUserStruct struct {
+ ID string
+ Male bool
+ SubInfo SubInfo // 嵌套子结构
+}
+func (cs CallUserStruct) JavaClassName() string {
+ return "com.ikurento.user.CallUserStruct"
+}
+
+type SubInfo struct {
+ SubID string
+ SubMale bool
+ SubAge int
+}
+
+func (s SubInfo) JavaClassName() string {
+ return "com.ikurento.user.SubInfo"
+}
+```
+
+User结构定义:
+
+```
+type User struct {
+ Id string
+ Name string
+ Age int32
+ SubInfo SubInfo // 嵌套上述子结构SubInfo
+}
+
+func (u *User) JavaClassName() string {
+ return "com.ikurento.user.User"
+}
+```
+
+开启服务:
+
+```
+cd server`
+`source builddev.sh`
+`go run .
+```
+
+#### 3.4.2 定义请求体 (适配于序列化协议)
+
+请求体定义为json文件,约定键值均为string
+键对应go语言struct字段名例如"ID"、"Name" ,值对应"type@val"
+其中type支持string int bool time,val使用string 来初始化,如果只填写type则初始化为零值。 约定每个struct必须有JavaClassName字段,务必与server端严格对应
+
+见userCall.json:
+
+```
+{
+ "ID": "string@A000",
+ "Male": "bool@true",
+ "SubInfo": {
+ "SubID": "string@A001",
+ "SubMale": "bool@false",
+ "SubAge": "int@18",
+ "JavaClassName":"string@com.ikurento.user.SubInfo"
+ },
+ "JavaClassName": "string@com.ikurento.user.CallUserStruct"
+}
+```
+
+userCall.json将参数CallUserStruct的结构及子结构SubInfo都定义了出来,并且给请求参数赋值。
+
+user.json 同理,作为返回值不需要赋初始值,但JavaClassName字段一定与server端严格对应
+
+```
+{
+ "ID": "string",
+ "Name": "string",
+ "Age": "int",
+ "JavaClassName": "string@com.ikurento.user.User",
+ "SubInfo": {
+ "SubID": "string",
+ "SubMale": "bool",
+ "SubAge": "int",
+ "JavaClassName":"string@com.ikurento.user.SubInfo"
+ }
+}
+```
+
+#### 3.4.3 调试端口
+
+```
+./dubbo-go-cli -h=localhost -p=20001 -proto=dubbo -i=com.ikurento.user.UserProvider -method=GetUser -sendObj="./userCall.json" -recvObj="./user.json"
+```
+
+打印结果:
+
+```
+2020/10/26 20:47:45 Created pkg:
+2020/10/26 20:47:45 &{ID:A000 Male:true SubInfo:0xc00006ea20 JavaClassName:com.ikurento.user.CallUserStruct}
+2020/10/26 20:47:45 SubInfo:
+2020/10/26 20:47:45 &{SubID:A001 SubMale:false SubAge:18 JavaClassName:com.ikurento.user.SubInfo}
+
+
+2020/10/26 20:47:45 Created pkg:
+2020/10/26 20:47:45 &{ID: Name: Age:0 JavaClassName:com.ikurento.user.User SubInfo:0xc00006ec90}
+2020/10/26 20:47:45 SubInfo:
+2020/10/26 20:47:45 &{SubID: SubMale:false SubAge:0 JavaClassName:com.ikurento.user.SubInfo}
+
+
+2020/10/26 20:47:45 connected to localhost:20001!
+2020/10/26 20:47:45 try calling interface:com.ikurento.user.UserProvider.GetUser
+2020/10/26 20:47:45 with protocol:dubbo
+
+2020/10/26 20:47:45 After 3ms , Got Rsp:
+2020/10/26 20:47:45 &{ID:A002 Name:Alex Stocks Age:18 JavaClassName: SubInfo:0xc0001241b0}
+2020/10/26 20:47:45 SubInfo:
+2020/10/26 20:47:45 &{SubID:A001 SubMale:false SubAge:18 JavaClassName:}```
+```
+
+可看到详细的请求体赋值情况,以及返回结果和耗时。支持嵌套结构
+
+server端打印结果
+
+```
+=======================
+req:&main.CallUserStruct{ID:"A000", Male:true, SubInfo:main.SubInfo{SubID:"A001", SubMale:false, SubAge:18}}
+=======================
+```
+
+可见接收到了来自cli的数据
diff --git a/content/zh/docs3-building/golang-sdk/samples/_index.md b/content/zh/docs3-building/golang-sdk/samples/_index.md
new file mode 100644
index 0000000000..15e599c61c
--- /dev/null
+++ b/content/zh/docs3-building/golang-sdk/samples/_index.md
@@ -0,0 +1,5 @@
+---
+type: docs
+title: "示例"
+weight: 4
+---
diff --git a/content/zh/docs3-building/golang-sdk/samples/adaptive-service.md b/content/zh/docs3-building/golang-sdk/samples/adaptive-service.md
new file mode 100644
index 0000000000..7d15f61873
--- /dev/null
+++ b/content/zh/docs3-building/golang-sdk/samples/adaptive-service.md
@@ -0,0 +1,28 @@
+---
+title: dubbogo 3.0 柔性服务
+keywords: dubbogo 3.0 柔性服务
+description: dubbogo 3.0 柔性服务
+---
+
+# 柔性负载均衡 (柔性服务)
+
+柔性服务是一种去中心化的智能负载均衡组件,同时也是 Dubbo-go 3.0 版本中重磅新特性之一。柔性服务尚处于早期实验阶段,该特性将在后续版本中持续优化,与 Dubbo 社区共同探索出一套适合微服务场景的最佳实践。
+
+传统的负载均衡算法是由随机节点、RoundRobin 等算法实现,他们的局限性在于不知道当前服务提供者的负载情况,算法总是以尽可能公平的概率调用不同的服务提供者。在实践中,公平不等于高性能,集群服务性能还与服务负载、任务复杂度等多因素相关。为解决传统负载均衡算法的不足,Dubbo-go 在 3.0 版本中引入了柔性服务,实现了容量动态评估和分流功能。
+
+容量评估是柔性服务的核心,它能动态评估服务端容量水平。在容量评估的过程中,两个核心指标是 TPS 和响应时间,要平衡系统利用率和系统性能两者之间的关系,使整体处于最佳的状态。
+
+- TPS 从服务提供者的角度反映系统利用率。在系统压力未饱和前,请求数越大则系统利用率越高,但是进一步加大请求量直至系统过饱和后,出现过载的问题,导致整体效率呈下降趋势。
+- 响应时间是从服务调用者的角度反映系统性能。在系统压力未饱和前,响应时间与请求数成线性增长的关系,但是进一步加大请求量直至系统过饱和后,响应时间与请求数成指数级增长。
+
+
+
+
+柔性服务则在调用过程中收集
+
+在 Dubbo-go 3.0 版本中,支持服务柔性负载均衡。在微服务场景下,客户端会在调用过程中收集该服务下游 server 实例的硬件资源消耗情况,通过容量评估与筛选策略,选择最合适的下游实例进行调用,从而提升系统整体的性能。
+
+服务柔性将在之后的迭代中持续优化,追求与 Dubbo 社区共同探索出最佳实践。
+
+
+下一章: [【使用 Pixiu 暴露 Dubbo-go 服务】](./pixiu-nacos-triple/)
\ No newline at end of file
diff --git a/content/zh/docs3-building/golang-sdk/samples/config-center-dynamic.md b/content/zh/docs3-building/golang-sdk/samples/config-center-dynamic.md
new file mode 100644
index 0000000000..5a1fad2c49
--- /dev/null
+++ b/content/zh/docs3-building/golang-sdk/samples/config-center-dynamic.md
@@ -0,0 +1,152 @@
+---
+title: Dubbogo 3.0 配置中心和配置监听
+weight: 2
+type: docs
+---
+
+## 1. 配置中心概念
+
+配置中心即为在分布式场景下,无法将最新的框架配置文件和应用程序绑定在一起,可以指定好配置中心的信息,例如配置中心类型和地址,并在框架启动时从配置中心拉取相应配置进行启动。
+
+## 2. 配置中心的配置
+
+参考仓库:[dubbo-go-samples/configcenter](https://github.com/apache/dubbo-go-samples/tree/master/configcenter)
+
+dubbogo.yml
+
+```yaml
+dubbo:
+ config-center:
+ protocol: nacos
+ address: 127.0.0.1:8848
+ data-id: dubbo-go-samples-configcenter-nacos-server
+ namespace: myNamespaceID # 可选配置 nacos namespace ID, 默认是 public
+ group: mygroup # 可选配置 nacos group, 默认是 DEFAULT_GROUP
+```
+
+配置中心 nacos 内
+
+group 默认为 `dubbo`
+
+dataID 为指定的id:`dubbo-go-samples-configcenter-nacos-server`
+
+写入框架配置例如下面,即可正常启动。
+
+```yaml
+dubbo:
+ registries:
+ demoZK:
+ protocol: zookeeper
+ timeout: 3s
+ address: 127.0.0.1:2181
+ protocols:
+ triple:
+ name: tri
+ port: 20000
+ provider:
+ services:
+ GreeterProvider:
+ interface: com.apache.dubbo.sample.basic.IGreeter
+```
+
+
+
+## 3. Dubbogo 动态配置 API
+
+Config API 为 dubbogo 3.0 用来操作配置结构的 API。可使用框架提供的 Config API 进行配置结构的初始化,获取组件实例并使用。一个例子如下,包含了动态配置实例的初始化、发布配置、读取配置、订阅配置操作。
+
+```go
+const configCenterNacosServerConfig = `# set in config center, group is 'dubbo', dataid is 'dubbo-go-samples-configcenter-nacos-server', namespace is default 'public'
+dubbo:
+ registries:
+ demoZK:
+ protocol: zookeeper
+ address: 127.0.0.1:2181
+ protocols:
+ triple:
+ name: tri
+ port: 20000
+ provider:
+ services:
+ GreeterProvider:
+ interface: com.apache.dubbo.sample.basic.IGreeter # must be compatible with grpc or dubbo-java`
+
+type GreeterProvider struct {
+ api.GreeterProviderBase
+}
+
+func (s *GreeterProvider) SayHello(ctx context.Context, in *api.HelloRequest) (*api.User, error) {
+ logger.Infof("Dubbo3 GreeterProvider get user name = %s\n", in.Name)
+ return &api.User{Name: "Hello " + in.Name, Id: "12345", Age: 21}, nil
+}
+
+// There is no need to export DUBBO_GO_CONFIG_PATH, as you are using config api to set config
+func main() {
+ // 获取动态配置实例 dynamicConfig
+ dynamicConfig, err := config.NewConfigCenterConfigBuilder().
+ SetProtocol("nacos").
+ SetAddress("127.0.0.1:8848").
+ SetGroup("dubbo").
+ Build().GetDynamicConfiguration()
+ if err != nil {
+ panic(err)
+ }
+
+ // 使用 dynamicConfig 结构来发布配置
+ if err := dynamicConfig.PublishConfig("dubbo-go-samples-configcenter-nacos-server", "dubbo", configCenterNacosServerConfig); err != nil {
+ panic(err)
+ }
+
+ // 使用 dynamicConfig 结构来读取配置
+ data, err := dynamicConfig.GetRule("dubbo-go-samples-configcenter-nacos-server", config_center.WithGroup("dubbo"))
+ if err != nil{
+ panic(err)
+ }
+ logger.Infof("get config = %s", data)
+
+
+ // 使用 dynamicConfig 结构, 通过自定义listener来订阅配置更新事件
+ l := &listener{}
+ dynamicConfig.AddListener("dubbo-go-samples-configcenter-nacos-server", l)
+
+ time.Sleep(time.Second * 10)
+
+ config.SetProviderService(&GreeterProvider{})
+
+ // 以 API 的形式来启动框架
+ rootConfig := config.NewRootConfigBuilder().
+ SetConfigCenter(config.NewConfigCenterConfigBuilder().
+ SetProtocol("nacos").SetAddress("127.0.0.1:8848"). // 根据配置结构,设置配置中心
+ SetDataID("dubbo-go-samples-configcenter-nacos-server"). // 设置配置ID
+ SetGroup("dubbo").
+ Build()).
+ Build()
+
+ if err := rootConfig.Init(); err != nil { // 框架启动
+ panic(err)
+ }
+ select {}
+}
+
+type listener struct {
+
+}
+
+func (l listener) Process(event *config_center.ConfigChangeEvent) {
+ logger.Infof("listener get config = %s", event.Value)
+}
+
+```
+
+当然,以 API 的形式来启动框架时,可以直接以API的形式来启动框架。参考基本概念模块的 [Dubbogo 框架配置](../concept/configuration/)
+
+## 4. Dubbogo 配置热更新
+
+// todo
+
+正在开发中ing
+
+
+
+下一章: [【Filter】](./custom-filter/)
+
diff --git a/content/zh/docs3-building/golang-sdk/samples/custom-filter.md b/content/zh/docs3-building/golang-sdk/samples/custom-filter.md
new file mode 100644
index 0000000000..63e870b8e7
--- /dev/null
+++ b/content/zh/docs3-building/golang-sdk/samples/custom-filter.md
@@ -0,0 +1,116 @@
+---
+title: 自定义Filter组件
+weight: 3
+type: docs
+---
+
+参考samples [dubbo-go-samples/filter](https://github.com/apache/dubbo-go-samples/tree/master/filter)
+
+## 1. Filter 概念
+
+```go
+// Filter interface defines the functions of a filter
+// Extension - Filter
+type Filter interface {
+ // Invoke is the core function of a filter, it determines the process of the filter
+ Invoke(context.Context, protocol.Invoker, protocol.Invocation) protocol.Result
+ // OnResponse updates the results from Invoke and then returns the modified results.
+ OnResponse(context.Context, protocol.Result, protocol.Invoker, protocol.Invocation) protocol.Result
+}
+```
+
+Filter 可以加载在 Consumer 端或者 Provider端。当加载在 Consumer 端,其Invoke函数调用的下游为网络层,OnResponse 为请求结束从网络层获取到返回结果后被调用。当加载在 Provider 端,其 Invoke 函数调用的下游为用户代码,OnResponse 为用户代码执行结束后向下传递至网络层前被调用。
+
+Filter 采用面向切面设计的思路,通过对 Filter 的合理扩展,可以记录日志、设置数据打点,记录 invoker 所对应服务端性能,限流等等工作。
+
+## 2. 框架预定义 Filter
+
+框架预定义了一系列filter,可以在配置中直接使用,其代码实现位于[filter](https://github.com/apache/dubbo-go/tree/3.0/filter)
+
+- accesslog
+- active
+- sign: AuthConsumerFilter
+- auth: AuthProviderFilter
+- echo
+- execute: ExecuteLimitFilter
+- generic: GenericFilter
+- generic_service: GenericServiceFilter
+- pshutdown: GracefulShutdownProviderFilter
+- cshutdown: GracefulShutdownConsumerFilter
+- hystrix_consumer: HystrixConsumerFilter
+- hystrix_provider: HystrixProviderFilter
+- metrics
+- seata
+- sentinel-provider
+- sentinel-consumer
+- token
+- tps
+- tracing
+
+## 3. 默认加载Filter
+
+用户在配置文件中配置了将要使用的 Filter 时,框架使用用户配置的 Filter,否则则加载默认Filter:
+
+- Consumer:
+
+ cshutdown
+
+- Provider:
+
+ echo, metrics, token, accesslog, tps, generic_service, executivete, pshutdown
+
+## 4. 用户指定 Filter
+
+指定filter时可用','分隔
+
+- Consumer 端
+
+ ```yaml
+ dubbo:
+ consumer:
+ filter: echo,token,tps,myCustomFilter # 可指定自定义filter
+ ```
+
+
+
+- Provider 端
+
+ ```yaml
+ dubbo:
+ provider:
+ services:
+ GreeterProvider:
+ filter: myCustomFilter,echo,tps
+ ```
+
+## 5. 自定义Filter
+
+用户可在代码中自定义 Filter,注册到框架上,并在配置中选择使用。
+
+```go
+func init() {
+ extension.SetFilter("myCustomFilter", NewMyClientFilter)
+}
+
+func NewMyClientFilter() filter.Filter {
+ return &MyClientFilter{}
+}
+
+type MyClientFilter struct {
+}
+
+func (f *MyClientFilter) Invoke(ctx context.Context, invoker protocol.Invoker, invocation protocol.Invocation) protocol.Result {
+ fmt.Println("MyClientFilter Invoke is called, method Name = ", invocation.MethodName())
+ return invoker.Invoke(ctx, invocation)
+}
+func (f *MyClientFilter) OnResponse(ctx context.Context, result protocol.Result, invoker protocol.Invoker, protocol protocol.Invocation) protocol.Result {
+ fmt.Println("MyClientFilter OnResponse is called")
+ return result
+}
+
+```
+
+
+
+下一章: [【注册中心配置】](./registry/)
+
diff --git a/content/zh/docs3-building/golang-sdk/samples/custom-logger.md b/content/zh/docs3-building/golang-sdk/samples/custom-logger.md
new file mode 100644
index 0000000000..2165f891ad
--- /dev/null
+++ b/content/zh/docs3-building/golang-sdk/samples/custom-logger.md
@@ -0,0 +1,88 @@
+---
+title: 日志
+weight: 6
+type: docs
+---
+
+参考samples [dubbo-go-samples/logger](https://github.com/apache/dubbo-go-samples/tree/master/logger)
+
+## 1. 日志配置
+
+dubbogo 3.0 默认采用 zap 日志库,在配置文件中不添加 logger 配置,日志将会打印到控制默认级别为debug。您也可在配置文件中配置日志级别、, 可参照如下方式来配置zap-config和lumberjack-config,从而定制化日志输出。
+
+```yaml
+dubbo:
+ logger:
+ zap-config:
+ level: debug # 日志级别
+ development: false
+ disableCaller: false
+ disableStacktrace: false
+ encoding: "console"
+ # zap encoder 配置
+ encoderConfig:
+ messageKey: "message"
+ levelKey: "level"
+ timeKey: "time"
+ nameKey: "logger"
+ callerKey: "caller"
+ stacktraceKey: "stacktrace"
+ lineEnding: ""
+ levelEncoder: "capitalColor"
+ timeEncoder: "iso8601"
+ durationEncoder: "seconds"
+ callerEncoder: "short"
+ nameEncoder: ""
+ outputPaths:
+ - "stderr"
+ errorOutputPaths:
+ - "stderr"
+ lumberjack-config:
+ # 写日志的文件名称
+ filename: "logs.log"
+ # 每个日志文件长度的最大大小,单位是 MiB。默认 100MiB
+ maxSize: 1
+ # 日志保留的最大天数(只保留最近多少天的日志)
+ maxAge: 3
+ # 只保留最近多少个日志文件,用于控制程序总日志的大小
+ maxBackups: 5
+ # 是否使用本地时间,默认使用 UTC 时间
+ localTime: true
+ # 是否压缩日志文件,压缩方法 gzip
+ compress: false
+```
+
+## 2. 日志API 和 自定义日志
+
+日志Interface
+
+```go
+type Logger interface {
+ Info(args ...interface{})
+ Warn(args ...interface{})
+ Error(args ...interface{})
+ Debug(args ...interface{})
+ Fatal(args ...interface{})
+
+ Infof(fmt string, args ...interface{})
+ Warnf(fmt string, args ...interface{})
+ Errorf(fmt string, args ...interface{})
+ Debugf(fmt string, args ...interface{})
+ Fatalf(fmt string, args ...interface{})
+}
+```
+
+日志API
+
+```go
+import "dubbo.apache.org/dubbo-go/v3/common/logger"
+
+
+logger.SetLoggerLevel(warn) // 在 main 函数中设置日志级别
+logger.SetLogger(myLogger) // 在 main 函数中设置自定义logger
+```
+
+- 日志API不可以在Init 阶段使用,否则可能会发生意料之外的问题。
+
+下一章: [【Metrics 数据上报】](./metrics/)
+
diff --git a/content/zh/docs3-building/golang-sdk/samples/exception_response.md b/content/zh/docs3-building/golang-sdk/samples/exception_response.md
new file mode 100644
index 0000000000..e61250f0e0
--- /dev/null
+++ b/content/zh/docs3-building/golang-sdk/samples/exception_response.md
@@ -0,0 +1,117 @@
+---
+title: Triple 异常回传
+weight: 5
+type: docs
+---
+
+参考samples [dubbo-go-samples/error](https://github.com/apache/dubbo-go-samples/tree/master/error)
+
+## 用户异常回传介绍
+
+用户可以在 provider 端生成用户定义的异常信息,可以记录异常产生堆栈,triple 协议可保证将用户在客户端获取到异常 message ,并可以查看报错堆栈,便于定位问题。
+
+注意返回 error 非 nil 时,框架不负责其他返回值的传递。
+
+- 在Triple provider 端返回异常,以 pb 序列化为例:
+
+```go
+package main
+
+import (
+ "context"
+)
+
+import (
+ "dubbo.apache.org/dubbo-go/v3/common/logger"
+
+ // 使用可以记录对战信息的异常库,此处以 "github.com/pkg/errors" 为例
+ "github.com/pkg/errors"
+)
+
+import (
+ triplepb "github.com/apache/dubbo-go-samples/api"
+)
+
+
+// 一个实现了 pb 接口的服务提供结构
+type ErrorResponseProvider struct {
+ triplepb.UnimplementedGreeterServer
+}
+
+// 回传错误的接口
+func (s *ErrorResponseProvider) SayHello(ctx context.Context, in *triplepb.HelloRequest) (*triplepb.User, error) {
+ logger.Infof("Dubbo3 GreeterProvider get user name = %s\n" + in.Name)
+ // 返回用户自定义异常
+ return &triplepb.User{Name: "Hello " + in.Name, Id: "12345", Age: 21}, errors.New("user defined error")
+}
+
+```
+
+
+
+- 客户端打印异常和堆栈
+
+```go
+package main
+
+import (
+ "context"
+)
+
+import (
+ "dubbo.apache.org/dubbo-go/v3/common/logger"
+ "dubbo.apache.org/dubbo-go/v3/config"
+ _ "dubbo.apache.org/dubbo-go/v3/imports"
+
+ tripleCommon "github.com/dubbogo/triple/pkg/common"
+)
+
+import (
+ triplepb "github.com/apache/dubbo-go-samples/api"
+)
+
+var greeterProvider = new(triplepb.GreeterClientImpl)
+
+func init() {
+ config.SetConsumerService(greeterProvider)
+}
+
+func main() {
+ if err := config.Load(); err != nil {
+ panic(err)
+ }
+
+ req := triplepb.HelloRequest{
+ Name: "laurence",
+ }
+
+ // 发起调用
+ if user, err := greeterProvider.SayHello(context.TODO(), &req); err != nil {
+ // 打印异常信息,err.Error() 将返回用户定义的 message,即 user defined error
+ logger.Infof("response result: %v, error = %s", user, err)
+
+ // 打印异常堆栈,需断言为 tripleCommon.TripleError
+ logger.Infof("error details = %+v", err.(tripleCommon.TripleError).Stacks())
+ }
+}
+
+```
+
+```text
+2021-11-12T18:36:33.730+0800 INFO cmd/client.go:53 response result: , error = user defined error
+2021-11-12T18:36:33.730+0800 INFO cmd/client.go:54 error details = [type.googleapis.com/google.rpc.DebugInfo]:{stack_entries:"user defined error
+main.(*ErrorResponseProvider).SayHello
+ /dubbo-go-samples/error/triple/pb/go-server/cmd/error_reponse.go:40
+reflect.Value.call
+ /usr/local/go/src/reflect/value.go:543
+reflect.Value.Call
+ /usr/local/go/src/reflect/value.go:339
+dubbo.apache.org/dubbo-go/v3/common/proxy/proxy_factory.(*ProxyInvoker).Invoke
+ /Users/laurence/go/pkg/mod/dubbo.apache.org/dubbo-go/v3@v3.0.0-rc4-1/common/proxy/proxy_factory/default.go:145
+ ...
+
+```
+
+可看到报错信息和堆栈
+
+下一章: [【日志】](./custom-logger/)
\ No newline at end of file
diff --git a/content/zh/docs3-building/golang-sdk/samples/generic.md b/content/zh/docs3-building/golang-sdk/samples/generic.md
new file mode 100644
index 0000000000..f1448d18db
--- /dev/null
+++ b/content/zh/docs3-building/golang-sdk/samples/generic.md
@@ -0,0 +1,102 @@
+---
+title: 泛化调用
+weight: 8
+type: docs
+---
+
+## 1. Dubbogo 泛化调用 Java Server
+
+使用 Triple 协议 + hessian2 序列化方案
+
+可参考Dubbogo 3.0 [泛化调用文档](https://www.yuque.com/docs/share/f4e72670-74ab-45b9-bc0c-4b42249ed953?#)
+
+### 1.1 Java-Server启动
+
+1. 传输结构定义
+
+```java
+package org.apache.dubbo;
+
+import java.io.Serializable;
+import java.util.Date;
+
+public class User implements Serializable {
+ private String id;
+
+ private String name;
+
+ private int age;
+
+ private Date time = new Date();
+}
+```
+
+2. 接口定义
+
+```java
+package org.apache.dubbo;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+//import org.apache.dubbo.rpc.filter.GenericFilter;
+
+public interface UserProvider {
+ User GetUser1(String userId);
+}
+```
+
+### 1.2 Go-Client 泛化调用
+
+此处展示以 API 的形式构造泛化接口引用
+
+```go
+// 初始化 Reference 配置
+refConf := config.NewReferenceConfigBuilder().
+ SetInterface("org.apache.dubbo.UserProvider").
+ SetRegistryIDs("zk").
+ SetProtocol(tripleConst.TRIPLE).
+ SetGeneric(true).
+ SetSerialization("hessian2").
+ Build()
+
+// 构造 Root 配置,引入注册中心模块
+rootConfig := config.NewRootConfigBuilder().
+ AddRegistry("zk", config.NewRegistryConfigWithProtocolDefaultPort("zookeeper")).
+ Build()
+
+// Reference 配置初始化,因为需要使用注册中心进行服务发现,需要传入经过配置的 rootConfig
+if err := refConf.Init(rootConfig); err != nil{
+ panic(err)
+}
+
+// 泛化调用加载、服务发现
+refConf.GenericLoad(appName)
+
+time.Sleep(time.Second)
+
+// 发起泛化调用
+resp, err := refConf.GetRPCService().(*generic.GenericService).Invoke(
+ context.TODO(),
+ "getUser1",
+ []string{"java.lang.String"},
+ []hessian.Object{"A003"},
+)
+
+if err != nil {
+ panic(err)
+}
+logger.Infof("GetUser1(userId string) res: %+v", resp)
+```
+
+GenericService 的 Invoke 方法包括三个参数:context.Context, []string, []hessian.Object,
+
+其中第二个参数为对应参数的 Java 类名,例如java.lang.String、org.apache.dubbo.User,第三个参数为参数列表,hessian.Object 即为 interface。第二、第三个参数应与方法签名一致,按顺序对应。
+
+获得map结构的返回结果
+
+```
+INFO cmd/client.go:89 GetUser1(userId string) res: map[age:48 class:org.apache.dubbo.User id:A003 name:Joe sex:MAN time:2021-10-04 14:03:03.37 +0800 CST]
+```
+
+
diff --git a/content/zh/docs3-building/golang-sdk/samples/go_java_interactive.md b/content/zh/docs3-building/golang-sdk/samples/go_java_interactive.md
new file mode 100644
index 0000000000..9d1075296d
--- /dev/null
+++ b/content/zh/docs3-building/golang-sdk/samples/go_java_interactive.md
@@ -0,0 +1,848 @@
+---
+title: Go-Java 互通示例
+weight: 1
+type: docs
+---
+
+## 准备工作
+
+### 环境
+
+JDK 8,Golang >= 1.15,Dubbo 3.0.2,zookeeper 启动,
+
+### Go- Java 互通前提
+
+- Go/Java 定义的传输结构一致
+
+ - PB 序列化
+
+ proto for Go
+
+ ```protobuf
+ // The response message containing the greetings
+ message User {
+ string name = 1;
+ string id = 2;
+ int32 age = 3;
+ }
+ ```
+
+ proto for Java
+
+ ```protobuf
+ // The response message containing the greetings
+ message User {
+ string name = 1;
+ string id = 2;
+ int32 age = 3;
+ }
+ ```
+
+ - Hessian 序列化
+
+ POJO for Go,需参考 [Dubbogo Hessian 序列化支持文档](https://www.yuque.com/docs/share/c698bd6e-e4d6-47db-bc1c-c757cc9b4f3e?)
+
+ ```go
+ type User struct {
+ ID string
+ Name string
+ Age int32
+ }
+
+ func (u *User) JavaClassName() string {
+ return "org.apache.dubbo.User"
+ }
+
+ func init(){
+ hessian.RegisterPOJO(&User{})
+ }
+ ```
+
+ POJO for Java
+
+ ```java
+ package org.apache.dubbo
+
+ public class User {
+ private String id;
+ private String name;
+ private int age;
+ }
+ ```
+
+- Java 需要互通的方法签名与 Go 一致
+
+ 例如:
+
+ Java Interface
+
+ ```java
+ public interface IGreeter {
+ /**
+ * <pre>
+ * Sends a greeting
+ * </pre>
+ */
+ User sayHello(HelloRequest request);
+ }
+ ```
+
+ Go client (由protoc-gen-go-triple 根据 proto 文件自动生成)
+
+ ```go
+ type GreeterClientImpl struct {
+ // Sends a greeting
+ SayHello func(ctx context.Context, in *HelloRequest) (*User, error)
+ }
+ ```
+
+ Go server (由开发者定义)
+
+ ```go
+ type GreeterProvider struct {
+ api.GreeterProviderBase
+ }
+
+ func (s *GreeterProvider) SayHello(ctx context.Context, in *api.HelloRequest) (*api.User, error) {
+ logger.Infof("Dubbo3 GreeterProvider get user name = %s\n", in.Name)
+ return &api.User{Name: "Hello " + in.Name, Id: "12345", Age: 21}, nil
+ }
+ ```
+
+ Go 方法需要遵守 [Dubbogo 3.0 用户服务接口定义规范](https://www.yuque.com/docs/share/eff9c51f-a7f4-47d6-87ff-11a2152bdffe?)
+
+
+
+- Java 的三元组与Go service/reference 配置的 interface 一致
+
+ 三元组,即为接口级别配置的:interface, group, version。**其中需要注意,group 和 version 的概念为 dubbo 接口的 group 和vesion,在启动 dubbo-java 服务时配置于 spring cloud 的 properties 文件中,并非pom.xml 中 mvn 依赖的version。** group 和version 默认为空,在 dubbo-go 框架中,可以在service/reference 的对应位置指定 group 和 version。
+
+ 例如:
+
+ Java 的接口全名:com.apache.dubbo.sample.basic.IGreeter,接口 version 为v1.0.1, group 为
+
+ Go-client:
+
+ ```yaml
+ references:
+ GreeterClientImpl:
+ protocol: tri
+ interface: com.apache.dubbo.sample.basic.IGreeter # must be compatible with grpc or dubbo-java
+ group: dubbogo # 需要与服务端对应 默认为空
+ version: v1.0.1 # 需要与服务端对应 默认为空
+ ```
+
+ Go-server:
+
+ ```yaml
+ services:
+ GreeterProvider:
+ protocol-ids: tripleProtocol
+ interface: com.apache.dubbo.sample.basic.IGreeter # must be compatible with grpc or dubbo-java
+ group: dubbogo # 需要与服务端对应 默认为空
+ version: v1.0.1 # 需要与服务端对应 默认为空
+ ```
+
+
+
+## 1. 基于 Triple 协议互通 (PB序列化)
+
+参考 [dubbo-go-samples/helloworld](https://github.com/apache/dubbo-go-samples/tree/master/helloworld)
+
+### 1.1 Go-Client -> Java-Server
+
+#### Java-Server 启动
+
+1. 定义 Java 的 PB 文件,可参考 [Dubbo 快速开始](https://dubbo.apache.org/zh/docs/quick-start/)
+
+```protobuf
+syntax = "proto3";
+
+option java_package = "org.apache.dubbo.sample.hello";
+
+package helloworld;
+
+// The request message containing the user's name.
+message HelloRequest {
+ string name = 1;
+}
+
+// The response message containing the greetings
+message User {
+ string name = 1;
+ string id = 2;
+ int32 age = 3;
+}
+```
+
+该接口描述文件定义了将会生成的 Java 类 org.apache.dubbo.sample.hello.Helloworld,以及类中包含的传输结构 HelloRequest 和 User 类。
+
+2. 定义服务接口:
+
+ com.apache.dubbo.sample.basic.IGreeter
+
+```java
+package com.apache.dubbo.sample.basic;
+
+// 引入根据 PB 生成的类
+import org.apache.dubbo.sample.hello.Helloworld.User;
+import org.apache.dubbo.sample.hello.Helloworld.HelloRequest;
+
+public interface IGreeter {
+ /**
+ * <pre>
+ * Sends a greeting
+ * </pre>
+ */
+ // 定义接口
+ User sayHello(HelloRequest request);
+}
+```
+
+3. 实现服务接口:
+
+ IGreeter1Impl.java
+
+```java
+package com.apache.dubbo.sample.basic;
+
+import org.apache.dubbo.sample.hello.Helloworld.User;
+import org.apache.dubbo.sample.hello.Helloworld.HelloRequest;
+
+public class IGreeter1Impl implements IGreeter {
+ @Override
+ public User sayHello(HelloRequest request) {
+ System.out.println("receiv: " + request);
+ User usr = User.newBuilder()
+ .setName("hello " + request.getName())
+ .setAge(18)
+ .setId("12345").build();
+ return usr;
+ }
+}
+```
+
+4. 使用 Dubbo3 框架启动服务
+
+ ApiProvider.java
+
+```java
+package com.apache.dubbo.sample.basic;
+
+import org.apache.dubbo.common.constants.CommonConstants;
+import org.apache.dubbo.config.ApplicationConfig;
+import org.apache.dubbo.config.ProtocolConfig;
+import org.apache.dubbo.config.RegistryConfig;
+import org.apache.dubbo.config.ServiceConfig;
+import java.util.concurrent.CountDownLatch;
+
+public class ApiProvider {
+ public static void main(String[] args) throws InterruptedException {
+ ServiceConfig<IGreeter> service = new ServiceConfig<>();
+ service.setInterface(IGreeter.class);
+ service.setRef(new IGreeter1Impl());
+ // 使用 Triple 协议
+ service.setProtocol(new ProtocolConfig(CommonConstants.TRIPLE, 50051));
+ service.setApplication(new ApplicationConfig("demo-provider"));
+ // 使用 ZK 作为注册中心
+ service.setRegistry(new RegistryConfig("zookeeper://127.0.0.1:2181"));
+ service.export();
+ System.out.println("dubbo service started");
+ new CountDownLatch(1).await();
+ }
+}
+```
+
+启动服务,可看到输出如下日志,代表 Java Triple Server 启动成功
+
+```
+main INFO bootstrap.DubboBootstrap: [DUBBO] DubboBootstrap has started., dubbo version: 3.0.2, current host: 192.168.0.108
+dubbo service started
+```
+
+#### Go-Client 启动
+
+对于已经启动的Dubbo服务,如需要开发与其对应的Go-client,需要进行如下步骤:
+
+1. 编写与 Java 适配的 proto文件
+
+ samples_api.proto
+
+```protobuf
+
+syntax = "proto3";
+package api; // pacakge 名随意指定
+
+// necessary
+option go_package = "./;api";
+
+// The greeting service definition.
+service Greeter {
+ // Sends a greeting
+ rpc SayHello (HelloRequest) returns (User) {}
+}
+
+// The request message containing the user's name.
+message HelloRequest {
+ string name = 1;
+}
+
+// The response message containing the greetings
+message User {
+ string name = 1;
+ string id = 2;
+ int32 age = 3;
+}
+```
+
+2. 使用 protoc-gen-triple 生成接口文件
+
+```bash
+protoc -I . samples_api.proto --triple_out=plugins=triple:.
+```
+
+3. 撰写配置文件: dubbogo.yml
+
+```yaml
+dubbo:
+ registries:
+ demoZK:
+ protocol: zookeeper
+ address: 127.0.0.1:2181
+ consumer:
+ references:
+ GreeterClientImpl:
+ protocol: tri
+ interface: com.apache.dubbo.sample.basic.IGreeter # must be compatible with grpc or dubbo-java
+```
+
+4. 撰写 main.go 文件,发起调用
+
+```go
+// 引入生成的接口结构
+var grpcGreeterImpl = new(api.GreeterClientImpl)
+
+// export DUBBO_GO_CONFIG_PATH=dubbogo.yml
+func main() {
+ config.SetConsumerService(grpcGreeterImpl)
+ if err := config.Load(); err != nil {
+ panic(err)
+ }
+ time.Sleep(3 * time.Second)
+
+ logger.Info("start to test dubbo")
+ req := &api.HelloRequest{
+ Name: "laurence",
+ }
+ reply, err := grpcGreeterImpl.SayHello(context.Background(), req)
+ if err != nil {
+ logger.Error(err)
+ }
+ logger.Infof("client response result: %v\n", reply)
+}
+```
+
+5. 可查看到调用成功的日志
+
+- go-client
+
+```
+cmd/client.go:53 client response result: name:"hello laurence" id:"12345" age:18
+```
+
+- java-server
+
+```
+receiv: name: "laurence"
+```
+
+### 1.2 Java-Client -> Go-Server
+
+#### Go-Server 启动
+
+1. 定义配置文件
+
+```yaml
+dubbo:
+ registries:
+ demoZK:
+ protocol: zookeeper
+ address: 127.0.0.1:2181
+ protocols:
+ triple:
+ name: tri
+ port: 20000
+ provider:
+ services:
+ GreeterProvider:
+ interface: com.apache.dubbo.sample.basic.IGreeter # must be compatible with grpc or dubbo-java
+```
+
+2. 引入传输结构,定义服务
+
+```go
+type GreeterProvider struct {
+ api.GreeterProviderBase
+}
+
+func (s *GreeterProvider) SayHello(ctx context.Context, in *api.HelloRequest) (*api.User, error) {
+ logger.Infof("Dubbo3 GreeterProvider get user name = %s\n", in.Name)
+ return &api.User{Name: "Hello " + in.Name, Id: "12345", Age: 21}, nil
+}
+```
+
+3. 启动服务
+
+```go
+// export DUBBO_GO_CONFIG_PATH=dubbogo.yml
+func main() {
+ config.SetProviderService(&GreeterProvider{})
+ if err := config.Load(); err != nil {
+ panic(err)
+ }
+ select {}
+}
+```
+
+
+
+#### Java-Client 启动
+
+1. proto 文件编写和接口生成参考上述 java-server 介绍
+
+2. 启动Consumer
+
+ ApiCnosumer.java
+
+```java
+public class ApiConsumer {
+ public static void main(String[] args) throws InterruptedException, IOException {
+ ReferenceConfig<IGreeter> ref = new ReferenceConfig<>();
+ ref.setInterface(IGreeter.class);
+ ref.setCheck(false);
+ ref.setProtocol(CommonConstants.TRIPLE);
+ ref.setLazy(true);
+ ref.setTimeout(100000);
+ ref.setApplication(new ApplicationConfig("demo-consumer"));
+ ref.setRegistry(new RegistryConfig("zookeeper://127.0.0.1:2181"));
+ final IGreeter iGreeter = ref.get();
+
+ System.out.println("dubbo ref started");
+ Helloworld.HelloRequest req = Helloworld.HelloRequest.newBuilder().setName("laurence").build();
+ try {
+ final Helloworld.User reply = iGreeter.sayHello(req);
+ TimeUnit.SECONDS.sleep(1);
+ System.out.println("Reply:" + reply);
+ } catch (Throwable t) {
+ t.printStackTrace();
+ }
+ System.in.read();
+ }
+}
+```
+
+## 2. 基于 Dubbo 协议互通 (Hessian2序列化)
+
+参考 [dubbo-go-samples/rpc/dubbo](https://github.com/apache/dubbo-go-samples/tree/rpc/dubbo)
+
+### 2.1 Go-Client -> Java-Server
+
+#### Java-Server 启动
+
+1. 定义 Java 接口、参数和返回值,可参考 [Dubbo 快速开始](https://dubbo.apache.org/zh/docs/quick-start/)
+
+```java
+package org.apache.dubbo;
+
+// 需要暴露的服务接口
+public interface UserProvider {
+ User getUser(int usercode);
+}
+
+```
+
+```java
+package org.apache.dubbo;
+
+public class User implements Serializable {
+
+ private String id;
+
+ private String name;
+
+ private int age;
+
+ private Date time = new Date();
+ /* ... */
+}
+```
+
+2. 实现服务接口:
+
+UserProviderImpl.java
+
+```java
+
+package org.apache.dubbo;
+public class UserProviderImpl implements UserProvider {
+ public User getUser(int userCode) {
+ return new User(String.valueOf(userCode), "userCode get", 48);
+ }
+}
+
+```
+
+3. 使用SpringBoot 启动
+
+Provider.java
+
+```java
+package org.apache.dubbo;
+
+// use when config by API
+/*
+import java.util.concurrent.CountDownLatch;
+
+import org.apache.dubbo.common.constants.CommonConstants;
+import org.apache.dubbo.config.ApplicationConfig;
+import org.apache.dubbo.config.ProtocolConfig;
+import org.apache.dubbo.config.RegistryConfig;
+import org.apache.dubbo.config.ServiceConfig;
+*/
+import org.springframework.context.support.ClassPathXmlApplicationContext;
+
+public class Provider {
+ // main function, config from spring boot
+ public static void main(String[] args) throws Exception {
+ ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new String[]{"META-INF/spring/dubbo.provider.xml"});
+ context.start();
+ System.in.read(); // press any key to exit
+ }
+
+
+// config by API
+// public static void startComplexService() throws InterruptedException {
+// ServiceConfig<ComplexProvider> service = new ServiceConfig<>();
+// service.setInterface(ComplexProvider.class);
+// service.setRef(new ComplexProviderImpl());
+// service.setProtocol(new ProtocolConfig(CommonConstants.DUBBO_PROTOCOL, 20001));
+// service.setApplication(new ApplicationConfig("demo-provider"));
+// service.setRegistry(new RegistryConfig("zookeeper://127.0.0.1:2181"));
+// service.export();
+// System.out.println("dubbo service started");
+// new CountDownLatch(1).await();
+// }
+}
+
+```
+
+4. 通过Spring 配置 Dubbo 参数
+
+ Resources/META-INF.spring/dubbo.provider.xml
+
+```xml
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
+ xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
+ http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
+
+ <!-- 应用名 -->
+ <dubbo:application name="user-info-server"/>
+ <!-- 连接到哪个本地注册中心 -->
+ <dubbo:registry id="dubbogo" address="zookeeper://127.0.0.1:2181" />
+ <!-- 用dubbo协议在20880端口暴露服务 -->
+ <dubbo:protocol id="dubbo" name="dubbo" host="127.0.0.1" port="20010" />
+ <!-- 声明需要暴露的服务接口 -->
+ <dubbo:service id="aaa" registry="dubbogo" timeout="3000" interface="org.apache.dubbo.UserProvider" ref="demoService"/>
+ <dubbo:service id="bbb" registry="dubbogo" timeout="3000" interface="org.apache.dubbo.UserProvider" ref="otherService" version="2.0"/>
+ <dubbo:service id="ccc" registry="dubbogo" timeout="3000" interface="org.apache.dubbo.UserProvider" ref="otherService" group="as" version="2.0"/>
+
+ <bean id="demoService" class="org.apache.dubbo.UserProviderImpl" />
+ <bean id="otherService" class="org.apache.dubbo.UserProviderAnotherImpl"/>
+
+</beans>
+```
+
+
+
+启动Provider类,可看到输出如下日志,代表 Dubbo Server 启动成功
+
+```
+[DUBBO] DubboBootstrap is ready., dubbo version: 2.7.7, current host: 127.0.0.1
+[DUBBO] DubboBootstrap has started., dubbo version: 2.7.7, current host: 127.0.0.1
+```
+
+#### Go-Client 启动
+
+对于已经启动的Dubbo服务,如需要开发与其对应的Go-client,需要进行如下步骤:
+
+1. 编写与 Java 适配的 POJO 类 User
+
+
+```go
+import(
+ hessian "github.com/apache/dubbo-go-hessian2"
+)
+
+// 字段需要与 Java 侧对应,首字母大写
+type User struct {
+ ID string
+ Name string
+ Age int32
+ Time time.Time
+}
+
+
+func (u *User) JavaClassName() string {
+ return "org.apache.dubbo.User" // 需要与 Java 侧 User 类名对应
+}
+
+func init(){
+ hessian.RegisterPOJO(&pkg.User{}) // 注册 POJO
+}
+```
+
+2. 编写与 Java 侧一致的客户端存根类,其接口方法需要与Java侧对应
+
+ 规定第一个参数必须为 context.Context,最后一个返回值必须为 error
+
+```go
+
+import(
+ "dubbo.apache.org/dubbo-go/v3/config"
+)
+
+var (
+ userProvider = &pkg.UserProvider{}
+)
+
+// UserProvider 客户端存根类
+type UserProvider struct {
+ // dubbo标签,用于适配go侧客户端大写方法名 -> java侧小写方法名,只有 dubbo 协议客户端才需要使用
+ GetUser func(ctx context.Context, req int32) (*User, error) `dubbo:"getUser"`
+}
+
+func init(){
+ // 注册客户端存根类到框架,实例化客户端接口指针 userProvider
+ config.SetConsumerService(userProvider)
+}
+
+```
+
+3. 撰写配置文件: dubbogo.yml
+
+```yaml
+dubbo:
+ registries:
+ demoZK: # 定义注册中心ID
+ protocol: zookeeper
+ timeout: 3s
+ address: 127.0.0.1:2181
+ consumer:
+ references:
+ UserProvider: # 存根类名
+ protocol: dubbo # dubbo 协议,默认 hessian2 序列化方式
+ interface: org.apache.dubbo.UserProvider # 接口需要与Java侧对应
+ logger:
+ zap-config:
+ level: info # 日志级别
+```
+
+或者使用Triple + Hessian2 序列化请求Server。本例子如果跟Java Server互通则不能用Triple。
+
+```yaml
+dubbo:
+ registries:
+ demoZK:
+ protocol: zookeeper
+ timeout: 3s
+ address: 127.0.0.1:2181
+ consumer:
+ references:
+ UserProvider:
+ protocol: tri # triple 协议
+ serialization: hessian2 # 序列化方式 hessian2,triple 协议默认为 pb 序列化,不配置会报错
+ interface: org.apache.dubbo.UserProvider
+ logger:
+ zap-config:
+ level: info
+```
+
+4. 撰写 main.go 文件,发起调用
+
+```go
+func main(){
+ config.Load()
+ var i int32 = 1
+ user, err := userProvider.GetUser2(context.TODO(), i)
+ if err != nil {
+ panic(err)
+ }
+ logger.Infof("response result: %v", user)
+}
+```
+
+5. 可查看到调用成功的日志,符合预期
+
+- go-client
+
+```bash
+response result: User{ID:1, Name:userCode get, Age:48, Time:2021-10-21 20:25:26.009 +0800 CST}
+```
+
+### 2.2 Java-Client -> Go-Server
+
+#### Go-Server 启动
+
+1. 定义配置文件
+
+```yaml
+dubbo:
+ registries:
+ demoZK:
+ protocol: zookeeper
+ address: 127.0.0.1:2181
+ protocols:
+ dubbo:
+ name: dubbo
+ port: 20000
+ provider:
+ services:
+ UserProvider:
+ interface: org.apache.dubbo.UserProvider
+ logger:
+ zap-config:
+ level: info
+```
+
+2. 引入传输结构,定义服务以及方法名映射
+
+```go
+
+type UserProvider struct {
+}
+
+func (u *UserProvider) GetUser(ctx context.Context, req int32) (*User, error) {
+ var err error
+ logger.Infof("req:%#v", req)
+ user := &User{}
+ user.ID = strconv.Itoa(int(req))
+ return user, err
+}
+
+// MethodMapper 定义方法名映射,从 Go 的方法名映射到 Java 小写方法名,只有 dubbo 协议服务接口才需要使用
+func (s *UserProvider) MethodMapper() map[string]string {
+ return map[string]string{
+ "GetUser": "getUser",
+ }
+}
+
+func init(){
+ config.SetProviderService(&pkg.UserProvider{})
+}
+
+```
+
+3. 启动服务
+
+```go
+// export DUBBO_GO_CONFIG_PATH=dubbogo.yml
+func main() {
+ if err := config.Load(); err != nil {
+ panic(err)
+ }
+ select {}
+}
+```
+
+
+
+#### Java-Client 启动
+
+1. Java 客户端 Spring 配置
+
+ resources/META-INF.spring/dubbo.consumer.xml
+
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <!--
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+ <beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
+ xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
+ http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
+
+
+ <!-- 消费方应用名,用于计算依赖关系,不是匹配条件,不要与提供方一样 -->
+ <dubbo:application name="user-info-client" />
+ <!-- 连接到哪个本地注册中心 -->
+ <dubbo:registry id="dubbogo" address="zookeeper://127.0.0.1:2181" />
+ <!-- dubbo.registry.address from dubbo.properties -->
+ <!-- dubbo:registry address="${dubbo.registry.address}" / -->
+
+ <!-- 用dubbo协议在20880端口暴露服务 -->
+ <dubbo:protocol id="dubbo" name="dubbo" />
+
+ <!-- 声明需要使用的服务接口 -->
+ <dubbo:reference registry="dubbogo" check="false" id="userProvider" protocol="dubbo" interface="org.apache.dubbo.UserProvider">
+ <!--<dubbo:parameter key="heartbeat" value="10000"/ -->
+ </dubbo:reference>
+
+ <dubbo:reference registry="dubbogo" check="false" id="userProvider1" protocol="dubbo" version="2.0" interface="org.apache.dubbo.UserProvider">
+ </dubbo:reference>
+ <dubbo:reference registry="dubbogo" check="false" id="userProvider2" protocol="dubbo" version="2.0" group="as" interface="org.apache.dubbo.UserProvider">
+ </dubbo:reference>
+ </beans>
+
+ ```
+
+2. 发起调用
+
+```java
+
+public class Consumer {
+ // Define a private variable (Required in Spring)
+ private static UserProvider userProvider;
+
+ public static void main(String[] args) throws Exception {
+ ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new String[]{"META-INF/spring/dubbo.consumer.xml"});
+ userProvider = (UserProvider)context.getBean("userProvider");
+ testGetUser();
+ }
+
+
+ private static void testGetUser() throws Exception {
+ User user = userProvider.getUser(1);
+ System.out.println(user.getId());
+ }
+}
+```
+
diff --git a/content/zh/docs3-building/golang-sdk/samples/grpc_cli.md b/content/zh/docs3-building/golang-sdk/samples/grpc_cli.md
new file mode 100644
index 0000000000..b18cde10a1
--- /dev/null
+++ b/content/zh/docs3-building/golang-sdk/samples/grpc_cli.md
@@ -0,0 +1,21 @@
+---
+title: 使用 grpc_cli 调试 Dubbo-go 服务
+weight: 10
+type: docs
+---
+
+## 1. 简介
+
+grpc_cli 工具是 gRPC 生态用于调试服务的工具,在 server 开启[反射服务](https://github.com/grpc/grpc/blob/master/doc/server-reflection.md)的前提下,可以获取到服务的 proto 文件、服务名、方法名、参数列表,以及发起 gRPC 调用。
+
+Triple 协议兼容 gRPC 生态,并默认开启 gRPC 反射服务,因此可以直接使用 grpc_cli 调试 triple 服务。
+
+## 2. 安装grpc_cli
+
+参考[文档](https://github.com/grpc/grpc/blob/master/doc/command_line_tool.md)
+
+## 3. 例子
+
+参考 [3.0 快速开始](https://dubbogo.github.io/zh-cn/docs/user/quickstart/3.0/quickstart_triple/)
+
+
diff --git a/content/zh/docs3-building/golang-sdk/samples/mesh_router.md b/content/zh/docs3-building/golang-sdk/samples/mesh_router.md
new file mode 100644
index 0000000000..c63ad5fd18
--- /dev/null
+++ b/content/zh/docs3-building/golang-sdk/samples/mesh_router.md
@@ -0,0 +1,144 @@
+---
+title: 路由规则
+weight: 12
+type: docs
+---
+
+## 路由规则介绍
+[《微服务Mesh路由方案草案V2》](https://www.yuque.com/docs/share/c132d5db-0dcb-487f-8833-7c7732964bd4?# )
+
+## 简介
+
+路由规则,简单来说就是根据**特定的条件**,将**特定的请求**流量发送到**特定的服务提供者**。从而实现流量的分配。
+
+在 Dubbo3 统一路由规则的定义中,需要提供两个yaml格式的资源:virtual service 和 destination rule。其格式和 service mesh 定义的路由规则非常相似。
+- virtual service
+
+定义host,用于和destination rule建立联系。\
+定义 service 匹配规则\
+定义 match 匹配规则\
+匹配到特定请求后,进行目标集群的查找和验证,对于为空情况,使用 fallback 机制。
+
+- destination rule
+
+定义特定集群子集,以及子集所适配的标签,标签从 provider 端暴露的 url 中获取,并尝试匹配。
+
+## 提供能力
+### 基于配置中心的路由配置
+
+sample示例参见[Mesh Router](https://github.com/apache/dubbo-go-samples/tree/master/route/meshroute)
+
+#### 1. 路由规则文件注解
+
+路由规则只针对客户端,对于服务端,只需要在服务提供时打好特定的参数标签即可。
+
+##### 1.1 virtual-service
+
+```yaml
+apiVersion: service.dubbo.apache.org/v1alpha1
+kind: VirtualService
+metadata: {name: demo-route}
+spec:
+ dubbo:
+ # 使用正则表达式匹配service名,只有个满足该service名的请求才能路由。
+ # 就此例子来说,不满足service名的请求会直接找不到provider
+ # - services:
+ # - { regex: org.apache.dubbo.UserProvider* }
+ - routedetail:
+ - match:
+ # 匹配规则,如果(sourceLabel)客户端url满足存在参数 `trafficLabel: xxx` 的才能匹配成功
+ - sourceLabels: {trafficLabel: xxx}
+ name: xxx-project
+ route: # 一旦匹配上述match规则,将选择 dest_rule 里定义的名为 isolation 的子集
+ - destination: {host: demo, subset: isolation}
+ - match:
+ - sourceLabels: {trafficLabel: testing-trunk}
+ name: testing-trunk
+ route: # 一旦匹配上述match规则,将选择 dest_rule 里定义的名为 testing-trunk 的子集
+ - destination: {host: demo, subset: testing-trunk}
+ - name: testing # 没有match,兜底逻辑,上述不满足后一定会被匹配到。
+ route:
+ - destination: {host: demo, subset: testing}
+ services:
+ - {exact: com.apache.dubbo.sample.basic.IGreeter}
+ hosts: [demo] # 匹配dest_rule.yml里面的 host 为demo
+```
+
+##### 1.2 destination-rule
+
+```yaml
+apiVersion: service.dubbo.apache.org/v1alpha1
+kind: DestinationRule
+metadata: { name: demo-route }
+spec:
+ host: demo
+ subsets:
+ - labels: { env-sign: xxx, tag1: hello }
+ name: isolation
+ - labels: { env-sign: yyy }
+ name: testing-trunk
+ - labels: { env-sign: zzz }
+ name: testing
+ trafficPolicy:
+ loadBalancer: { simple: ROUND_ROBIN }
+```
+
+#### 2. client、server 路由参数设置
+
+- client 端
+
+ dubbogo.yml
+
+ 定义配置中心
+
+```yaml
+ config-center:
+ protocol: zookeeper
+ address: 127.0.0.1:2181
+ data-id: "dubbo-go-samples-configcenter-zookeeper-client"
+```
+
+在代码中通过 API 将配置发布至配置中心,也可预先手动配置。
+
+```go
+dynamicConfiguration, err := config.GetRootConfig().ConfigCenter.GetDynamicConfiguration()
+if err != nil {
+ panic(err)
+}
+
+// publish mesh route config
+err = dynamicConfiguration.PublishConfig("dubbo.io.MESHAPPRULE", "dubbo", MeshRouteConf)
+if err != nil {
+ return
+}
+```
+
+
+
+server 端
+
+```yaml
+dubbo:
+ registries:
+ demoZK:
+ protocol: zookeeper
+ timeout: 3s
+ address: 127.0.0.1:2181
+ protocols:
+ triple:
+ name: tri
+ port: 20000
+ provider:
+ services:
+ GreeterProvider:
+ interface: com.apache.dubbo.sample.basic.IGreeter # must be compatible with grpc or dubbo-java
+ params:
+ env-sign: zzz # server label, 对应 destination Rule中的testing,即兜底逻辑
+```
+
+#### 3. 运行方法
+
+直接使用goland运行本示例
+
+
+运行后,可观测到所有客户端流量都路由至 server,根据source label,没有命中的virtualService,因此路由至兜底testing。
diff --git a/content/zh/docs3-building/golang-sdk/samples/metrics.md b/content/zh/docs3-building/golang-sdk/samples/metrics.md
new file mode 100644
index 0000000000..8bf41d453c
--- /dev/null
+++ b/content/zh/docs3-building/golang-sdk/samples/metrics.md
@@ -0,0 +1,207 @@
+---
+title: Metrics 数据上报
+weight: 7
+type: docs
+---
+
+参考Samples: [dubbo-go-samples/metrics](https://github.com/apache/dubbo-go-samples/tree/master/metrics)
+
+## 1. 数据上报配置
+
+在不指定 metrics: 字段的时候,默认开启拉模式 prometheus 数据上报,端口默认为9090,监听path默认为/metrics。可参考如下服务端配置例子来定制化。
+
+```yaml
+dubbo:
+ application:
+ version: 3.0.0-rc3 # 版本号
+ metrics:
+ enable: true # default is true
+ path: /custom-metrics-path # default is /metrics
+ port: 9091 # default is 9090
+ namespace: dubbo # default is dubbo 作为数据上报 metrics 的前缀
+ registries:
+ myzk:
+ protocol: zookeeper
+ address: localhost:2181
+ protocols:
+ triple:
+ name: tri
+ port: 20000
+ provider:
+ services:
+ GreeterProvider:
+ group: dubbo-go # 所属 group,需要与客户端一致
+ interface: com.apache.dubbo.HelloService # 接口名
+```
+
+## 2. 默认数据上报指标
+
+本地启动上述服务端后,可于 localhost:9091/custom-metrics-path 收集到默认数据指标,包含gc、goroutine数目,内存占用情况等。
+
+```yaml
+# HELP go_gc_duration_seconds A summary of the pause duration of garbage collection cycles.
+# TYPE go_gc_duration_seconds summary
+go_gc_duration_seconds{quantile="0"} 3.0916e-05
+go_gc_duration_seconds{quantile="0.25"} 3.0916e-05
+go_gc_duration_seconds{quantile="0.5"} 3.1167e-05
+go_gc_duration_seconds{quantile="0.75"} 0.000164084
+go_gc_duration_seconds{quantile="1"} 0.000164084
+go_gc_duration_seconds_sum 0.000226167
+go_gc_duration_seconds_count 3
+# HELP go_goroutines Number of goroutines that currently exist.
+# TYPE go_goroutines gauge
+go_goroutines 25
+# HELP go_info Information about the Go environment.
+# TYPE go_info gauge
+go_info{version="go1.17.2"} 1
+# HELP go_memstats_alloc_bytes Number of bytes allocated and still in use.
+# TYPE go_memstats_alloc_bytes gauge
+go_memstats_alloc_bytes 6.195808e+06
+# HELP go_memstats_alloc_bytes_total Total number of bytes allocated, even if freed.
+# TYPE go_memstats_alloc_bytes_total counter
+go_memstats_alloc_bytes_total 9.482768e+06
+# HELP go_memstats_buck_hash_sys_bytes Number of bytes used by the profiling bucket hash table.
+# TYPE go_memstats_buck_hash_sys_bytes gauge
+go_memstats_buck_hash_sys_bytes 1.449179e+06
+# HELP go_memstats_frees_total Total number of frees.
+# TYPE go_memstats_frees_total counter
+go_memstats_frees_total 29419
+# HELP go_memstats_gc_cpu_fraction The fraction of this program's available CPU time used by the GC since the program started.
+# TYPE go_memstats_gc_cpu_fraction gauge
+go_memstats_gc_cpu_fraction 0.022937924367975027
+# HELP go_memstats_gc_sys_bytes Number of bytes used for garbage collection system metadata.
+# TYPE go_memstats_gc_sys_bytes gauge
+go_memstats_gc_sys_bytes 5.235864e+06
+# HELP go_memstats_heap_alloc_bytes Number of heap bytes allocated and still in use.
+# TYPE go_memstats_heap_alloc_bytes gauge
+go_memstats_heap_alloc_bytes 6.195808e+06
+# HELP go_memstats_heap_idle_bytes Number of heap bytes waiting to be used.
+# TYPE go_memstats_heap_idle_bytes gauge
+go_memstats_heap_idle_bytes 3.792896e+06
+# HELP go_memstats_heap_inuse_bytes Number of heap bytes that are in use.
+# TYPE go_memstats_heap_inuse_bytes gauge
+go_memstats_heap_inuse_bytes 8.036352e+06
+# HELP go_memstats_heap_objects Number of allocated objects.
+# TYPE go_memstats_heap_objects gauge
+go_memstats_heap_objects 16489
+# HELP go_memstats_heap_released_bytes Number of heap bytes released to OS.
+# TYPE go_memstats_heap_released_bytes gauge
+go_memstats_heap_released_bytes 3.416064e+06
+# HELP go_memstats_heap_sys_bytes Number of heap bytes obtained from system.
+# TYPE go_memstats_heap_sys_bytes gauge
+go_memstats_heap_sys_bytes 1.1829248e+07
+# HELP go_memstats_last_gc_time_seconds Number of seconds since 1970 of last garbage collection.
+# TYPE go_memstats_last_gc_time_seconds gauge
+go_memstats_last_gc_time_seconds 1.635778234064745e+09
+# HELP go_memstats_lookups_total Total number of pointer lookups.
+# TYPE go_memstats_lookups_total counter
+go_memstats_lookups_total 0
+# HELP go_memstats_mallocs_total Total number of mallocs.
+# TYPE go_memstats_mallocs_total counter
+go_memstats_mallocs_total 45908
+# HELP go_memstats_mcache_inuse_bytes Number of bytes in use by mcache structures.
+# TYPE go_memstats_mcache_inuse_bytes gauge
+go_memstats_mcache_inuse_bytes 9600
+# HELP go_memstats_mcache_sys_bytes Number of bytes used for mcache structures obtained from system.
+# TYPE go_memstats_mcache_sys_bytes gauge
+go_memstats_mcache_sys_bytes 16384
+# HELP go_memstats_mspan_inuse_bytes Number of bytes in use by mspan structures.
+# TYPE go_memstats_mspan_inuse_bytes gauge
+go_memstats_mspan_inuse_bytes 116144
+# HELP go_memstats_mspan_sys_bytes Number of bytes used for mspan structures obtained from system.
+# TYPE go_memstats_mspan_sys_bytes gauge
+go_memstats_mspan_sys_bytes 131072
+# HELP go_memstats_next_gc_bytes Number of heap bytes when next garbage collection will take place.
+# TYPE go_memstats_next_gc_bytes gauge
+go_memstats_next_gc_bytes 7.935184e+06
+# HELP go_memstats_other_sys_bytes Number of bytes used for other system allocations.
+# TYPE go_memstats_other_sys_bytes gauge
+go_memstats_other_sys_bytes 1.426069e+06
+# HELP go_memstats_stack_inuse_bytes Number of bytes in use by the stack allocator.
+# TYPE go_memstats_stack_inuse_bytes gauge
+go_memstats_stack_inuse_bytes 753664
+# HELP go_memstats_stack_sys_bytes Number of bytes obtained from system for stack allocator.
+# TYPE go_memstats_stack_sys_bytes gauge
+go_memstats_stack_sys_bytes 753664
+# HELP go_memstats_sys_bytes Number of bytes obtained from system.
+# TYPE go_memstats_sys_bytes gauge
+go_memstats_sys_bytes 2.084148e+07
+# HELP go_threads Number of OS threads created.
+# TYPE go_threads gauge
+go_threads 12
+```
+
+## 3. 调用指标 RT
+
+启动例子中的客户端,经过几次调用后,会发现增加了对应的数据指标,以默认namespace dubbo 为前缀。
+
+```yaml
+# HELP dubbo_provider_service_rt
+# TYPE dubbo_provider_service_rt gauge
+dubbo_provider_service_rt{group="dubbo-go",method="SayHello",service="com.apache.dubbo.HelloService",timeout="",version="3.0.0-rc3"} 127542
+```
+
+可看到对应接口名、方法名的请求rt时间。该部分调用指标待后续完善。
+
+## 4. 手动数据上报
+
+可在业务代码中调用API进行手动数据上报。支持Counter、Summary、Gauge 类型,并支持多个标签。上报后即可收集。
+
+```go
+import "dubbo.apache.org/dubbo-go/v3/metrics/prometheus"
+
+for {
+ // metrics refresh per second
+ time.Sleep(time.Second)
+ prometheus.IncSummary("test_summary", rand.Float64())
+ prometheus.IncSummaryWithLabel("test_summary_with_label", rand.Float64(), map[string]string{
+ "summarylabel1": "value1", // label and value for this summary
+ "summarylabel2": "value2",
+ })
+
+ prometheus.IncCounter("test_counter")
+ prometheus.IncCounterWithLabel("test_counter_with_label", map[string]string{
+ "counterlabel1": "value1", // label and value for this counter
+ "counterlabel2": "value2",
+ })
+
+ prometheus.SetGauge("test_gauge", rand.Float64())
+ prometheus.SetGaugeWithLabel("test_gauge_with_label", rand.Float64(), map[string]string{
+ "gaugelabel1": "value1",
+ "gaugelabel2": "value2",
+ })
+ }
+```
+
+运行一段时间后,可以收集到如下用户定义指标
+
+```yaml
+# HELP dubbo_test_counter
+# TYPE dubbo_test_counter counter
+dubbo_test_counter 463
+# HELP dubbo_test_counter_with_label
+# TYPE dubbo_test_counter_with_label counter
+dubbo_test_counter_with_label{counterlabel1="value1",counterlabel2="value2"} 463
+# HELP dubbo_test_gauge
+# TYPE dubbo_test_gauge gauge
+dubbo_test_gauge 0.7402836247772934
+# HELP dubbo_test_gauge_with_label
+# TYPE dubbo_test_gauge_with_label gauge
+dubbo_test_gauge_with_label{gaugelabel1="value1",gaugelabel2="value2"} 0.8360973807546456
+# HELP dubbo_test_summary
+# TYPE dubbo_test_summary summary
+dubbo_test_summary_sum 228.1800106582441
+dubbo_test_summary_count 463
+# HELP dubbo_test_summary_with_label
+# TYPE dubbo_test_summary_with_label summary
+dubbo_test_summary_with_label{summarylabel1="value1",summarylabel2="value2",quantile="0.5"} 0.5174757569778469
+dubbo_test_summary_with_label{summarylabel1="value1",summarylabel2="value2",quantile="0.75"} 0.734268575017709
+dubbo_test_summary_with_label{summarylabel1="value1",summarylabel2="value2",quantile="0.9"} 0.9059918694279894
+dubbo_test_summary_with_label{summarylabel1="value1",summarylabel2="value2",quantile="0.98"} 0.9761803018478838
+dubbo_test_summary_with_label{summarylabel1="value1",summarylabel2="value2",quantile="0.99"} 0.9820270046489341
+dubbo_test_summary_with_label{summarylabel1="value1",summarylabel2="value2",quantile="0.999"} 0.9986025122460248
+dubbo_test_summary_with_label_sum{summarylabel1="value1",summarylabel2="value2"} 233.609026131067
+dubbo_test_summary_with_label_count{summarylabel1="value1",summarylabel2="value2"} 463
+```
+
+
diff --git a/content/zh/docs3-building/golang-sdk/samples/pixiu-nacos-triple.md b/content/zh/docs3-building/golang-sdk/samples/pixiu-nacos-triple.md
new file mode 100644
index 0000000000..e20304c39c
--- /dev/null
+++ b/content/zh/docs3-building/golang-sdk/samples/pixiu-nacos-triple.md
@@ -0,0 +1,71 @@
+---
+title: 使用 Pixiu 暴露 Dubbo-go 服务
+weight: 9
+type: docs
+---
+
+Dubbo-go-pixiu 网关支持调用 GO/Java 的 Dubbo 集群。在 Dubbo-go 3.0 的场景下,我们可以通过 Pixiu 网关,在集群外以 HTTP 协议请求 pixiu 网关,在网关层进行协议转换,进一步调用集群内的Dubbo-go 服务。
+
+
+
+用户调用 Dubbo-go 服务的 path 为http://$(app_name)/$(service_name)/$(method)
+
+例如一个proto文件内有如下定义:
+
+```protobuf
+package org.apache.dubbo.quickstart.samples;
+
+service UserProvider {
+ rpc SayHello (HelloRequest) returns (User) {}
+}
+
+message HelloRequest {
+ string name = 1;
+}
+```
+
+并在dubbo-go 服务启动时在dubbogo.yml 内配置应用名为my-dubbogo-app:
+
+```yaml
+dubbo:
+ application:
+ name: my-dubbogo-app
+```
+
+pixiu 网关即可解析 path 为 http://my-dubbogo-app/org.apache.dubbo.quickstart.samples.UserProvider/SayHello 的路由,并转发至对应服务。来自外部HTTP 请求的 body 为 json 序列化的请求参数,例如 {"name":"test"}。
+
+我们目前推荐使用 Nacos 作为注册中心。
+
+用户可以在自己的集群里部署我们的demo,集群最好拥有暴露 lb 类型 service 的能力,从而可以在公网访问至集群内的服务,您也可以直接集群内进行请求。针对您的集群,执行:
+
+```bash
+$ kubectl apply -f https://raw.githubusercontent.com/dubbogo/triple-pixiu-demo/master/deploy/pixiu-triple-demo.yml
+```
+
+会在 dubbogo-triple-nacos 命名空间下创建如下资源,包含三个 triple-server,一个pixiu网关,一个 nacos server。并通过 Servcie 将服务暴露至公网。
+
+```plain
+namespace/dubbogo-triple-nacos created
+service/dubbo-go-nacos created
+deployment.apps/dubbogo-nacos-deployment created
+deployment.apps/pixiu created
+deployment.apps/server created
+service/pixiu created
+```
+
+获取 pixiu 公网 ip 并进行调用
+
+```plain
+$ kubectl get svc -n dubbogo-triple-nacos
+NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
+dubbo-go-nacos ClusterIP 192.168.123.204 <none> 8848/TCP 32s
+pixiu LoadBalancer 192.168.156.175 30.XXX.XXX.XX 8881:30173/TCP 32s
+```
+
+通过curl 调用 demo 服务,并获得响应结果。
+
+```bash
+$ curl -X POST -d '{"name":"laurence"}' http://30.XXX.XXX.XX:8881/dubbogoDemoServer/org.apache.dubbo.laurence.samples.UserProvider/SayHello
+{"name":"Hello laurence","id":"12345","age":21}
+```
+
diff --git a/content/zh/docs3-building/golang-sdk/samples/registry.md b/content/zh/docs3-building/golang-sdk/samples/registry.md
new file mode 100644
index 0000000000..2a31e27b0f
--- /dev/null
+++ b/content/zh/docs3-building/golang-sdk/samples/registry.md
@@ -0,0 +1,110 @@
+---
+title: 注册中心配置
+weight: 4
+type: docs
+---
+
+参考samples [dubbo-go-samples/registry](https://github.com/apache/dubbo-go-samples/tree/master/registry)
+
+## Registry 注册中心配置
+
+- **Nacos 注册中心**
+
+```yaml
+dubbo:
+ application: # 应用信息,服务启动后会将相关信息注册到注册中心,可被客户端从 url 中识别
+ name: myApp # application=myApp; name=myApp
+ module: opensource # module=opensource
+ organization: dubbo # organization=dubbo
+ owner: laurence # owner=laurence
+ version: myversion # app.version=myversion
+ environment: pro # environment=pro
+ registries:
+ nacosWithCustomGroup:
+ protocol: nacos # 注册中心选择 nacos
+ address: 127.0.0.1:8848 # nacos ip
+ group: myGroup # nacos group, 默认 DEFAULT_GROUP
+ namespace: 9fb00abb-278d-42fc-96bf-e0151601e4a1 # nacos namespaceID, should be created before. 默认public
+ username: abc
+ password: abc
+ protocols:
+ dubbo:
+ name: dubbo
+ port: 20000
+ provider:
+ services:
+ UserProviderWithCustomGroupAndVersion: # 接口三元组:接口名、版本号、分组。client 和 server 需要保持一致。
+ interface: org.apache.dubbo.UserProvider.Test # 接口名必填
+ version: myInterfaceVersion # 默认为空
+ group: myInterfaceGroup # 默认为空
+```
+
+dubbogo 的注册中心配置的 group、namespace、username、password,均与 nacos 相关概念对应。
+
+- **Zookeeper 注册中心**
+
+```yaml
+dubbo:
+ # application: 与nacos 一致,不再赘述
+ registries:
+ demoZK:
+ protocol: zookeeper # 注册中心选择 nacos
+ address: 127.0.0.1:2181 # zookeeper ip
+ group: myGroup # nacos group, 默认 dubbo
+ protocols:
+ triple:
+ name: tri
+ port: 20000
+ provider:
+ services:
+ UserProviderWithCustomGroupAndVersion: # 接口三元组:接口名、版本号、分组。client 和 server 需要保持一致。
+ interface: com.apache.dubbo.sample.basic.IGreeter # 接口名必填
+ version: myInterfaceVersion # 默认为空
+ group: myInterfaceGroup # 默认为空
+```
+
+zookeeper 注册时,provider 端将接口信息注册在` /$(group)/$(interface)/providers` 节点,以上面配置为例,注册的 zk path 为 `/myGroup/com.apache.dubbo.sample.basic.IGreeter/providers/`
+
+consumer 端注册在 /$(group)/$(interface)/consumers 作统计用。
+
+- **ETCD 注册中心**
+
+```yaml
+dubbo:
+ registries:
+ etcd:
+ protocol: etcdv3
+ timeout: 3s
+ address: 127.0.0.1:2379
+ protocols:
+ dubbo:
+ name: dubbo
+ port: 20000
+ provider:
+ services:
+ UserProvider:
+ interface: org.apache.dubbo.UserProvider
+```
+
+- **应用级服务注册发现**
+
+```yaml
+dubbo:
+ registries:
+ demoZK:
+ protocol: zookeeper # nacos/zookeeper
+ address: 127.0.0.1:2181
+ registry-type: service # 使用应用级服务发现
+ metadata-report: # 配置元数据中心
+ protocol: zookeeper
+ address: 127.0.0.1:2181
+ protocols:
+ triple:
+ name: tri
+ port: 20000
+ provider:
+ services:
+ GreeterProvider:
+ interface: com.apache.dubbo.sample.basic.IGreeter
+```
+
diff --git a/content/zh/docs3-building/golang-sdk/samples/samples_repo.md b/content/zh/docs3-building/golang-sdk/samples/samples_repo.md
new file mode 100644
index 0000000000..2749e29b39
--- /dev/null
+++ b/content/zh/docs3-building/golang-sdk/samples/samples_repo.md
@@ -0,0 +1,173 @@
+---
+title: dubbo-go 3.0 示例仓库
+keywords: dubbo-go 3.0 示例仓库
+description: dubbo-go 3.0 示例仓库
+---
+
+为了方便 Dubbogo 框架用户的使用,我们提供了 Samples 仓库以供用户参考:
+
+[【Dubbo-go-samples 仓库地址】](https://github.com/apache/dubbo-go-samples)
+
+## 1. Samples 仓库包含的例子
+
+* config-api: 使用 API 进行配置初始化
+* configcenter: 使用不同的配置中心,目前支持三种:zookeeper、apollo、和 nacos
+* context: 如何使用上下文传递 attachment
+* direct: 直连模式
+* game: 游戏服务例子
+* generic: 泛化调用
+* rpc: RPC 调用例子, 包含 Triple、Dubbo等协议以及跨语言/gRPC互通示例
+* helloworld: RPC调用入门例子
+* logger: 日志例子
+* registry: 展示与不同注册中心的对接,包含了 zk、nacos、etcd
+* metrics: 数据上报
+* filter: 使用提供filter和自定义filter的例子
+* registry/servicediscovery:应用级服务发现例子
+* router: 路由例子
+* tracing: 链路追踪例子
+
+## 2. 如何运行
+
+目前有三种方式来运行 dubbo-go 的示例:
+
+1. 通过 bash 命令快速开始: 通过简单的命令行启动样例以及进行单元测试
+2. 在 IDE 中快速开始,这也是**推荐**的方式: 在工程 ".run" 子目录下,提供了所有示例的 GoLand 运行配置文件,因此用户可以简单在 IDE 中单击运行所有的示例。
+3. 在 IDE 中手工配置并运行: 为了完整性的目的,也为了万一您不使用 GoLand 而使用其他的 IDE,这里也提供了如何一步一步的配置的指南,帮助用户理解如何在 IDE 中配置,运行或者调试 dubbo-go 的示例。
+
+### 2.1 通过 命令行 快速开始
+
+*前置条件:需要 docker 环境就绪*
+
+下面我们将使用 "helloworld" 作为示例:
+
+1. **启动注册中心(比如 zookeeper)**
+
+ ```bash
+ make -f build/Makefile docker-up
+ ```
+
+ 当看到类似下面的输出信息时,就表明 zookeeper server 启动就绪了。
+
+ ```bash
+ > Starting dependency services with ./integrate_test/dockercompose/docker-compose.yml
+ Docker Compose is now in the Docker CLI, try `docker compose up`
+
+ Creating network "dockercompose_default" with the default driver
+ Creating dockercompose_zookeeper_1 ... done
+ Creating etcd ... done
+ Creating nacos-standalone ... done
+ ```
+
+ 如果要停掉注册中心,可以通过运行以下的命令完成:
+
+ ```bash
+ make -f build/Makefile docker-down
+ ```
+
+2. **启动服务提供方**
+
+ ```bash
+ cd helloworld/go-server/cmd
+ export DUBBO_GO_CONFIG_PATH="../conf/dubbogo.yml"
+ go run .
+ ```
+
+ 当看到类似下面的输出信息时,就表明服务提供方启动就绪了。
+
+ ```bash
+ 2021/10/27 00:33:10 Connected to 127.0.0.1:2181
+ 2021/10/27 00:33:10 Authenticated: id=72057926938066944, timeout=10000
+ 2021/10/27 00:33:10 Re-submitting `0` credentials after reconnect
+ ```
+
+3. **运行服务调用方**
+
+ ```bash
+ cd helloworld/go-client/cmd
+ export DUBBO_GO_CONFIG_PATH="../conf/dubbogo.yml"
+ go run .
+ ```
+
+ 当以下的信息输出时,说明 `go-client` 调用 `go-server` 成功。
+
+ ```bash
+ 2021-10-27T00:40:44.879+0800 DEBUG triple/dubbo3_client.go:106 TripleClient.Invoke: get reply = name:"Hello laurence" id:"12345" age:21
+ 2021-10-27T00:40:44.879+0800 DEBUG proxy/proxy.go:218 [makeDubboCallProxy] result: name:"Hello laurence" id:"12345" age:21 , err: <nil>
+ 2021-10-27T00:40:44.879+0800 INFO cmd/client.go:51 client response result: name:"Hello laurence" id:"12345" age:21
+ ```
+
+4. **集成测试**
+ 本项目 dubbo-go-samples 除了用来展示如何使用 dubbo-go 中的功能和特性之外,还被用于 apache/dubbo-go 的集成测试。可以按照以下的步骤来运行针对 `go-server` 设计的集成测试:
+
+ 首先启动服务方
+ ```bash
+ cd helloworld/go-server/cmd
+ export DUBBO_GO_CONFIG_PATH="../conf/dubbogo.yml"
+ go run .
+ ```
+
+ 然后切换到单测目录, 设置环境变量,然后执行单测
+ ```bash
+ cd integrate_test/helloworld/tests/integration
+ export DUBBO_GO_CONFIG_PATH="../../../../helloworld/go-client/conf/dubbogo.yml"
+ go test -v
+ ```
+
+ 当以下信息输出时,说明集成测试通过。
+
+ ```bash
+ > Running integration test for application go-server
+ ...
+ --- PASS: TestSayHello (0.01s)
+ PASS
+ ok github.com/apache/dubbo-go-samples/integrate_test/helloworld/tests/integration 0.119s
+ ```
+
+7. **关闭并清理**
+ ```bash
+ make -f build/Makefile clean docker-down
+ ```
+
+*以下的两种运行方式都与 IDE 有关。这里我们以 Intellij GoLand 为例来讨论。*
+
+### 2.2 在 IDE 中快速开始
+
+一旦在 GoLand 中打开本项目,可以发现,在 "Run Configuration" 弹出菜单中已经存在了一系列事先配置好了的用来运行相关服务提供方和调用方的选项,例如:"helloworld-go-server" 和 "helloworld-go-client"。
+
+可以选择其中的任意一个快速启动相关示例。当然在运行之前,假设需要的注册中心已经事先启动了,不然用例将会失败。您可以选择手动自行启动的方式,也可以利用工程中提供的 "docker-compose.yml" 在启动注册中心的 docker 实例。选择后者的话,可以参考[第三种方式](#3-manually-run-in-ide)中的细节。
+
+### 2.3.在 IDE 中手工运行
+
+这里以 *Intellij GoLand* 为例。在 GoLand 中打开 dubbo-go-samples 工程之后,按照以下的步骤来运行/调试本示例:
+
+1. **启动 zookeeper 服务器**
+
+ 打开 "integrate_test/dockercompose/docker-compose.yml" 这个文件,然后点击位于编辑器左边 gutter 栏位中的 ▶︎▶︎ 图标运行,"Service" Tab 应当会弹出并输出类似下面的文本信息:
+ ```
+ Deploying 'Compose: docker'...
+ /usr/local/bin/docker-compose -f ...integrate_test/dockercompose/docker-compose.yml up -d
+ Creating network "docker_default" with the default driver
+ Creating docker_zookeeper_1 ...
+ 'Compose: docker' has been deployed successfully.
+ ```
+
+2. **启动服务提供方**
+
+ 打开 "helloworld/go-server/cmd/server.go" 文件,然后点击左边 gutter 栏位中紧挨着 "main" 函数的 ▶︎ 图标,并从弹出的菜单中选择 "Modify Run Configuration...",并确保以下配置的准确:
+ * Working Directory: "helloworld/go-server" 目录的绝对路径,比如: */home/dubbo-go-samples/helloworld/go-server*
+ * Environment: DUBBO_GO_CONFIG_PATH="../conf/dubbogo.yml"
+
+ 这样示例中的服务端就准备就绪,随时可以运行了。
+
+3. **运行服务消费方**
+
+ 打开 "helloworld/go-client/cmd/client.go" 这个文件,然后从左边 gutter 栏位中点击紧挨着 "main" 函数的 ▶︎ 图标,然后从弹出的菜单中选择 "Modify Run Configuration...",并确保以下配置的准确:
+ * Working Directory: "helloworld/go-client" 目录的绝对路径,比如: */home/dubbo-go-samples/helloworld/go-client*
+ * Environment: DUBBO_GO_CONFIG_PATH="../conf/dubbogo.yml"
+
+ 然后就可以运行并调用远端的服务了,如果调用成功,将会有以下的输出:
+ ```
+ [2021-02-03/16:19:30 main.main: client.go: 66] response result: &{A001 Alex Stocks 18 2020-02-04 16:19:30.422 +0800 CST}
+ ```
+
+如果需要调试该示例或者 dubbo-go 框架,可以在 IDE 中从 "Run" 切换到 "Debug"。如果要结束的话,直接点击 ◼︎ 就好了。
diff --git a/content/zh/docs3-building/golang-sdk/samples/service-discovery.md b/content/zh/docs3-building/golang-sdk/samples/service-discovery.md
new file mode 100644
index 0000000000..ccb2f23a9d
--- /dev/null
+++ b/content/zh/docs3-building/golang-sdk/samples/service-discovery.md
@@ -0,0 +1,56 @@
+---
+title: 应用级服务发现
+weight: 11
+type: docs
+---
+
+参考文章[**《Dubbo 迈出云原生重要一步 应用级服务发现解析》**](https://baijiahao.baidu.com/s?id=1669266413887039723&wfr=spider&for=pc)
+
+参考仓库:[dubbo-go-samples/registry/serivcediscovery](https://github.com/apache/dubbo-go-samples/tree/master/registry/servicediscovery)
+
+## 配置方案
+
+- Consumer 端
+
+```yaml
+dubbo:
+ registries:
+ demoZK:
+ protocol: nacos
+ address: 127.0.0.1:8848
+ registry-type: service # 指定该注册中心为应用级服务发现,不填默认为接口级
+ metadata-report: # 定义元数据中心
+ protocol: nacos # 元数据中心可选nacos/zk
+ address: 127.0.0.1:8848
+ consumer:
+ references:
+ GreeterClientImpl:
+ protocol: tri
+ interface: com.apache.dubbo.sample.basic.IGreeter
+```
+
+
+
+- Provider 端
+
+```yaml
+dubbo:
+ registries:
+ demoZK:
+ protocol: nacos
+ address: 127.0.0.1:8848
+ registry-type: service # 指定该注册中心为应用级服务发现,不填默认为接口级
+ metadata-report: # 定义元数据中心
+ protocol: nacos # 元数据中心可选nacos/zk
+ address: 127.0.0.1:8848
+ protocols:
+ triple:
+ name: tri
+ port: 20000
+ provider:
+ services:
+ GreeterProvider:
+ interface: com.apache.dubbo.sample.basic.IGreeter
+```
+
+相比于常规配置,定义好registry-type: service, 并且定义好元数据中心后,将会使用应用级服务注册/服务发现。
diff --git a/content/zh/docs3-building/golang-sdk/samples/start-check.md b/content/zh/docs3-building/golang-sdk/samples/start-check.md
new file mode 100644
index 0000000000..2427919337
--- /dev/null
+++ b/content/zh/docs3-building/golang-sdk/samples/start-check.md
@@ -0,0 +1,29 @@
+---
+title: dubbogo 3.0 启动时检查
+keywords: dubbogo 3.0 启动时检查
+description: dubbogo 3.0 启动时检查
+---
+
+# 启动时检查
+
+在启动时检查依赖的服务是否可用
+
+Dubbo-go 缺省会在启动时检查依赖的服务是否可用,不可用时会抛出异常,阻止应用初始化完成,以便上线时,能及早发现问题,默认 check="true",并等待3s。
+
+可以通过 check="false" 关闭检查,比如,测试时,有些服务不关心,或者出现了循环依赖,必须有一方先启动。
+
+关闭 check 后,请注意 provider数量比较多时, consumer 订阅 provider 生成服务字典可能会有一定延迟,如果 consumer 一启动就对外提供服务,
+可能会造成"冷启动"。所以在这个时候,请对服务进行预热。
+
+示例:
+
+```yaml
+dubbo:
+ consumer:
+ check : false
+ reference:
+ myserivce:
+ check: true
+```
+
+
diff --git a/content/zh/docs3-building/golang-sdk/sourcecode/_index.md b/content/zh/docs3-building/golang-sdk/sourcecode/_index.md
new file mode 100644
index 0000000000..4b2a9b3ec7
--- /dev/null
+++ b/content/zh/docs3-building/golang-sdk/sourcecode/_index.md
@@ -0,0 +1,6 @@
+
+---
+title: "源码解读"
+type: docs
+weight: 1
+---
diff --git a/content/zh/docs3-building/golang-sdk/sourcecode/protocol.md b/content/zh/docs3-building/golang-sdk/sourcecode/protocol.md
new file mode 100644
index 0000000000..8960674ca9
--- /dev/null
+++ b/content/zh/docs3-building/golang-sdk/sourcecode/protocol.md
@@ -0,0 +1,24 @@
+---
+title: 网络协议
+type: docs
+weight: 1
+---
+
+对于 Dubbogo 微服务框架,网络协议为远程过程调用中负责网络通信的模块,负责应用层到网络层的数据序列化、打包、请求发起、网络端口监听等功能。Dubbogo 为协议抽象了一套接口如下:
+
+```go
+type Protocol interface {
+ // Export service for remote invocation
+ Export(invoker Invoker) Exporter
+ // Refer a remote service
+ Refer(url *common.URL) Invoker
+ // Destroy will destroy all invoker and exporter, so it only is called once.
+ Destroy()
+}
+```
+
+该接口包含三个方法。其中 Export 方法负责服务的暴露过程。入参 invoker 为dubbo 的概念,其封装了一个可以被调用的实例。在具体网络协议(例如Triple)实现的 Export 方法中,会针对特定的协议,将封装有一定逻辑的可调用实例 Invoker 以网络端口监听的形式暴露给外部服务,来自外部针对该网络端口的请求将会被 Export 方法开启的监听协程获取,进而根据网络协议进行拆解包和反序列化,得到解析后的请求数据。
+
+Refer 方法负责服务的引用过程,其入参 url 为 dubbo 框架通用的结构,可以描述一个希望引用的服务,url 参数中包含了多个希望引用服务的参数,例如对应服务的接口名(interface),版本号(version),使用协议(protocol) 等等。在具体网络协议(例如Triple)实现的 Refer 方法中,会将特定的网络协议封装到 Invoker 可调用实例的方法中,用户层发起的 RPC 调用即可直接通过返回的 Invoker 对象,发起特定协议的网络请求。
+
+Destroy 方法作用为销毁当前暴露的服务,用于服务下线场景。Dubbogo 框架有优雅下线机制,可以在服务进程终止前以监听信号的形式,下线所有已启动的服务。
\ No newline at end of file
diff --git a/content/zh/docs3-building/golang-sdk/sourcecode/registry.md b/content/zh/docs3-building/golang-sdk/sourcecode/registry.md
new file mode 100644
index 0000000000..ff103a7270
--- /dev/null
+++ b/content/zh/docs3-building/golang-sdk/sourcecode/registry.md
@@ -0,0 +1,52 @@
+---
+title: 注册中心
+type: docs
+weight: 1
+---
+
+Dubbogo 为注册中心抽象了一套接口如下:
+
+```go
+// Registry Extension - Registry
+type Registry interface {
+ common.Node
+
+ // Register is used for service provider calling, register services
+ // to registry. And it is also used for service consumer calling, register
+ // services cared about, for dubbo's admin monitoring.
+ Register(url *common.URL) error
+
+ // UnRegister is required to support the contract:
+ // 1. If it is the persistent stored data of dynamic=false, the
+ // registration data can not be found, then the IllegalStateException
+ // is thrown, otherwise it is ignored.
+ // 2. Unregister according to the full url match.
+ // url Registration information, is not allowed to be empty, e.g:
+ // dubbo://10.20.153.10/org.apache.dubbo.foo.BarService?version=1.0.0&application=kylin
+ UnRegister(url *common.URL) error
+
+ // Subscribe is required to support the contract:
+ // When creating new registry extension, pls select one of the
+ // following modes.
+ // Will remove in dubbogo version v1.1.0
+ // mode1: return Listener with Next function which can return
+ // subscribe service event from registry
+ // Deprecated!
+ // subscribe(event.URL) (Listener, error)
+ // Will replace mode1 in dubbogo version v1.1.0
+ // mode2: callback mode, subscribe with notify(notify listener).
+ Subscribe(*common.URL, NotifyListener) error
+
+ // UnSubscribe is required to support the contract:
+ // 1. If don't subscribe, ignore it directly.
+ // 2. Unsubscribe by full URL match.
+ // url Subscription condition, not allowed to be empty, e.g.
+ // consumer://10.20.153.10/org.apache.dubbo.foo.BarService?version=1.0.0&application=kylin
+ // listener A listener of the change event, not allowed to be empty
+ UnSubscribe(*common.URL, NotifyListener) error
+}
+```
+
+该接口主要包含四个方法,分别是注册、反注册、订阅、取消订阅。顾名思义,概括了客户端和服务端与注册中心交互的动作。针对普通接口级服务注册发现场景,在Provider 服务启动时,会将自身服务接口信息抽象为一个 url,该 url 包含了客户端发起调用所需的所有信息(ip、端口、协议等),服务端的注册中心组件会将该 url 写入注册中心(例如zk)。客户端启动后,在服务引用 Refer 步骤会通过注册中心组件订阅(Subscribe)需要的服务信息,获取到的服务信息以异步事件更新的形式写入客户端缓存,从而在服务发现成功后,可以根据拿到的服务 url 参数,向对应服务提供者发起调用。
+
+##
\ No newline at end of file
diff --git a/content/zh/docs3-building/golang-sdk/tasks/_index.md b/content/zh/docs3-building/golang-sdk/tasks/_index.md
new file mode 100644
index 0000000000..8ff078f3da
--- /dev/null
+++ b/content/zh/docs3-building/golang-sdk/tasks/_index.md
@@ -0,0 +1,6 @@
+---
+type: docs
+title: "任务"
+linkTitle: "任务"
+weight: 1
+---
\ No newline at end of file
diff --git a/content/zh/docs3-building/golang-sdk/tasks/cli/_index.md b/content/zh/docs3-building/golang-sdk/tasks/cli/_index.md
new file mode 100644
index 0000000000..ced6d6abfd
--- /dev/null
+++ b/content/zh/docs3-building/golang-sdk/tasks/cli/_index.md
@@ -0,0 +1,5 @@
+---
+type: docs
+title: "应用模板"
+weight: 9
+---
\ No newline at end of file
diff --git a/content/zh/docs3-building/golang-sdk/tasks/cli/app_template.md b/content/zh/docs3-building/golang-sdk/tasks/cli/app_template.md
new file mode 100644
index 0000000000..12481c940a
--- /dev/null
+++ b/content/zh/docs3-building/golang-sdk/tasks/cli/app_template.md
@@ -0,0 +1,86 @@
+---
+type: docs
+title: 使用 Dubbo-go 应用模板
+weight: 1
+---
+
+## 1. 准备工作
+
+- dubbo-go cli 工具和依赖工具已安装
+
+## 2. 使用 dubbogo-cli 创建项目模板
+
+运行 `dubbogo-cli newApp .`
+
+```plain
+$ mkdir cli-create-server
+$ cd cli-create-server
+$ dubbogo-cli newApp .
+$ tree .
+.
+├── Makefile
+├── api
+│ └── api.proto
+├── build
+│ └── Dockerfile
+├── chart
+│ ├── app
+│ │ ├── Chart.yaml
+│ │ ├── templates
+│ │ │ ├── _helpers.tpl
+│ │ │ ├── deployment.yaml
+│ │ │ ├── service.yaml
+│ │ │ └── serviceaccount.yaml
+│ │ └── values.yaml
+│ └── nacos_env
+│ ├── Chart.yaml
+│ ├── templates
+│ │ ├── _helpers.tpl
+│ │ ├── deployment.yaml
+│ │ └── service.yaml
+│ └── values.yaml
+├── cmd
+│ └── app.go
+├── conf
+│ └── dubbogo.yaml
+├── go.mod
+├── go.sum
+└── pkg
+ └── service
+ └── service.go
+```
+
+生成项目包括几个目录:
+
+- api:放置接口文件:proto文件和生成的pb.go文件
+
+- build:放置构建相关文件
+
+- chart:放置发布用 chart 包、基础环境 chart 包:nacos、mesh(开发中)
+
+- cmd:程序入口
+
+- conf:框架配置
+
+- pkg/service:RPC 服务实现
+
+- Makefile:
+
+ - 镜像、应用名:
+
+ - IMAGE = $(your_repo)/$(namespace)/$(image_name)
+ TAG = 1.0.0
+
+ - APPNAME = dubbo-go-app # 用于 helm 发布,对应 chart 名、应用名和服务名(service名)
+
+ - 提供脚本,例如:
+
+ - make build # 打包镜像并推送
+
+ - make buildx-publish # arm 架构本地打包amd64镜像并推送,依赖 docker buildx
+
+ - make deploy # 通过 helm 发布应用
+
+ - make remove # 删除已经发布的 helm 应用
+
+ - make proto-gen # api/ 下生成 pb.go 文件
diff --git a/content/zh/docs3-building/golang-sdk/tasks/config/_index.md b/content/zh/docs3-building/golang-sdk/tasks/config/_index.md
new file mode 100644
index 0000000000..d7340403c9
--- /dev/null
+++ b/content/zh/docs3-building/golang-sdk/tasks/config/_index.md
@@ -0,0 +1,5 @@
+---
+type: docs
+title: "配置"
+weight: 3
+---
\ No newline at end of file
diff --git a/content/zh/docs3-building/golang-sdk/tasks/config/config_api.md b/content/zh/docs3-building/golang-sdk/tasks/config/config_api.md
new file mode 100644
index 0000000000..41c43dcbc0
--- /dev/null
+++ b/content/zh/docs3-building/golang-sdk/tasks/config/config_api.md
@@ -0,0 +1,100 @@
+---
+type: docs
+title: 使用配置 API 启动应用
+weight: 2
+---
+
+## 1. 准备工作
+
+- dubbo-go cli 工具和依赖工具已安装
+- 创建一个新的 demo 应用
+
+## 2. 使用配置 API 启动应用
+
+用户无需使用配置文件,可直接在代码中以 API 的调用的形式写入配置
+
+### 2.1 修改服务端代码:
+
+```go
+func main() {
+ config.SetProviderService(&GreeterProvider{})
+
+ protocolConfig := config.NewProtocolConfigBuilder().
+ SetPort("20000").
+ SetName("tri").
+ Build()
+
+ serviceConfig := config.NewServiceConfigBuilder().
+ SetInterface(""). // read interface from pb
+ Build()
+
+ providerConfig := config.NewProviderConfigBuilder().
+ AddService("GreeterProvider", serviceConfig).
+ Build()
+
+ rootConfig := config.NewRootConfigBuilder().
+ AddProtocol("triple-protocol-id", protocolConfig). // add protocol, key is custom
+ SetProvider(providerConfig).Build()
+
+ if err := config.Load(config.WithRootConfig(rootConfig)); err != nil {
+ panic(err)
+ }
+ select {}
+}
+
+```
+
+配置 API 看上去写法较为复杂,但单个配置结构的构造过程都是一致的,参考 Java Builder 的设计,我们在配置 API 模块选用 `New().SetA().SetB().Build()`的方式来逐层构造单个配置结构。
+
+完成后,可删除掉go-server/conf 文件夹。
+
+
+
+### 2.2 修改客户端代码:
+
+go-client/cmd/client.go
+
+```go
+func main() {
+ config.SetConsumerService(grpcGreeterImpl)
+
+ referenceConfig := config.NewReferenceConfigBuilder().
+ SetProtocol("tri").
+ SetURL("tri://localhost:20000").
+ SetInterface(""). // read interface name from pb
+ Build()
+
+ consumerConfig := config.NewConsumerConfigBuilder().
+ AddReference("GreeterClientImpl", referenceConfig).
+ Build()
+
+ rootConfig := config.NewRootConfigBuilder().
+ SetConsumer(consumerConfig).Build()
+ if err := config.Load(config.WithRootConfig(rootConfig)); err != nil {
+ panic(err)
+ }
+
+ logger.Info("start to test dubbo")
+ req := &api.HelloRequest{
+ Name: "laurence",
+ }
+ reply, err := grpcGreeterImpl.SayHello(context.Background(), req)
+ if err != nil {
+ logger.Error(err)
+ }
+ logger.Infof("client response result: %v\n", reply)
+}
+
+```
+
+完成后,可删除掉go-client/conf 文件夹。
+
+### 2.3 验证 Config API
+
+分别启动 server 和 client ,查看调用信息。
+
+```
+INFO cmd/client.go:62 client response result: name:"Hello laurence" id:"12345" age:21
+```
+
+
diff --git a/content/zh/docs3-building/golang-sdk/tasks/config/remote_config.md b/content/zh/docs3-building/golang-sdk/tasks/config/remote_config.md
new file mode 100644
index 0000000000..13f211ba67
--- /dev/null
+++ b/content/zh/docs3-building/golang-sdk/tasks/config/remote_config.md
@@ -0,0 +1,47 @@
+---
+type: docs
+title: 远程加载配置启动
+weight: 1
+---
+
+# 远程加载配置启动
+
+## 1. 准备工作
+
+- dubbo-go cli 工具和依赖工具已安装
+- 创建一个新的 demo 应用
+- 本地/远程启动一个 Nacos 实例,登录控制台
+
+## 2. 在配置中心创建配置
+
+Dubbogo 服务框架支持将配置文件 'dubbogo.yaml' 的内容预先放入配置中心,再通过配置注册中心的地址。在本地 dubbogo.yaml 配置文件内只需写入配置中心的信息即可,目前支持作为配置中心的中间件有:apollo、nacos、zookeeper
+
+可参考 [配置中心 samples](https://github.com/apache/dubbo-go-samples/tree/master/configcenter),凡是正确配置了config-center 配置的服务,都会优先从配置中心加载整个配置文件。
+
+```yaml
+dubbo:
+ config-center:
+ protocol: nacos
+ address: 127.0.0.1:8848
+ data-id: dubbo-go-samples-configcenter-nacos-server
+ group: myGroup # nacos group, default is DEFAULT_GROUP
+# namespace: 9fb00abb-278d-42fc-96bf-e0151601e4a1 # nacos namespaceID, default is public namespace
+
+## set in config center, group is 'dubbo', dataid is 'dubbo-go-samples-configcenter-nacos-server', namespace is default
+#dubbo:
+# registries:
+# demoZK:
+# protocol: nacos
+# timeout: 3s
+# address: 127.0.0.1:8848
+# protocols:
+# triple:
+# name: tri
+# port: 20000
+# provider:
+# services:
+# GreeterProvider:
+# interface: com.apache.dubbo.sample.basic.IGreeter # must be compatible with grpc or dubbo-java
+```
+
+
diff --git a/content/zh/docs3-building/golang-sdk/tasks/debug/_index.md b/content/zh/docs3-building/golang-sdk/tasks/debug/_index.md
new file mode 100644
index 0000000000..839b729ef6
--- /dev/null
+++ b/content/zh/docs3-building/golang-sdk/tasks/debug/_index.md
@@ -0,0 +1,5 @@
+---
+type: docs
+title: "调试"
+weight: 7
+---
\ No newline at end of file
diff --git a/content/zh/docs3-building/golang-sdk/tasks/debug/dubbogo_cli.md b/content/zh/docs3-building/golang-sdk/tasks/debug/dubbogo_cli.md
new file mode 100644
index 0000000000..7675e4143f
--- /dev/null
+++ b/content/zh/docs3-building/golang-sdk/tasks/debug/dubbogo_cli.md
@@ -0,0 +1,147 @@
+---
+title: 使用 Nacos 作为注册中心
+type: docs
+weight: 2
+---
+
+## 1. 准备工作
+
+- dubbo-go cli 工具和依赖工具已安装
+- 创建一个新的 demo 应用
+- 参考任务[【修改使用的协议】](../../rpc/choose_protocol/)将应用使用修改为使用 dubbo 协议暴露
+
+## 2. 使用 grpc_cli 工具进行 Dubbo 服务调试
+
+### 2.1 开启服务端
+示例:user.go:
+```go
+func (u *UserProvider) GetUser(ctx context.Context, userStruct *CallUserStruct) (*User, error) {
+ fmt.Printf("=======================\nreq:%#v\n", userStruct)
+ rsp := User{"A002", "Alex Stocks", 18, userStruct.SubInfo}
+ fmt.Printf("=======================\nrsp:%#v\n", rsp)
+ return &rsp, nil
+}
+
+```
+服务端开启一个服务,名为GetUser,传入一个CallUserStruct的参数,返回一个User参数\
+CallUserStruct参数定义:
+```go
+type CallUserStruct struct {
+ ID string
+ Male bool
+ SubInfo SubInfo // 嵌套子结构
+}
+func (cs CallUserStruct) JavaClassName() string {
+ return "com.ikurento.user.CallUserStruct"
+}
+
+type SubInfo struct {
+ SubID string
+ SubMale bool
+ SubAge int
+}
+
+func (s SubInfo) JavaClassName() string {
+ return "com.ikurento.user.SubInfo"
+}
+
+```
+User结构定义:
+```go
+type User struct {
+ Id string
+ Name string
+ Age int32
+ SubInfo SubInfo // 嵌套上述子结构SubInfo
+}
+
+func (u *User) JavaClassName() string {
+ return "com.ikurento.user.User"
+}
+```
+
+开启服务:
+
+`cd server `\
+`source builddev.sh`\
+`go run .`
+
+### 2.2 定义请求体(打解包协议)
+
+请求体定义为json文件,约定键值均为string\
+键对应go语言struct字段名例如"ID"、"Name" ,值对应"type@val"\
+其中type支持string int bool time,val使用string 来初始化,如果只填写type则初始化为零值。
+约定每个struct必须有JavaClassName字段,务必与server端严格对应
+
+见userCall.json:
+```json
+{
+ "ID": "string@A000",
+ "Male": "bool@true",
+ "SubInfo": {
+ "SubID": "string@A001",
+ "SubMale": "bool@false",
+ "SubAge": "int@18",
+ "JavaClassName":"string@com.ikurento.user.SubInfo"
+ },
+ "JavaClassName": "string@com.ikurento.user.CallUserStruct"
+}
+```
+userCall.json将参数CallUserStruct的结构及子结构SubInfo都定义了出来,并且给请求参数赋值。
+
+user.json 同理,作为返回值不需要赋初始值,但JavaClassName字段一定与server端严格对应
+```go
+{
+ "ID": "string",
+ "Name": "string",
+ "Age": "int",
+ "JavaClassName": "string@com.ikurento.user.User",
+ "SubInfo": {
+ "SubID": "string",
+ "SubMale": "bool",
+ "SubAge": "int",
+ "JavaClassName":"string@com.ikurento.user.SubInfo"
+ }
+}
+```
+
+### 2.3 执行请求
+`dubbogo-cli call --h=localhost --p 20001 --proto=dubbo --i=com.ikurento.user.UserProvider --method=GetUser --sendObj="./userCall.json" --recvObj="./user.json"`
+
+cli端打印结果:
+```log
+2020/10/26 20:47:45 Created pkg:
+2020/10/26 20:47:45 &{ID:A000 Male:true SubInfo:0xc00006ea20 JavaClassName:com.ikurento.user.CallUserStruct}
+2020/10/26 20:47:45 SubInfo:
+2020/10/26 20:47:45 &{SubID:A001 SubMale:false SubAge:18 JavaClassName:com.ikurento.user.SubInfo}
+
+
+2020/10/26 20:47:45 Created pkg:
+2020/10/26 20:47:45 &{ID: Name: Age:0 JavaClassName:com.ikurento.user.User SubInfo:0xc00006ec90}
+2020/10/26 20:47:45 SubInfo:
+2020/10/26 20:47:45 &{SubID: SubMale:false SubAge:0 JavaClassName:com.ikurento.user.SubInfo}
+
+
+2020/10/26 20:47:45 connected to localhost:20001!
+2020/10/26 20:47:45 try calling interface:com.ikurento.user.UserProvider.GetUser
+2020/10/26 20:47:45 with protocol:dubbo
+
+2020/10/26 20:47:45 After 3ms , Got Rsp:
+2020/10/26 20:47:45 &{ID:A002 Name:Alex Stocks Age:18 JavaClassName: SubInfo:0xc0001241b0}
+2020/10/26 20:47:45 SubInfo:
+2020/10/26 20:47:45 &{SubID:A001 SubMale:false SubAge:18 JavaClassName:}```
+```
+可看到详细的请求体赋值情况,以及返回结果和耗时。支持嵌套结构
+
+server端打印结果
+```
+=======================
+req:&main.CallUserStruct{ID:"A000", Male:true, SubInfo:main.SubInfo{SubID:"A001", SubMale:false, SubAge:18}}
+=======================
+```
+可见接收到了来自cli的数据
+
+
+
+
+
diff --git a/content/zh/docs3-building/golang-sdk/tasks/debug/grpc_cli.md b/content/zh/docs3-building/golang-sdk/tasks/debug/grpc_cli.md
new file mode 100644
index 0000000000..83fc225442
--- /dev/null
+++ b/content/zh/docs3-building/golang-sdk/tasks/debug/grpc_cli.md
@@ -0,0 +1,77 @@
+---
+title: 使用 grpc_cli 调试 Dubbo-go 服务
+type: docs
+weight: 1
+---
+
+grpc_cli 工具是 gRPC 生态用于调试服务的工具,在 server 开启[反射服务](https://github.com/grpc/grpc/blob/master/doc/server-reflection.md)的前提下,可以获取到服务的 proto 文件、服务名、方法名、参数列表,以及发起 gRPC 调用。
+
+Triple 协议兼容 gRPC 生态,并默认开启 gRPC 反射服务,因此可以直接使用 grpc_cli 调试 triple 服务。
+
+## 1. 准备工作
+
+- dubbo-go cli 工具和依赖工具已安装
+- 创建一个新的 demo 应用
+- 安装grpc_cli,参考 [grpc_cli 文档](https://github.com/grpc/grpc/blob/master/doc/command_line_tool.md)
+
+## 2. 使用 grpc_cli 工具进行 Triple 服务调试
+
+### 2.1 启动 demo 应用 server
+
+```bash
+$ mkdir grpc_cli_test
+$ cd grpc_cli_test
+$ dubbogo-cli newDemo .
+$ go mod tidy
+$ cd go-server/cmd
+$ go run .
+```
+
+### 2.2 使用 grpc_cli 进行服务调试
+
+1. 查看 triple 服务的接口定义
+
+```shell
+$ grpc_cli ls localhost:20000 -l
+filename: samples_api.proto
+package: api;
+service Greeter {
+ rpc SayHello(api.HelloRequest) returns (api.User) {}
+ rpc SayHelloStream(stream api.HelloRequest) returns (stream api.User) {}
+}
+```
+
+2. 查看请求参数类型
+
+ 例如开发者期望测试上述端口的 SayHello 方法,尝试获取 HelloRequest 的具体定义,需要执行如下指令,可查看到对应参数的定义。
+
+```shell
+$ grpc_cli type localhost:20000 api.HelloRequest
+message HelloRequest {
+ string name = 1 [json_name = "name"];
+}
+```
+
+3. 请求接口
+
+ 已经知道了请求参数的具体类型,可以发起调用来测试对应服务。查看返回值是否符合预期。
+
+```shell
+$ grpc_cli call localhost:20000 SayHello "name: 'laurence'"
+connecting to localhost:20000
+name: "Hello laurence"
+id: "12345"
+age: 21
+Received trailing metadata from server:
+accept-encoding : identity,gzip
+grpc-accept-encoding : identity,deflate,gzip
+Rpc succeeded with OK status
+```
+
+ 可看到获得了正确的返回值。在 server 侧可以观察到被正确请求的日志:
+
+```shell
+Dubbo3 GreeterProvider get user name = laurence
+```
+
+
diff --git a/content/zh/docs3-building/golang-sdk/tasks/mesh/_index.md b/content/zh/docs3-building/golang-sdk/tasks/mesh/_index.md
new file mode 100644
index 0000000000..d53ba53fd1
--- /dev/null
+++ b/content/zh/docs3-building/golang-sdk/tasks/mesh/_index.md
@@ -0,0 +1,5 @@
+---
+type: docs
+title: "服务网格"
+weight: 5
+---
\ No newline at end of file
diff --git a/content/zh/docs3-building/golang-sdk/tasks/mesh/app.md b/content/zh/docs3-building/golang-sdk/tasks/mesh/app.md
new file mode 100644
index 0000000000..c1f75846e2
--- /dev/null
+++ b/content/zh/docs3-building/golang-sdk/tasks/mesh/app.md
@@ -0,0 +1,426 @@
+---
+title: Istio 环境部署 Dubbo-go 应用
+type: docs
+weight: 2
+---
+
+在本章节中,我们将使用应用模板快速创建一组 Dubbo-go Server和 Client 端应用,部署在 Istio 集群中;观察、调试和验证服务发现和调用成功。
+
+## 1. 准备工作
+
+- dubbo-go cli 工具和依赖工具已安装、grpc_cli (如需本地调试)。
+- docker、helm、kubectl 环境已安装。(arm 机器需支持 docker buildx)
+- [任务【istio 环境部署】](./build/) 已完成
+
+## 2. 开发 server 端 Dubbo-go 应用
+
+### 2.1 使用 dubbogo-cli 创建项目模板
+
+```plain
+$ mkdir mesh-app-server
+$ cd mesh-app-server
+$ dubbogo-cli newApp .
+$ tree .
+.
+├── Makefile
+├── api
+│ └── api.proto
+├── build
+│ └── Dockerfile
+├── chart
+│ ├── app
+│ │ ├── Chart.yaml
+│ │ ├── templates
+│ │ │ ├── _helpers.tpl
+│ │ │ ├── deployment.yaml
+│ │ │ ├── service.yaml
+│ │ │ └── serviceaccount.yaml
+│ │ └── values.yaml
+│ └── nacos_env
+│ ├── Chart.yaml
+│ ├── templates
+│ │ ├── _helpers.tpl
+│ │ ├── deployment.yaml
+│ │ └── service.yaml
+│ └── values.yaml
+├── cmd
+│ └── app.go
+├── conf
+│ └── dubbogo.yaml
+├── go.mod
+├── go.sum
+└── pkg
+ └── service
+ └── service.go
+```
+
+生成项目包括几个目录:
+
+- api:放置接口文件:proto文件和生成的pb.go文件
+- build:放置构建相关文件
+- chart:放置发布用 chart 仓库、基础环境chart 仓库:nacos、mesh(开发中)
+- cmd:程序入口
+- conf:框架配置
+- pkg/service:RPC 服务实现
+- Makefile:
+
+- - 镜像、Helm 安装名称:
+
+- - ```
+ IMAGE = $(your_repo)/$(namespace)/$(image_name)
+ TAG = 1.0.0
+ HELM_INSTALL_NAME = dubbo-go-app
+ ```
+
+- - 提供脚本,例如:
+
+- - - make build # 打包镜像并推送
+ - make buildx-publish # arm架构本地打包amd64镜像并推送,依赖buildx
+ - make deploy # 通过 helm 发布应用
+ - make remove # 删除已经发布的 helm 应用
+ - make proto-gen # api下生成 pb.go 文件
+ - ...
+
+### 2.2 开发和部署 Dubbo-go 应用:
+
+#### 开发应用
+
+- 编译接口
+
+ 开发人员需要修改 proto 文件,本任务中直接使用默认接口即可。
+
+ ```bash
+ $ make proto-gen
+ protoc --go_out=./api --go-triple_out=./api ./api/api.proto
+ ```
+
+- 拉取依赖
+
+ ```bash
+ $ go get dubbo.apache.org/dubbo-go/v3@3.0
+ $ make tidy
+ go mod tidy
+ ```
+
+- 编写业务逻辑
+
+ 修改 pkg/service/service.go 实现函数, 返回字符串中显示版本为 v1.0.0
+
+ ```go
+ func (s *GreeterServerImpl) SayHello(ctx context.Context, in *api.HelloRequest) (*api.User, error) {
+ return &api.User{Name: "Hello " + in.Name, Id: "v1.0.0"}, nil
+ }
+ ```
+
+- 修改配置如下字段,从而使用xds协议作为注册中心
+
+ conf/dubbogo.yaml
+
+ ```yaml
+ dubbo:
+ registries:
+ xds:
+ protocol: xds
+ address: istiod.istio-system.svc.cluster.local:15010
+ protocols:
+ triple:
+ name: tri
+ port: 20000
+ provider:
+ services:
+ GreeterServerImpl:
+ interface: "" # read from stub
+
+ ```
+
+ 至此,应用开发完成。
+
+#### 配置构建和部署参数
+
+- 指定需要构建的镜像:
+
+ 修改 Makefile 如下字段,指定好需要构建的镜像地址和版本。
+
+ 指定好需要通过 helm 安装的名称。
+
+ ```
+ IMAGE = xxx/dubbo-go-server
+ TAG = 1.0.0
+ HELM_INSTALL_NAME = dubbo-go-server-v1
+ ```
+
+- 指定需要部署的应用和镜像:
+
+ 修改 chart/app/Chart.yaml 如下字段,指定当前应用名为 `dubbo-go-server`,部署时会创建一个名为 dubbo-go-server 的 service ,关联当前应用的所有版本。
+
+ ```yaml
+ apiVersion: v1
+ name: dubbo-go-server
+ description: dubbo-go-server
+ ```
+
+ 修改 chart/app/values.yaml 如下字段,指定需要部署的镜像以及当前开发的应用版本 dubbogoAppVersion 为 v1。
+
+ 部署的镜像需要和上述构建的镜像一致。当前应用版本用于 mesh 流量规则控制。
+
+ ```yaml
+ image:
+ repository: xxx/dubbo-go-server
+ pullPolicy: Always
+ tag: "1.0.0"
+
+ # Dubbo-go-mesh version control labels
+ version:
+ labels:
+ dubbogoAppVersion: v1
+ ```
+
+ 至此,构建参数和发布参数都已指定好,可以进行构建和部署了。
+
+#### 使用模板构建和部署 Dubbo-go 应用
+
+- 构建、推送镜像
+
+ `$ make build ` (本地为 amd64机器)
+
+ 或者
+
+ `$ make buildx-publish` (本地为 arm64机器,依赖 docker buildx 命令)
+
+- 发布 Dubbo-go 应用至集群
+
+ ```bash
+ $ make deploy
+ helm install dubbo-go-server-v1 ./chart/app
+ NAME: dubbo-go-server-v1
+ LAST DEPLOYED: Thu Apr 7 11:19:42 2022
+ NAMESPACE: default
+ STATUS: deployed
+ REVISION: 1
+ TEST SUITE: None
+ $ helm list
+ NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION
+ dubbo-go-server-v1 default 1 2022-04-07 11:19:42.350553 +0800 CST deployed dubbo-go-server-0.0.1 1.16.0
+ ```
+
+ 可看到通过 helm 部署成功
+
+
+
+### 2.3 验证应用
+
+#### 查看资源部署情况
+
+查看部署好的 deployment ,版本为 v1。
+
+```bash
+$ kubectl get deployment
+NAME READY UP-TO-DATE AVAILABLE AGE
+dubbo-go-server-v1 1/1 1 1 26s
+```
+
+查看部署好的 service。
+
+```bash
+$ kubectl get svc
+NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
+dubbo-go-server ClusterIP 192.168.216.253 <none> 20000/TCP 70s
+```
+
+#### (*可选)本地调试部署好的 Dubbo-go 应用
+
+使用 kubectl port-forward Dubbo-go 应用到本地
+
+```bash
+$ kubectl port-forward svc/dubbo-go-server 20000
+Forwarding from 127.0.0.1:20000 -> 20000
+Forwarding from [::1]:20000 -> 20000
+```
+
+使用 grpc_cli 调试集群内的应用,参考任务[【使用 grpc_cli 调试 Dubbo-go 应用】](../debug/grpc_cli/)
+
+```bash
+$ grpc_cli ls localhost:20000 -l
+filename: api/api.proto
+package: api;
+service Greeter {
+ rpc SayHello(api.HelloRequest) returns (api.User) {}
+ rpc SayHelloStream(stream api.HelloRequest) returns (stream api.User) {}
+}
+```
+
+使用 grpc_cli 发起调用,测试接口
+
+```bash
+$ grpc_cli call localhost:20000 SayHello "name: 'laurence'"
+connecting to localhost:20000
+name: "Hello laurence"
+id: "v1.0.0"
+Received trailing metadata from server:
+accept-encoding : identity,gzip
+grpc-accept-encoding : identity,deflate,gzip
+Rpc succeeded with OK status
+```
+
+至此,我们成功开发了一个应用,把它部署在了 istio 集群内。
+
+## 3. 开发 Client 端 Dubbo-go 应用
+
+### 3.1 使用 dubbogo-cli 创建另一个项目模板
+
+```bash
+$ dubbogo-cli newApp .
+```
+
+### 3.2 开发和部署客户端 Dubbo-go 应用:
+
+#### 编写业务逻辑
+
+- 修改 cmd/app.go 的 main 方法,针对下游接口每秒钟发起一次调用
+
+```go
+func main() {
+ client := &api.GreeterClientImpl{}
+ config.SetConsumerService(client)
+ if err := config.Load(); err != nil {
+ panic(err)
+ }
+ request := &api.HelloRequest{
+ Name: "laurence",
+ }
+
+ for{
+ if rsp, err := client.SayHello(context.Background(), request); err != nil{
+ logger.Errorf("call server error = %s", err)
+ }else{
+ logger.Infof("call server response = %+v", rsp)
+ }
+ time.Sleep(time.Second)
+ }
+}
+```
+
+- 修改如下配置文件,使用xds协议作为注册中心,加载名为 GreeterClientImpl 的客户端服务。
+
+ conf/dubbogo.yaml
+
+ ```yaml
+ dubbo:
+ registries:
+ xds:
+ protocol: xds
+ address: istiod.istio-system.svc.cluster.local:15010
+ consumer:
+ references:
+ GreeterClientImpl:
+ protocol: tri
+ interface: "" # read from stub
+ ```
+
+ 至此,应用开发完成。
+
+#### 配置构建和部署参数
+
+- 指定需要构建的镜像:
+
+ 修改 Makefile 如下字段,指定好需要构建的镜像地址和版本。
+
+ 指定好需要通过 helm 安装的名称。
+
+ ```
+ IMAGE = xxx/dubbo-go-client
+ TAG = 1.0.0
+ HELM_INSTALL_NAME = dubbo-go-client
+ ```
+
+- 指定需要部署的应用和镜像:
+
+ 修改 chart/app/Chart.yaml 如下字段,指定当前应用名为 `dubbo-go-client`,部署时会创建一个名为 dubbo-go-client 的 service ,关联当前应用的所有版本。对于一个只有客户端的应用,可以不创建sevice,可以由开发者在模板中修改,本教程中我们默认创建。
+
+ ```yaml
+ apiVersion: v1
+ name: dubbo-go-client
+ description: dubbo-go-client
+ ```
+
+ 修改 chart/app/values.yaml 如下字段,指定需要部署的镜像以及当前开发的应用版本 dubbogoAppVersion 为 v1。
+
+ 部署的镜像需要和上述构建的镜像一致。当前应用版本用于 mesh 流量规则控制。
+
+ ```yaml
+ image:
+ repository: xxx/dubbo-go-client
+ pullPolicy: Always
+ tag: "1.0.0"
+
+ # Dubbo-go-mesh version control labels
+ version:
+ labels:
+ dubbogoAppVersion: v1
+ ```
+
+ 至此,构建参数和发布参数都已指定好,可以进行构建和部署了。
+
+#### 使用模板构建和部署 Dubbo-go 应用
+
+- 构建、推送镜像
+
+ `$ make build ` (本地为 amd64机器)
+
+ 或者
+
+ `$ make buildx-publish` (本地为 arm64机器,依赖 docker buildx 命令)
+
+- 发布 Dubbo-go Client 应用至集群
+
+ ```bash
+ $ make deploy
+ helm install dubbo-go-client ./chart/app
+ NAME: dubbo-go-client
+ LAST DEPLOYED: Thu Apr 7 11:49:55 2022
+ NAMESPACE: default
+ STATUS: deployed
+ REVISION: 1
+ TEST SUITE: None
+ $ helm list
+ NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION
+ dubbo-go-client default 1 2022-04-07 11:49:55.517898 +0800 CST deployed dubbo-go-client-0.0.1 1.16.0
+ dubbo-go-server-v1 default 1 2022-04-07 11:23:18.397658 +0800 CST deployed dubbo-go-server-0.0.1 1.16.0
+ ```
+
+ 可看到通过 helm 部署成功, 目前已经在集群中存在 Client 和 Server 两个应用。
+
+### 3.3 验证应用
+
+#### 查看资源部署情况
+
+查看部署好的 client 和 server 两个 deployment。
+
+```bash
+$ kubectl get deployment
+NAME READY UP-TO-DATE AVAILABLE AGE
+dubbo-go-client-v1 1/1 1 1 22m
+dubbo-go-server-v1 1/1 1 1 49m
+```
+
+查看客户端调用日志
+
+```bash
+$ kubectl get pods | grep client | awk '{print $1}' | xargs kubectl logs
+...
+2022-04-07T04:13:55.777Z INFO cmd/app.go:29 call server response = name:"Hello laurence" id:"v1.0.0"
+2022-04-07T04:13:56.778Z INFO cmd/app.go:29 call server response = name:"Hello laurence" id:"v1.0.0"
+2022-04-07T04:13:57.779Z INFO cmd/app.go:29 call server response = name:"Hello laurence" id:"v1.0.0"
+2022-04-07T04:13:58.781Z INFO cmd/app.go:29 call server response = name:"Hello laurence" id:"v1.0.0"
+2022-04-07T04:13:59.782Z INFO cmd/app.go:29 call server response = name:"Hello laurence" id:"v1.0.0"
+2022-04-07T04:14:00.784Z INFO cmd/app.go:29 call server response = name:"Hello laurence" id:"v1.0.0"
+2022-04-07T04:14:01.785Z INFO cmd/app.go:29 call server response = name:"Hello laurence" id:"v1.0.0"
+```
+
+验证调用成功
+
+## 4. 小结
+
+dubbogo-cli 提供的应用模板可以方便地支持开发者进行镜像的构建、推送、部署。
+
+在 Istio 环境中,server 应用将自身服务信息注册在 Isito 上,由客户端监听 xds 资源,查询 istio debug 端口进行接口级别的服务发现。开发人员无需关心 service名、主机名、集群名等概念,只需要引入接口,发起调用即可。
diff --git a/content/zh/docs3-building/golang-sdk/tasks/mesh/build.md b/content/zh/docs3-building/golang-sdk/tasks/mesh/build.md
new file mode 100644
index 0000000000..1ecece63e7
--- /dev/null
+++ b/content/zh/docs3-building/golang-sdk/tasks/mesh/build.md
@@ -0,0 +1,32 @@
+---
+title: 部署 Istio 环境
+type: docs
+weight: 1
+---
+
+## 1. 准备工作
+
+- docker、helm、kubectl 环境已安装。
+- dubbo-go cli 工具和依赖工具已安装
+
+## 2. 部署 Istio 环境
+
+1. 使用helm 安装 istio 基础 CRD 和 istiod 组件。也可以参考 [Istio 文档](https://istio.io/) 使用 istioctl 安装。
+
+```bash
+$ helm repo add istio https://istio-release.storage.googleapis.com/charts
+$ kubectl create namespace istio-system
+$ helm install istio-base istio/base -n istio-system
+$ helm install istiod istio/istiod --namespace istio-system
+```
+
+2. 删除istio 水平扩展资源
+
+ *目前 dubbo-go 依赖单个 istiod 实例进行服务发现。
+
+```bash
+$ kubectl delete hpa istiod -n istio-system
+```
+
+安装完成后,可以在 istio-system 命名空间下看到一个 istiod pod 在正常运行。
+
diff --git a/content/zh/docs3-building/golang-sdk/tasks/mesh/ingress.md b/content/zh/docs3-building/golang-sdk/tasks/mesh/ingress.md
new file mode 100644
index 0000000000..ed17399bee
--- /dev/null
+++ b/content/zh/docs3-building/golang-sdk/tasks/mesh/ingress.md
@@ -0,0 +1,8 @@
+---
+title: 使用 pixiu 网关接入 ingress 流量
+type: docs
+weight: 4
+---
+
+
+
diff --git a/content/zh/docs3-building/golang-sdk/tasks/mesh/traffic_management.md b/content/zh/docs3-building/golang-sdk/tasks/mesh/traffic_management.md
new file mode 100644
index 0000000000..4da1a10909
--- /dev/null
+++ b/content/zh/docs3-building/golang-sdk/tasks/mesh/traffic_management.md
@@ -0,0 +1,417 @@
+---
+title: 流量管理
+type: docs
+weight: 3
+---
+
+在本节中,我们将延续上一个任务[【在 Istio 环境部署 Dubbo-go 应用】](./app/)。
+
+在之前的任务中,我们在集群中部署了一组 Dubbo-go Server和 Client 端应用,验证了服务发现和调用成功。在本节中,我们将创建新版本的 Server 端应用。通过配置 VirtualService 和 DestinationRule ,实现路由管理,和流量转移能力
+
+## 1. 准备工作
+
+- dubbo-go cli 工具和依赖工具已安装、grpc_cli (如需本地调试)。
+- docker、helm、kubectl 环境已安装。(arm 机器需支持 docker buildx)
+- 任务[【在 Istio 环境部署 Dubbo-go 应用】](./app/)已完成
+
+## 2. 开发多版本Dubbo-go 应用。
+
+### 2.1 使用 dubbogo-cli 创建另一个项目模板
+
+```bash
+$ dubbogo-cli newApp .
+```
+
+### 2.2 开发和部署客户端 Dubbo-go 应用 v2:
+
+#### 编写业务逻辑
+
+- 修改 package/service/service.go 的实现方法,返回版本号为 v2.0.0
+
+```go
+func (s *GreeterServerImpl) SayHello(ctx context.Context, in *api.HelloRequest) (*api.User, error) {
+ return &api.User{Name: "Hello " + in.Name, Id: "v2.0.0"}, nil
+}
+```
+
+- 修改如下配置文件,使用xds协议作为注册中心,加载名为 GreeterServerImpl 的服务结构。
+
+ conf/dubbogo.yaml
+
+ ```yaml
+ dubbo:
+ registries:
+ xds:
+ protocol: xds
+ address: istiod.istio-system.svc.cluster.local:15010
+ protocols:
+ triple:
+ name: tri
+ port: 20000
+ provider:
+ services:
+ GreeterServerImpl:
+ interface: "" # read from stub
+
+ ```
+
+ 至此,应用开发完成。
+
+#### 配置构建和部署参数
+
+- 指定需要构建的镜像:
+
+ 修改 Makefile 如下字段,指定好需要构建的镜像地址和版本,我们把镜像 tag 改为 2.0.0。
+
+ 指定好需要通过 helm 安装的名称。
+
+ ```
+ IMAGE = xxx/dubbo-go-server
+ TAG = 2.0.0
+ HELM_INSTALL_NAME = dubbo-go-server
+ ```
+
+- 指定需要部署的应用和镜像:
+
+ 修改 chart/app/Chart.yaml 如下字段,指定当前应用名为 `dubbo-go-server`,我们在创建v1版本服务的时候,已经有了该应用的 service,这次部署时模板将不会创建 service。
+
+ ```yaml
+ apiVersion: v1
+ name: dubbo-go-server
+ description: dubbo-go-server
+ ```
+
+ 修改 chart/app/values.yaml 如下字段,指定需要部署的镜像为2.0.0,以及当前开发的应用版本 dubbogoAppVersion 为 v2。
+
+ 部署的镜像需要和上述构建的镜像一致。当前应用版本用于 mesh 流量规则控制。
+
+ ```yaml
+ image:
+ repository: xxx/dubbo-go-server
+ pullPolicy: Always
+ tag: "2.0.0"
+
+ # Dubbo-go-mesh version control labels
+ version:
+ labels:
+ dubbogoAppVersion: v2
+ ```
+
+ 至此,构建参数和发布参数都已指定好,可以进行构建和部署了。
+
+#### 使用模板构建和部署 Dubbo-go 应用
+
+- 构建、推送镜像
+
+ `$ make build ` (本地为 amd64机器)
+
+ 或者
+
+ `$ make buildx-publish` (本地为 arm64机器,依赖 docker buildx 命令)
+
+- 发布 Dubbo-go Server v2 至集群
+
+ ```bash
+ $ make deploy
+ NAME: dubbo-go-server-v2
+ LAST DEPLOYED: Thu Apr 7 12:29:28 2022
+ NAMESPACE: default
+ STATUS: deployed
+ REVISION: 1
+ TEST SUITE: None
+ $ helm list
+ NAME NAMESPACE REVISION UPDATED STATUS CHART dubbo-go-client default 1 2022-04-07 11:49:55.517898 +0800 CST deployed dubbo-go-client-0.0.1 1.16.0
+ dubbo-go-server-v1 default 1 2022-04-07 11:23:18.397658 +0800 CST deployed dubbo-go-server-0.0.1 1.16.0
+ dubbo-go-server-v2 default 1 2022-04-07 12:29:28.497476 +0800 CST deployed dubbo-go-client-0.0.1 1.16.0
+ ```
+
+ 可看到通过 helm 部署成功, 目前已经在集群中存在一个 Client 应用,和 Server 的两个版本。
+
+### 2.3 验证应用
+
+#### 查看资源部署情况
+
+查看部署好的 deployment ,server 包含了两个版本。
+
+```bash
+$ kubectl get deployment
+NAME READY UP-TO-DATE AVAILABLE AGE
+dubbo-go-client-v1 1/1 1 1 40m
+dubbo-go-server-v2 1/1 1 1 77s
+dubbo-go-server-v1 1/1 1 1 67m
+```
+
+查看部署好的 service。两个版本的deployment 共用同一个 service。
+
+```bash
+$ kubectl get svc
+NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
+dubbo-go-client ClusterIP 192.168.8.176 <none> 20000/TCP 41m
+dubbo-go-server ClusterIP 192.168.216.253 <none> 20000/TCP 67m
+```
+
+查看 Client 应用日志,验证请求调用到了两个版本的应用上。
+
+```bash
+$ kubectl get pods | grep client | awk '{print $1}' | xargs kubectl logs
+...
+2022-04-07T05:06:40.384Z INFO cmd/app.go:29 call server response = name:"Hello laurence" id:"v2.0.0"
+2022-04-07T05:06:41.386Z INFO cmd/app.go:29 call server response = name:"Hello laurence" id:"v2.0.0"
+2022-04-07T05:06:42.388Z INFO cmd/app.go:29 call server response = name:"Hello laurence" id:"v1.0.0"
+2022-04-07T05:06:43.389Z INFO cmd/app.go:29 call server response = name:"Hello laurence" id:"v2.0.0"
+2022-04-07T05:06:44.390Z INFO cmd/app.go:29 call server response = name:"Hello laurence" id:"v2.0.0"
+2022-04-07T05:06:45.392Z INFO cmd/app.go:29 call server response = name:"Hello laurence" id:"v1.0.0"
+2022-04-07T05:06:46.393Z INFO cmd/app.go:29 call server response = name:"Hello laurence" id:"v1.0.0"
+2022-04-07T05:06:47.394Z INFO cmd/app.go:29 call server response = name:"Hello laurence" id:"v1.0.0"
+2022-04-07T05:06:48.396Z INFO cmd/app.go:29 call server response = name:"Hello laurence" id:"v2.0.0"
+2022-04-07T05:06:49.397Z INFO cmd/app.go:29 call server response = name:"Hello laurence" id:"v1.0.0"
+```
+
+至此,我们开发并且部署成功了多版本应用。
+
+## 3. 配置请求路由
+
+### 3.1 配置目标规则
+
+执行以下命令以创建目标规则,该目标规则将 dubbo-go-server 细分为两个子集。v1和 v2
+
+```bash
+$ kubectl apply -f destinationrule.yaml
+```
+
+destinationrule.yaml 内容:
+
+```yaml
+apiVersion: networking.istio.io/v1alpha3
+kind: DestinationRule
+metadata:
+ name: dubbo-go-server
+spec:
+ host: dubbo-go-server
+ subsets:
+ - name: v1
+ labels:
+ dubbogoAppVersion: v1 # 对应应用模板中 chart/app/values.yaml 中指定的版本标签
+ - name: v2
+ labels:
+ dubbogoAppVersion: v2
+```
+
+### 3.2 应用 Virtual Service
+
+执行以下命令以创建路由,该路由将所有流量都路由至v1 版本应用。
+
+```bash
+$ kubectl apply -f virtualservice.yaml
+```
+
+virtualservice.yaml 内容
+
+```yaml
+apiVersion: networking.istio.io/v1alpha3
+kind: VirtualService
+metadata:
+ name: dubbo-go-server
+spec:
+ hosts:
+ - dubbo-go-server
+ http:
+ - route:
+ - destination:
+ host: dubbo-go-server
+ subset: v1
+```
+
+
+
+### 3.3 验证路由生效
+
+所有流量将流向 v1 版本应用。
+
+```bash
+$ kubectl get pods | grep client | awk '{print $1}' | xargs kubectl logs
+...
+2022-04-07T05:40:44.353Z INFO cmd/app.go:29 call server response = name:"Hello laurence" id:"v1.0.0"
+2022-04-07T05:40:45.354Z INFO cmd/app.go:29 call server response = name:"Hello laurence" id:"v1.0.0"
+2022-04-07T05:40:46.356Z INFO cmd/app.go:29 call server response = name:"Hello laurence" id:"v1.0.0"
+2022-04-07T05:40:47.357Z INFO cmd/app.go:29 call server response = name:"Hello laurence" id:"v1.0.0"
+2022-04-07T05:40:48.359Z INFO cmd/app.go:29 call server response = name:"Hello laurence" id:"v1.0.0"
+2022-04-07T05:40:49.361Z INFO cmd/app.go:29 call server response = name:"Hello laurence" id:"v1.0.0"
+```
+
+
+
+## 4. 基于用户身份的路由
+
+有了上述多版本应用路由的基础,我们可以通过一些策略,来进行灵活的流量管理。
+
+### 4.1 为客户端应用增加用户身份标识
+
+我们希望拥有 user: admin 标识的流量都可以体验 v2 新版本应用。
+
+回到之前创建的 dubbo-go-client 项目,修改 cmd/app.go 的 main 函数,增加调用标识:`user: admin`。
+
+```go
+func main() {
+ client := &api.GreeterClientImpl{}
+ config.SetConsumerService(client)
+ if err := config.Load(); err != nil {
+ panic(err)
+ }
+ request := &api.HelloRequest{
+ Name: "laurence",
+ }
+
+ for{
+ ctx := context.Background()
+ ctx = context.WithValue(ctx, constant.AttachmentKey, map[string]string{
+ "user":"admin", // 使用上下文 context 为调用增加标识
+ })
+
+ if rsp, err := client.SayHello(ctx, request); err != nil{
+ logger.Errorf("call server error = %s", err)
+ }else{
+ logger.Infof("call server response = %+v", rsp)
+ }
+ time.Sleep(time.Second)
+ }
+}
+```
+
+- 构建、推送镜像,覆盖之前的提交。您也可以升级一下发布的镜像版本。
+
+ `$ make build ` (本地为 amd64机器)
+
+ 或者
+
+ `$ make buildx-publish` (本地为 arm64机器,依赖 docker buildx 命令)
+
+- 删除 dubbo-go-client 应用
+
+ ```
+ $ make remove
+ helm uninstall dubbo-go-client
+ release "dubbo-go-client" uninstalled
+ ```
+
+- 重新发布应用。
+
+ `$ make deploy`
+
+ 发布后,验证调用成功,由于前面进行了路由配置。所有流量都流向 v1 版本。
+
+ ```bash
+ $ kubectl get pods | grep client | awk '{print $1}' | xargs kubectl logs
+ ...
+ 2022-04-07T05:40:44.353Z INFO cmd/app.go:29 call server response = name:"Hello laurence" id:"v1.0.0"
+ 2022-04-07T05:40:45.354Z INFO cmd/app.go:29 call server response = name:"Hello laurence" id:"v1.0.0"
+ 2022-04-07T05:40:46.356Z INFO cmd/app.go:29 call server response = name:"Hello laurence" id:"v1.0.0"
+ 2022-04-07T05:40:47.357Z INFO cmd/app.go:29 call server response = name:"Hello laurence" id:"v1.0.0"
+ 2022-04-07T05:40:48.359Z INFO cmd/app.go:29 call server response = name:"Hello laurence" id:"v1.0.0"
+ 2022-04-07T05:40:49.361Z INFO cmd/app.go:29 call server response = name:"Hello laurence" id:"v1.0.0"
+ ```
+
+### 4.2 创建基于用户身份的路由
+
+执行以下命令以修改/创建路由,该路由将所有请求头存在 user: admin 标识的流量都路由至 v2 版本。
+
+```bash
+$ kubectl apply -f virtualservice.yaml
+```
+
+virtualservice.yaml 内容
+
+```yaml
+apiVersion: networking.istio.io/v1alpha3
+kind: VirtualService
+metadata:
+ name: dubbo-go-server
+spec:
+ hosts:
+ - dubbo-go-server
+ http:
+ - match:
+ - headers:
+ user:
+ exact: admin
+ route:
+ - destination:
+ host: dubbo-go-server
+ subset: v2
+ - route:
+ - destination:
+ host: dubbo-go-server
+ subset: v1
+```
+
+### 4.3 验证路由生效
+
+所有流量将流向 v2 版本应用。
+
+```bash
+$ kubectl get pods | grep client | awk '{print $1}' | xargs kubectl logs
+...
+2022-04-07T05:52:18.714Z INFO cmd/app.go:35 call server response = name:"Hello laurence" id:"v2.0.0"
+2022-04-07T05:52:19.716Z INFO cmd/app.go:35 call server response = name:"Hello laurence" id:"v2.0.0"
+2022-04-07T05:52:20.717Z INFO cmd/app.go:35 call server response = name:"Hello laurence" id:"v2.0.0"
+2022-04-07T05:52:21.718Z INFO cmd/app.go:35 call server response = name:"Hello laurence" id:"v2.0.0"
+2022-04-07T05:52:22.720Z INFO cmd/app.go:35 call server response = name:"Hello laurence" id:"v2.0.0"
+2022-04-07T05:52:23.722Z INFO cmd/app.go:35 call server response = name:"Hello laurence" id:"v2.0.0"
+2022-04-07T05:52:24.723Z INFO cmd/app.go:35 call server response = name:"Hello laurence" id:"v2.0.0"
+```
+
+
+
+## 5. 基于权重的路由
+
+### 5.1 创建基于权重的路由
+
+延续上述任务,我们执行以下命令以修改/创建路由,该路由将流量的 10% 导入新版本应用,进行灰度测试。
+
+```bash
+$ kubectl apply -f virtualservice.yaml
+```
+
+virtualservice.yaml 内容
+
+```yaml
+apiVersion: networking.istio.io/v1alpha3
+kind: VirtualService
+metadata:
+ name: dubbo-go-server
+spec:
+ hosts:
+ - dubbo-go-server
+ http:
+ - route:
+ - destination:
+ host: dubbo-go-server
+ subset: v1
+ weight: 90
+ - destination:
+ host: dubbo-go-server
+ subset: v2
+ weight: 10
+```
+
+### 5.2 验证路由生效
+
+少数流量将流向 v2 版本。
+
+```bash
+$ kubectl get pods | grep client | awk '{print $1}' | xargs kubectl logs
+...
+2022-04-07T05:55:52.035Z INFO cmd/app.go:35 call server response = name:"Hello laurence" id:"v1.0.0"
+2022-04-07T05:55:53.036Z INFO cmd/app.go:35 call server response = name:"Hello laurence" id:"v1.0.0"
+2022-04-07T05:55:54.037Z INFO cmd/app.go:35 call server response = name:"Hello laurence" id:"v1.0.0"
+2022-04-07T05:55:55.039Z INFO cmd/app.go:35 call server response = name:"Hello laurence" id:"v1.0.0"
+2022-04-07T05:55:56.041Z INFO cmd/app.go:35 call server response = name:"Hello laurence" id:"v1.0.0"
+2022-04-07T05:55:57.043Z INFO cmd/app.go:35 call server response = name:"Hello laurence" id:"v1.0.0"
+2022-04-07T05:55:58.045Z INFO cmd/app.go:35 call server response = name:"Hello laurence" id:"v1.0.0"
+2022-04-07T05:55:59.047Z INFO cmd/app.go:35 call server response = name:"Hello laurence" id:"v1.0.0"
+2022-04-07T05:56:00.049Z INFO cmd/app.go:35 call server response = name:"Hello laurence" id:"v1.0.0"
+2022-04-07T05:56:01.050Z INFO cmd/app.go:35 call server response = name:"Hello laurence" id:"v2.0.0"
+2022-04-07T05:56:02.053Z INFO cmd/app.go:35 call server response = name:"Hello laurence" id:"v1.0.0"
+2022-04-07T05:56:03.055Z INFO cmd/app.go:35 call server response = name:"Hello laurence" id:"v1.0.0"
+```
+
diff --git a/content/zh/docs3-building/golang-sdk/tasks/pixiu/_index.md b/content/zh/docs3-building/golang-sdk/tasks/pixiu/_index.md
new file mode 100644
index 0000000000..23149a926d
--- /dev/null
+++ b/content/zh/docs3-building/golang-sdk/tasks/pixiu/_index.md
@@ -0,0 +1,5 @@
+---
+type: docs
+title: "pixiu网关"
+weight: 8
+---
\ No newline at end of file
diff --git a/content/zh/docs3-building/golang-sdk/tasks/pixiu/http_triple.md b/content/zh/docs3-building/golang-sdk/tasks/pixiu/http_triple.md
new file mode 100644
index 0000000000..673dbeae94
--- /dev/null
+++ b/content/zh/docs3-building/golang-sdk/tasks/pixiu/http_triple.md
@@ -0,0 +1,79 @@
+---
+title: 接入 Ingress 流量
+type: docs
+weight: 1
+---
+
+## 1. 准备工作
+
+- kubectl
+- 一个 k8s 集群,配置好 kubeconfig
+
+## 2. 使用 HTTP 协议通过网关调用 Triple 应用
+
+Dubbo-go-pixiu 网关支持调用 GO/Java 的 Dubbo 集群。在 Dubbo-go 3.0 的场景下,我们可以通过 Pixiu 网关,在集群外以 HTTP 协议请求 pixiu 网关,在网关层进行协议转换,进一步调用集群内的Dubbo-go 服务。
+
+
+
+用户调用 Dubbo-go 服务的 path 为http://$(app_name)/$(service_name)/$(method)。
+
+例如一个proto文件内有如下定义:
+
+```protobuf
+package org.apache.dubbo.quickstart.samples;
+
+service UserProvider {
+ rpc SayHello (HelloRequest) returns (User) {}
+}
+
+message HelloRequest {
+ string name = 1;
+}
+```
+
+并在dubbo-go 服务启动时在dubbogo.yml 内配置应用名为my-dubbogo-app:
+
+```yaml
+dubbo:
+ application:
+ name: my-dubbogo-app
+```
+
+pixiu 网关即可解析 path 为 my-dubbogo-app/org.apache.dubbo.quickstart.samples.UserProvider/SayHello 的路由,并转发至对应服务。来自外部HTTP 请求的 body 为 json 序列化的请求参数,例如 {"name":"test"}。
+
+我们目前推荐使用 Nacos 作为注册中心。
+
+用户可以在自己的集群里部署我们的demo,集群最好拥有暴露 lb 类型 service 的能力,从而可以在公网访问至集群内的服务,您也可以直接集群内进行请求。
+
+针对您的集群,执行:
+
+```bash
+$ kubectl apply -f https://raw.githubusercontent.com/dubbogo/triple-pixiu-demo/master/deploy/pixiu-triple-demo.yml
+```
+
+会在 dubbogo-triple-nacos 命名空间下创建如下资源,包含三个 triple-server,一个pixiu网关,一个 nacos server。并通过 Servcie 将服务暴露至公网。
+
+```bash
+namespace/dubbogo-triple-nacos created
+service/dubbo-go-nacos created
+deployment.apps/dubbogo-nacos-deployment created
+deployment.apps/pixiu created
+deployment.apps/server created
+service/pixiu created
+```
+
+获取 pixiu 公网 ip 并进行调用
+
+```pgsql
+$ kubectl get svc -n dubbogo-triple-nacos
+NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
+dubbo-go-nacos ClusterIP 192.168.123.204 <none> 8848/TCP 32s
+pixiu LoadBalancer 192.168.156.175 30.XXX.XXX.XX 8881:30173/TCP 32s
+```
+
+通过curl 调用 demo 服务,并获得响应结果。
+
+```bash
+$ curl -X POST -d '{"name":"laurence"}' http://30.XXX.XXX.XX:8881/dubbogoDemoServer/org.apache.dubbo.laurence.samples.UserProvider/SayHello
+{"name":"Hello laurence","id":"12345","age":21}
+```
\ No newline at end of file
diff --git a/content/zh/docs3-building/golang-sdk/tasks/registry/_index.md b/content/zh/docs3-building/golang-sdk/tasks/registry/_index.md
new file mode 100644
index 0000000000..b63aeb739e
--- /dev/null
+++ b/content/zh/docs3-building/golang-sdk/tasks/registry/_index.md
@@ -0,0 +1,5 @@
+---
+type: docs
+title: "注册中心"
+weight: 2
+---
\ No newline at end of file
diff --git a/content/zh/docs3-building/golang-sdk/tasks/registry/multi_registry.md b/content/zh/docs3-building/golang-sdk/tasks/registry/multi_registry.md
new file mode 100644
index 0000000000..7892adf530
--- /dev/null
+++ b/content/zh/docs3-building/golang-sdk/tasks/registry/multi_registry.md
@@ -0,0 +1,118 @@
+---
+title: 多注册中心
+type: docs
+weight: 2
+---
+
+一个 Dubbo-go 应用可以配置的多个接口维度的注册中心。
+
+## 1. 准备工作
+
+- dubbo-go cli 工具和依赖工具已安装
+- 创建一个新的 demo 应用
+- 本地启动Nacos、Zookeeper
+
+## 2. 使用多注册中心
+
+修改服务端配置 go-server/conf/dubbogo.yaml, 同时将服务注册在两个注册中心上。
+
+```yaml
+dubbo:
+ registries:
+ zookeeper: # 指定 zookeeper 注册中心
+ protocol: zookeeper
+ address: 127.0.0.1:2181
+ nacos: # 指定 nacos 注册中心
+ protocol: nacos
+ address: 127.0.0.1:8848
+ protocols:
+ triple:
+ name: tri
+ port: 20000
+ provider:
+ services:
+ GreeterProvider:
+ registry-ids: # 同时注册
+ - zookeeper
+ - nacos
+ interface: ""
+```
+
+修改客户端配置 go-client/conf/dubbogo.yaml
+
+```yaml
+dubbo:
+ registries:
+ nacos: # 指定 nacos 注册中心
+ protocol: nacos
+ address: 127.0.0.1:8848
+ zookeeper: # 指定 zookeeper 注册中心
+ protocol: zookeeper
+ address: 127.0.0.1:2181
+ consumer:
+ references:
+ GreeterClientImpl:
+ registry-ids: # 从 nacos 注册中心服务发现
+ - nacos
+ protocol: tri
+ interface: ""
+ GreeterClientImpl2:
+ registry-ids: # 从 zookeeeper 注册中心服务发现
+ - zookeeper
+ protocol: tri
+ interface: ""
+```
+
+修改客户端代码,再定义一个客户端存根类,名为GreeterClientImpl2:
+
+```go
+var grpcGreeterImpl2 = new(GreeterClientImpl2)
+
+type GreeterClientImpl2 struct{
+ api.GreeterClientImpl
+}
+```
+
+客户端编写调用代码:
+
+```go
+func main() {
+ config.SetConsumerService(grpcGreeterImpl)
+ config.SetConsumerService(grpcGreeterImpl2)
+ if err := config.Load(); err != nil {
+ panic(err)
+ }
+
+ logger.Info("start to test dubbo")
+ req := &api.HelloRequest{
+ Name: "laurence",
+ }
+ reply, err := grpcGreeterImpl.SayHello(context.Background(), req)
+ if err != nil {
+ logger.Error(err)
+ }
+ logger.Infof("nacos server response result: %v\n", reply)
+
+ reply, err = grpcGreeterImpl2.SayHello(context.Background(), req)
+ if err != nil {
+ logger.Error(err)
+ }
+ logger.Infof("zk server response result: %v\n", reply)
+}
+
+```
+
+
+
+## 3. 多注册中心服务发现验证
+
+分别启动 go-server/cmd 和 go-client/cmd 查看两条调用成功的日志:
+
+```
+INFO cmd/client.go:55 nacos server response result: name:"Hello laurence" id:"12345" age:21
+
+INFO cmd/client.go:61 zk server response result: name:"Hello laurence" id:"12345" age:21
+
+```
+
+
diff --git a/content/zh/docs3-building/golang-sdk/tasks/registry/nacos.md b/content/zh/docs3-building/golang-sdk/tasks/registry/nacos.md
new file mode 100644
index 0000000000..7af9c89ec0
--- /dev/null
+++ b/content/zh/docs3-building/golang-sdk/tasks/registry/nacos.md
@@ -0,0 +1,80 @@
+---
+title: 使用 Nacos 作为注册中心
+type: docs
+weight: 1
+---
+
+## 1. 准备工作
+
+- dubbo-go cli 工具和依赖工具已安装
+- 创建一个新的 demo 应用
+- 启动一个 Nacos 实例,暴露 8848 端口
+
+## 2. 配置注册中心
+
+修改服务端配置 go-server/conf/dubbogo.yaml
+
+```yaml
+dubbo:
+ registries:
+ nacos: # 配置 Nacos 注册中心
+ protocol: nacos
+ address: 127.0.0.1:8848 # 指定 Nacos 地址
+ protocols:
+ triple:
+ name: tri
+ port: 20000
+ provider:
+ services:
+ GreeterProvider:
+ interface: "" # read from pb
+```
+
+修改客户端配置 go-client/conf/dubbogo.yaml
+
+```yaml
+dubbo:
+ registries:
+ nacos:
+ protocol: nacos
+ address: 127.0.0.1:8848
+ consumer:
+ references:
+ GreeterClientImpl:
+ protocol: tri
+ interface: "" # read from pb
+```
+
+
+
+## 3. 使用 Nacos 进行服务发现
+
+- 启动go-server/cmd,查看日志
+
+ ```bash
+ [Nacos Registry] Registry instance with param ...
+ ```
+
+ 日志中包含 Nacos 注册信息,将当前服务接口注册在 Nacos。
+
+ 可登陆控制台 http://localhost:8848/nacos 查看注册的服务
+
+- 启动 go-client/cmd 查看日志
+
+ ```
+ [Nacos Registry] Update begin, service event: ServiceEvent{Action{add}, Path{tri://xxx.xxx.xxx.xxx:20000/api.Greeter ...
+ ```
+
+ 日志中包含 Nacos 注册组件的订阅事件信息,获取到服务端 IP 和端口号,显示调用成功。
+
+ ```
+ client response result: name:"Hello laurence" id:"12345" age:21
+ ```
+
+
+
+## 4. 更多支持的注册中心
+
+参考 [dubbo-go-samples/registry](https://github.com/apache/dubbo-go-samples/tree/master/registry)
+
+
diff --git a/content/zh/docs3-building/golang-sdk/tasks/rpc/_index.md b/content/zh/docs3-building/golang-sdk/tasks/rpc/_index.md
new file mode 100644
index 0000000000..94943addb5
--- /dev/null
+++ b/content/zh/docs3-building/golang-sdk/tasks/rpc/_index.md
@@ -0,0 +1,5 @@
+---
+type: docs
+title: "服务调用"
+weight: 1
+---
\ No newline at end of file
diff --git a/content/zh/docs3-building/golang-sdk/tasks/rpc/call_grpc.md b/content/zh/docs3-building/golang-sdk/tasks/rpc/call_grpc.md
new file mode 100644
index 0000000000..6fb04dbb06
--- /dev/null
+++ b/content/zh/docs3-building/golang-sdk/tasks/rpc/call_grpc.md
@@ -0,0 +1,16 @@
+---
+title: 与 gRPC 应用互通
+type: docs
+weight: 5
+---
+
+## 1. 准备工作
+
+- dubbo-go cli 工具和依赖工具已安装
+- 创建一个新的 demo 应用
+
+## 2. Dubbo-go 应用与 gRPC 应用互通
+
+参考 [dubbo-go-samples/rpc/triple/pb/dubbogo-grpc](https://github.com/apache/dubbo-go-samples/tree/master/rpc/triple/pb/dubbogo-grpc)
+
+
diff --git a/content/zh/docs3-building/golang-sdk/tasks/rpc/call_java.md b/content/zh/docs3-building/golang-sdk/tasks/rpc/call_java.md
new file mode 100644
index 0000000000..31271fd995
--- /dev/null
+++ b/content/zh/docs3-building/golang-sdk/tasks/rpc/call_java.md
@@ -0,0 +1,847 @@
+---
+title: 与 Java 应用跨语言互通
+type: docs
+weight: 4
+---
+
+## 准备工作
+
+### 环境
+
+JDK 8,Golang >= 1.15,Dubbo 3.0.2,zookeeper 启动,
+
+### Go- Java 互通前提
+
+- Go/Java 定义的传输结构一致
+
+ - PB 序列化
+
+ proto for Go
+
+ ```protobuf
+ // The response message containing the greetings
+ message User {
+ string name = 1;
+ string id = 2;
+ int32 age = 3;
+ }
+ ```
+
+ proto for Java
+
+ ```protobuf
+ // The response message containing the greetings
+ message User {
+ string name = 1;
+ string id = 2;
+ int32 age = 3;
+ }
+ ```
+
+ - Hessian 序列化
+
+ POJO for Go,需参考 [Dubbogo Hessian 序列化支持文档](https://www.yuque.com/docs/share/c698bd6e-e4d6-47db-bc1c-c757cc9b4f3e?)
+
+ ```go
+ type User struct {
+ ID string
+ Name string
+ Age int32
+ }
+
+ func (u *User) JavaClassName() string {
+ return "org.apache.dubbo.User"
+ }
+
+ func init(){
+ hessian.RegisterPOJO(&User{})
+ }
+ ```
+
+ POJO for Java
+
+ ```java
+ package org.apache.dubbo
+
+ public class User {
+ private String id;
+ private String name;
+ private int age;
+ }
+ ```
+
+- Java 需要互通的方法签名与 Go 一致
+
+ 例如:
+
+ Java Interface
+
+ ```java
+ public interface IGreeter {
+ /**
+ * <pre>
+ * Sends a greeting
+ * </pre>
+ */
+ User sayHello(HelloRequest request);
+ }
+ ```
+
+ Go client (由protoc-gen-go-triple 根据 proto 文件自动生成)
+
+ ```go
+ type GreeterClientImpl struct {
+ // Sends a greeting
+ SayHello func(ctx context.Context, in *HelloRequest) (*User, error)
+ }
+ ```
+
+ Go server (由开发者定义)
+
+ ```go
+ type GreeterProvider struct {
+ api.GreeterProviderBase
+ }
+
+ func (s *GreeterProvider) SayHello(ctx context.Context, in *api.HelloRequest) (*api.User, error) {
+ logger.Infof("Dubbo3 GreeterProvider get user name = %s\n", in.Name)
+ return &api.User{Name: "Hello " + in.Name, Id: "12345", Age: 21}, nil
+ }
+ ```
+
+ Go 方法需要遵守 [Dubbogo 3.0 用户服务接口定义规范](https://www.yuque.com/docs/share/eff9c51f-a7f4-47d6-87ff-11a2152bdffe?)
+
+
+
+- Java 的三元组与Go service/reference 配置的 interface 一致
+
+ 三元组,即为接口级别配置的:interface, group, version。**其中需要注意,group 和 version 的概念为 dubbo 接口的 group 和vesion,在启动 dubbo-java 服务时配置于 spring cloud 的 properties 文件中,并非pom.xml 中 mvn 依赖的version。** group 和version 默认为空,在 dubbo-go 框架中,可以在service/reference 的对应位置指定 group 和 version。
+
+ 例如:
+
+ Java 的接口全名:com.apache.dubbo.sample.basic.IGreeter,接口 version 为v1.0.1, group 为
+
+ Go-client:
+
+ ```yaml
+ references:
+ GreeterClientImpl:
+ protocol: tri
+ interface: com.apache.dubbo.sample.basic.IGreeter # must be compatible with grpc or dubbo-java
+ group: dubbogo # 需要与服务端对应 默认为空
+ version: v1.0.1 # 需要与服务端对应 默认为空
+ ```
+
+ Go-server:
+
+ ```yaml
+ services:
+ GreeterProvider:
+ protocol-ids: tripleProtocol
+ interface: com.apache.dubbo.sample.basic.IGreeter # must be compatible with grpc or dubbo-java
+ group: dubbogo # 需要与服务端对应 默认为空
+ version: v1.0.1 # 需要与服务端对应 默认为空
+ ```
+
+
+
+## 1. 基于 Triple 协议互通 (PB序列化)
+
+参考 [dubbo-go-samples/helloworld](https://github.com/apache/dubbo-go-samples/tree/master/helloworld)
+
+### 1.1 Go-Client -> Java-Server
+
+#### Java-Server 启动
+
+1. 定义 Java 的 PB 文件,可参考 [Dubbo 快速开始](https://dubbo.apache.org/zh/docs/quick-start/)
+
+```protobuf
+syntax = "proto3";
+
+option java_package = "org.apache.dubbo.sample.hello";
+
+package helloworld;
+
+// The request message containing the user's name.
+message HelloRequest {
+ string name = 1;
+}
+
+// The response message containing the greetings
+message User {
+ string name = 1;
+ string id = 2;
+ int32 age = 3;
+}
+```
+
+该接口描述文件定义了将会生成的 Java 类 org.apache.dubbo.sample.hello.Helloworld,以及类中包含的传输结构 HelloRequest 和 User 类。
+
+2. 定义服务接口:
+
+ com.apache.dubbo.sample.basic.IGreeter
+
+```java
+package com.apache.dubbo.sample.basic;
+
+// 引入根据 PB 生成的类
+import org.apache.dubbo.sample.hello.Helloworld.User;
+import org.apache.dubbo.sample.hello.Helloworld.HelloRequest;
+
+public interface IGreeter {
+ /**
+ * <pre>
+ * Sends a greeting
+ * </pre>
+ */
+ // 定义接口
+ User sayHello(HelloRequest request);
+}
+```
+
+3. 实现服务接口:
+
+ IGreeter1Impl.java
+
+```java
+package com.apache.dubbo.sample.basic;
+
+import org.apache.dubbo.sample.hello.Helloworld.User;
+import org.apache.dubbo.sample.hello.Helloworld.HelloRequest;
+
+public class IGreeter1Impl implements IGreeter {
+ @Override
+ public User sayHello(HelloRequest request) {
+ System.out.println("receiv: " + request);
+ User usr = User.newBuilder()
+ .setName("hello " + request.getName())
+ .setAge(18)
+ .setId("12345").build();
+ return usr;
+ }
+}
+```
+
+4. 使用 Dubbo3 框架启动服务
+
+ ApiProvider.java
+
+```java
+package com.apache.dubbo.sample.basic;
+
+import org.apache.dubbo.common.constants.CommonConstants;
+import org.apache.dubbo.config.ApplicationConfig;
+import org.apache.dubbo.config.ProtocolConfig;
+import org.apache.dubbo.config.RegistryConfig;
+import org.apache.dubbo.config.ServiceConfig;
+import java.util.concurrent.CountDownLatch;
+
+public class ApiProvider {
+ public static void main(String[] args) throws InterruptedException {
+ ServiceConfig<IGreeter> service = new ServiceConfig<>();
+ service.setInterface(IGreeter.class);
+ service.setRef(new IGreeter1Impl());
+ // 使用 Triple 协议
+ service.setProtocol(new ProtocolConfig(CommonConstants.TRIPLE, 50051));
+ service.setApplication(new ApplicationConfig("demo-provider"));
+ // 使用 ZK 作为注册中心
+ service.setRegistry(new RegistryConfig("zookeeper://127.0.0.1:2181"));
+ service.export();
+ System.out.println("dubbo service started");
+ new CountDownLatch(1).await();
+ }
+}
+```
+
+启动服务,可看到输出如下日志,代表 Java Triple Server 启动成功
+
+```
+main INFO bootstrap.DubboBootstrap: [DUBBO] DubboBootstrap has started., dubbo version: 3.0.2, current host: 192.168.0.108
+dubbo service started
+```
+
+#### Go-Client 启动
+
+对于已经启动的Dubbo服务,如需要开发与其对应的Go-client,需要进行如下步骤:
+
+1. 编写与 Java 适配的 proto文件
+
+ samples_api.proto
+
+```protobuf
+syntax = "proto3";
+package api; // pacakge 名随意指定
+
+// necessary
+option go_package = "./;api";
+
+// The greeting service definition.
+service Greeter {
+ // Sends a greeting
+ rpc SayHello (HelloRequest) returns (User) {}
+}
+
+// The request message containing the user's name.
+message HelloRequest {
+ string name = 1;
+}
+
+// The response message containing the greetings
+message User {
+ string name = 1;
+ string id = 2;
+ int32 age = 3;
+}
+```
+
+2. 使用 protoc-gen-triple 生成接口文件
+
+```bash
+protoc -I . samples_api.proto --triple_out=plugins=triple:.
+```
+
+3. 撰写配置文件: dubbogo.yml
+
+```yaml
+dubbo:
+ registries:
+ demoZK:
+ protocol: zookeeper
+ address: 127.0.0.1:2181
+ consumer:
+ references:
+ GreeterClientImpl:
+ protocol: tri
+ interface: com.apache.dubbo.sample.basic.IGreeter # must be compatible with grpc or dubbo-java
+```
+
+4. 撰写 main.go 文件,发起调用
+
+```go
+// 引入生成的接口结构
+var grpcGreeterImpl = new(api.GreeterClientImpl)
+
+// export DUBBO_GO_CONFIG_PATH=dubbogo.yml
+func main() {
+ config.SetConsumerService(grpcGreeterImpl)
+ if err := config.Load(); err != nil {
+ panic(err)
+ }
+ time.Sleep(3 * time.Second)
+
+ logger.Info("start to test dubbo")
+ req := &api.HelloRequest{
+ Name: "laurence",
+ }
+ reply, err := grpcGreeterImpl.SayHello(context.Background(), req)
+ if err != nil {
+ logger.Error(err)
+ }
+ logger.Infof("client response result: %v\n", reply)
+}
+```
+
+5. 可查看到调用成功的日志
+
+- go-client
+
+```
+cmd/client.go:53 client response result: name:"hello laurence" id:"12345" age:18
+```
+
+- java-server
+
+```
+receiv: name: "laurence"
+```
+
+### 1.2 Java-Client -> Go-Server
+
+#### Go-Server 启动
+
+1. 定义配置文件
+
+```yaml
+dubbo:
+ registries:
+ demoZK:
+ protocol: zookeeper
+ address: 127.0.0.1:2181
+ protocols:
+ triple:
+ name: tri
+ port: 20000
+ provider:
+ services:
+ GreeterProvider:
+ interface: com.apache.dubbo.sample.basic.IGreeter # must be compatible with grpc or dubbo-java
+```
+
+2. 引入传输结构,定义服务
+
+```go
+type GreeterProvider struct {
+ api.GreeterProviderBase
+}
+
+func (s *GreeterProvider) SayHello(ctx context.Context, in *api.HelloRequest) (*api.User, error) {
+ logger.Infof("Dubbo3 GreeterProvider get user name = %s\n", in.Name)
+ return &api.User{Name: "Hello " + in.Name, Id: "12345", Age: 21}, nil
+}
+```
+
+3. 启动服务
+
+```go
+// export DUBBO_GO_CONFIG_PATH=dubbogo.yml
+func main() {
+ config.SetProviderService(&GreeterProvider{})
+ if err := config.Load(); err != nil {
+ panic(err)
+ }
+ select {}
+}
+```
+
+
+
+#### Java-Client 启动
+
+1. proto 文件编写和接口生成参考上述 java-server 介绍
+
+2. 启动Consumer
+
+ ApiCnosumer.java
+
+```java
+public class ApiConsumer {
+ public static void main(String[] args) throws InterruptedException, IOException {
+ ReferenceConfig<IGreeter> ref = new ReferenceConfig<>();
+ ref.setInterface(IGreeter.class);
+ ref.setCheck(false);
+ ref.setProtocol(CommonConstants.TRIPLE);
+ ref.setLazy(true);
+ ref.setTimeout(100000);
+ ref.setApplication(new ApplicationConfig("demo-consumer"));
+ ref.setRegistry(new RegistryConfig("zookeeper://127.0.0.1:2181"));
+ final IGreeter iGreeter = ref.get();
+
+ System.out.println("dubbo ref started");
+ Helloworld.HelloRequest req = Helloworld.HelloRequest.newBuilder().setName("laurence").build();
+ try {
+ final Helloworld.User reply = iGreeter.sayHello(req);
+ TimeUnit.SECONDS.sleep(1);
+ System.out.println("Reply:" + reply);
+ } catch (Throwable t) {
+ t.printStackTrace();
+ }
+ System.in.read();
+ }
+}
+```
+
+## 2. 基于 Dubbo 协议互通 (Hessian2序列化)
+
+参考 [dubbo-go-samples/rpc/dubbo](https://github.com/apache/dubbo-go-samples/tree/rpc/dubbo)
+
+### 2.1 Go-Client -> Java-Server
+
+#### Java-Server 启动
+
+1. 定义 Java 接口、参数和返回值,可参考 [Dubbo 快速开始](https://dubbo.apache.org/zh/docs/quick-start/)
+
+```java
+package org.apache.dubbo;
+
+// 需要暴露的服务接口
+public interface UserProvider {
+ User getUser(int usercode);
+}
+
+```
+
+```java
+package org.apache.dubbo;
+
+public class User implements Serializable {
+
+ private String id;
+
+ private String name;
+
+ private int age;
+
+ private Date time = new Date();
+ /* ... */
+}
+```
+
+2. 实现服务接口:
+
+UserProviderImpl.java
+
+```java
+package org.apache.dubbo;
+public class UserProviderImpl implements UserProvider {
+ public User getUser(int userCode) {
+ return new User(String.valueOf(userCode), "userCode get", 48);
+ }
+}
+
+```
+
+3. 使用SpringBoot 启动
+
+Provider.java
+
+```java
+package org.apache.dubbo;
+
+// use when config by API
+/*
+import java.util.concurrent.CountDownLatch;
+
+import org.apache.dubbo.common.constants.CommonConstants;
+import org.apache.dubbo.config.ApplicationConfig;
+import org.apache.dubbo.config.ProtocolConfig;
+import org.apache.dubbo.config.RegistryConfig;
+import org.apache.dubbo.config.ServiceConfig;
+*/
+import org.springframework.context.support.ClassPathXmlApplicationContext;
+
+public class Provider {
+ // main function, config from spring boot
+ public static void main(String[] args) throws Exception {
+ ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new String[]{"META-INF/spring/dubbo.provider.xml"});
+ context.start();
+ System.in.read(); // press any key to exit
+ }
+
+
+// config by API
+// public static void startComplexService() throws InterruptedException {
+// ServiceConfig<ComplexProvider> service = new ServiceConfig<>();
+// service.setInterface(ComplexProvider.class);
+// service.setRef(new ComplexProviderImpl());
+// service.setProtocol(new ProtocolConfig(CommonConstants.DUBBO_PROTOCOL, 20001));
+// service.setApplication(new ApplicationConfig("demo-provider"));
+// service.setRegistry(new RegistryConfig("zookeeper://127.0.0.1:2181"));
+// service.export();
+// System.out.println("dubbo service started");
+// new CountDownLatch(1).await();
+// }
+}
+
+```
+
+4. 通过Spring 配置 Dubbo 参数
+
+ Resources/META-INF.spring/dubbo.provider.xml
+
+```xml
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
+ xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
+ http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
+
+ <!-- 应用名 -->
+ <dubbo:application name="user-info-server"/>
+ <!-- 连接到哪个本地注册中心 -->
+ <dubbo:registry id="dubbogo" address="zookeeper://127.0.0.1:2181" />
+ <!-- 用dubbo协议在20880端口暴露服务 -->
+ <dubbo:protocol id="dubbo" name="dubbo" host="127.0.0.1" port="20010" />
+ <!-- 声明需要暴露的服务接口 -->
+ <dubbo:service id="aaa" registry="dubbogo" timeout="3000" interface="org.apache.dubbo.UserProvider" ref="demoService"/>
+ <dubbo:service id="bbb" registry="dubbogo" timeout="3000" interface="org.apache.dubbo.UserProvider" ref="otherService" version="2.0"/>
+ <dubbo:service id="ccc" registry="dubbogo" timeout="3000" interface="org.apache.dubbo.UserProvider" ref="otherService" group="as" version="2.0"/>
+
+ <bean id="demoService" class="org.apache.dubbo.UserProviderImpl" />
+ <bean id="otherService" class="org.apache.dubbo.UserProviderAnotherImpl"/>
+
+</beans>
+```
+
+
+
+启动Provider类,可看到输出如下日志,代表 Dubbo Server 启动成功
+
+```
+[DUBBO] DubboBootstrap is ready., dubbo version: 2.7.7, current host: 127.0.0.1
+[DUBBO] DubboBootstrap has started., dubbo version: 2.7.7, current host: 127.0.0.1
+```
+
+#### Go-Client 启动
+
+对于已经启动的Dubbo服务,如需要开发与其对应的Go-client,需要进行如下步骤:
+
+1. 编写与 Java 适配的 POJO 类 User
+
+
+```go
+import(
+ hessian "github.com/apache/dubbo-go-hessian2"
+)
+
+// 字段需要与 Java 侧对应,首字母大写
+type User struct {
+ ID string
+ Name string
+ Age int32
+ Time time.Time
+}
+
+
+func (u *User) JavaClassName() string {
+ return "org.apache.dubbo.User" // 需要与 Java 侧 User 类名对应
+}
+
+func init(){
+ hessian.RegisterPOJO(&pkg.User{}) // 注册 POJO
+}
+```
+
+2. 编写与 Java 侧一致的客户端存根类,其接口方法需要与Java侧对应
+
+ 规定第一个参数必须为 context.Context,最后一个返回值必须为 error
+
+```go
+import(
+ "dubbo.apache.org/dubbo-go/v3/config"
+)
+
+var (
+ userProvider = &pkg.UserProvider{}
+)
+
+// UserProvider 客户端存根类
+type UserProvider struct {
+ // dubbo标签,用于适配go侧客户端大写方法名 -> java侧小写方法名,只有 dubbo 协议客户端才需要使用
+ GetUser func(ctx context.Context, req int32) (*User, error) `dubbo:"getUser"`
+}
+
+func init(){
+ // 注册客户端存根类到框架,实例化客户端接口指针 userProvider
+ config.SetConsumerService(userProvider)
+}
+
+```
+
+3. 撰写配置文件: dubbogo.yml
+
+```yaml
+dubbo:
+ registries:
+ demoZK: # 定义注册中心ID
+ protocol: zookeeper
+ timeout: 3s
+ address: 127.0.0.1:2181
+ consumer:
+ references:
+ UserProvider: # 存根类名
+ protocol: dubbo # dubbo 协议,默认 hessian2 序列化方式
+ interface: org.apache.dubbo.UserProvider # 接口需要与Java侧对应
+ logger:
+ zap-config:
+ level: info # 日志级别
+```
+
+或者使用Triple + Hessian2 序列化请求Server。本例子如果跟Java Server互通则不能用Triple。
+
+```yaml
+dubbo:
+ registries:
+ demoZK:
+ protocol: zookeeper
+ timeout: 3s
+ address: 127.0.0.1:2181
+ consumer:
+ references:
+ UserProvider:
+ protocol: tri # triple 协议
+ serialization: hessian2 # 序列化方式 hessian2,triple 协议默认为 pb 序列化,不配置会报错
+ interface: org.apache.dubbo.UserProvider
+ logger:
+ zap-config:
+ level: info
+```
+
+4. 撰写 main.go 文件,发起调用
+
+```go
+func main(){
+ config.Load()
+ var i int32 = 1
+ user, err := userProvider.GetUser2(context.TODO(), i)
+ if err != nil {
+ panic(err)
+ }
+ logger.Infof("response result: %v", user)
+}
+```
+
+5. 可查看到调用成功的日志,符合预期
+
+- go-client
+
+```bash
+response result: User{ID:1, Name:userCode get, Age:48, Time:2021-10-21 20:25:26.009 +0800 CST}
+```
+
+### 2.2 Java-Client -> Go-Server
+
+#### Go-Server 启动
+
+1. 定义配置文件
+
+```yaml
+dubbo:
+ registries:
+ demoZK:
+ protocol: zookeeper
+ address: 127.0.0.1:2181
+ protocols:
+ dubbo:
+ name: dubbo
+ port: 20000
+ provider:
+ services:
+ UserProvider:
+ interface: org.apache.dubbo.UserProvider
+ logger:
+ zap-config:
+ level: info
+```
+
+2. 引入传输结构,定义服务以及方法名映射
+
+```go
+type UserProvider struct {
+}
+
+func (u *UserProvider) GetUser(ctx context.Context, req int32) (*User, error) {
+ var err error
+ logger.Infof("req:%#v", req)
+ user := &User{}
+ user.ID = strconv.Itoa(int(req))
+ return user, err
+}
+
+// MethodMapper 定义方法名映射,从 Go 的方法名映射到 Java 小写方法名,只有 dubbo 协议服务接口才需要使用
+func (s *UserProvider) MethodMapper() map[string]string {
+ return map[string]string{
+ "GetUser": "getUser",
+ }
+}
+
+func init(){
+ config.SetProviderService(&pkg.UserProvider{})
+}
+
+```
+
+3. 启动服务
+
+```go
+// export DUBBO_GO_CONFIG_PATH=dubbogo.yml
+func main() {
+ if err := config.Load(); err != nil {
+ panic(err)
+ }
+ select {}
+}
+```
+
+
+
+#### Java-Client 启动
+
+1. Java 客户端 Spring 配置
+
+ resources/META-INF.spring/dubbo.consumer.xml
+
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <!--
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+ <beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
+ xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
+ http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
+
+
+ <!-- 消费方应用名,用于计算依赖关系,不是匹配条件,不要与提供方一样 -->
+ <dubbo:application name="user-info-client" />
+ <!-- 连接到哪个本地注册中心 -->
+ <dubbo:registry id="dubbogo" address="zookeeper://127.0.0.1:2181" />
+ <!-- dubbo.registry.address from dubbo.properties -->
+ <!-- dubbo:registry address="${dubbo.registry.address}" / -->
+
+ <!-- 用dubbo协议在20880端口暴露服务 -->
+ <dubbo:protocol id="dubbo" name="dubbo" />
+
+ <!-- 声明需要使用的服务接口 -->
+ <dubbo:reference registry="dubbogo" check="false" id="userProvider" protocol="dubbo" interface="org.apache.dubbo.UserProvider">
+ <!--<dubbo:parameter key="heartbeat" value="10000"/ -->
+ </dubbo:reference>
+
+ <dubbo:reference registry="dubbogo" check="false" id="userProvider1" protocol="dubbo" version="2.0" interface="org.apache.dubbo.UserProvider">
+ </dubbo:reference>
+ <dubbo:reference registry="dubbogo" check="false" id="userProvider2" protocol="dubbo" version="2.0" group="as" interface="org.apache.dubbo.UserProvider">
+ </dubbo:reference>
+ </beans>
+
+ ```
+
+2. 发起调用
+
+```java
+public class Consumer {
+ // Define a private variable (Required in Spring)
+ private static UserProvider userProvider;
+
+ public static void main(String[] args) throws Exception {
+ ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new String[]{"META-INF/spring/dubbo.consumer.xml"});
+ userProvider = (UserProvider)context.getBean("userProvider");
+ testGetUser();
+ }
+
+
+ private static void testGetUser() throws Exception {
+ User user = userProvider.getUser(1);
+ System.out.println(user.getId());
+ }
+}
+```
+
+
+
+
+
diff --git a/content/zh/docs3-building/golang-sdk/tasks/rpc/choose_protocol.md b/content/zh/docs3-building/golang-sdk/tasks/rpc/choose_protocol.md
new file mode 100644
index 0000000000..8b93644e9e
--- /dev/null
+++ b/content/zh/docs3-building/golang-sdk/tasks/rpc/choose_protocol.md
@@ -0,0 +1,233 @@
+---
+title: 选择使用的网络协议
+keywords: 选择使用的网络协议
+description: 选择使用的网络协议
+
+---
+
+# 修改使用的协议
+
+## 1. 准备工作
+
+- dubbo-go cli 工具和依赖工具已安装
+- 创建一个新的 demo 应用
+
+## 2. 如何配置网络协议
+
+在快速开始章节可以看到,生成的Demo 将 Protocol 设置为 tri,表明使用 Triple 协议进行服务暴露和服务调用。快速开始章节使用的配置 API 进行配置的写入,这样的好处是无需使用配置文件。我们摘取出和网络协议相关的内容进行说明。
+
+### 使用配置文件
+
+参考 samples/helloworld
+
+- 客户端使用配置文件设置网络协议
+
+```yaml
+dubbo:
+ consumer:
+ references:
+ GreeterClientImpl:
+ protocol: tri # set protcol to tri
+ interface: com.apache.dubbo.sample.basic.IGreeter
+```
+
+- 服务端使用配置文件设置网络协议
+
+```yaml
+dubbo:
+ protocols:
+ triple: # define protcol-id 'triple'
+ name: tri # set protcol to tri
+ port: 20000 # set port to be listened
+ provider:
+ services:
+ GreeterProvider:
+ protocol-ids: triple # use protocol-ids named 'triple'
+ interface: com.apache.dubbo.sample.basic.IGreeter
+```
+
+
+
+## 3. 编写 Dubbo 协议的接口和实现
+
+### 3.1 定义接口和传输结构,位于api/api.go
+
+```go
+package api
+
+import (
+ "context"
+ "dubbo.apache.org/dubbo-go/v3/config"
+ hessian "github.com/apache/dubbo-go-hessian2"
+ "time"
+)
+
+//1. 定义传输结构, 如需 Java 互通,字段需要与 Java 侧对应,首字母大写
+type User struct {
+ ID string
+ Name string
+ Age int32
+ Time time.Time
+}
+
+func (u *User) JavaClassName() string {
+ return "org.apache.dubbo.User" // 如果与 Java 互通,需要与 Java 侧 User class全名对应,
+}
+
+
+var (
+ UserProviderClient = &UserProvider{} // 客户端指针
+)
+
+// 2。 定义客户端存根类:UserProvider
+type UserProvider struct {
+ // dubbo标签,用于适配go侧客户端大写方法名 -> java侧小写方法名,只有 dubbo 协议客户端才需要使用
+ GetUser func(ctx context.Context, req int32) (*User, error) //`dubbo:"getUser"`
+}
+
+func init(){
+ hessian.RegisterPOJO(&User{}) // 注册传输结构到 hessian 库
+ // 注册客户端存根类到框架,实例化客户端接口指针 userProvider
+ config.SetConsumerService(UserProviderClient)
+}
+```
+
+### 2.2 编写 Go-Server 配置和代码
+
+server/dubbogo.yaml
+
+```yaml
+dubbo:
+ registries:
+ demoZK: # 定义服务注册发现中心
+ protocol: zookeeper
+ address: 127.0.0.1:2181
+ protocols:
+ dubbo:
+ name: dubbo # 协议名 dubbo
+ port: 20000 # 监听端口
+ provider:
+ services:
+ UserProvider: # 服务提供结构类名
+ interface: org.apache.dubbo.UserProvider # 接口需要与 go/java 客户端对应
+```
+
+server/server.go
+
+```go
+package main
+
+import (
+ "context"
+ "dubbo.apache.org/dubbo-go/v3/common/logger" // dubbogo 框架日志
+ "dubbo.apache.org/dubbo-go/v3/config"
+ _ "dubbo.apache.org/dubbo-go/v3/imports" // dubbogo 框架依赖,所有dubbogo进程都需要隐式引入一次
+ "dubbo3-demo/api"
+ "strconv"
+ "time"
+)
+
+type UserProvider struct {
+}
+
+// 实现接口方法
+func (u *UserProvider) GetUser(ctx context.Context, req int32) (*api.User, error) {
+ var err error
+ logger.Infof("req:%#v", req)
+ user := &api.User{}
+ user.ID = strconv.Itoa(int(req))
+ user.Name = "laurence"
+ user.Age = 22
+ user.Time = time.Now()
+ return user, err
+}
+
+//// MethodMapper 定义方法名映射,从 Go 的方法名映射到 Java 小写方法名,只有 dubbo 协议服务接口才需要使用
+//// go -> go 互通无需使用
+//func (s *UserProvider) MethodMapper() map[string]string {
+// return map[string]string{
+// "GetUser": "getUser",
+// }
+//}
+
+func init(){
+ config.SetProviderService(&UserProvider{}) // 注册服务提供者类,类名与配置文件中的 service 对应
+}
+
+// export DUBBO_GO_CONFIG_PATH=dubbogo.yml 运行前需要设置环境变量,指定配置文件位置
+func main() {
+ if err := config.Load(); err != nil {
+ panic(err)
+ }
+ select {}
+}
+
+```
+
+
+
+### 2.3 编写 Go-Client 配置和代码
+
+client/dubbogo.yaml
+
+```yaml
+dubbo:
+ registries:
+ demoZK: # 定义服务注册发现中心
+ protocol: zookeeper
+ address: 127.0.0.1:2181
+ consumer:
+ references:
+ UserProvider: # 存根类名
+ protocol: dubbo # dubbo 协议,默认 hessian2 序列化方式
+ interface: org.apache.dubbo.UserProvider # 接口需要与 go/java 客户端对应
+```
+
+client/client.go
+
+```go
+package main
+
+import (
+ "context"
+ "dubbo.apache.org/dubbo-go/v3/common/logger"
+ "dubbo.apache.org/dubbo-go/v3/config"
+ _ "dubbo.apache.org/dubbo-go/v3/imports"
+ "dubbo3-demo/api"
+)
+
+func main(){
+ // 启动框架
+ if err := config.Load(); err != nil{
+ panic(err)
+ }
+ var i int32 = 1
+ // 发起调用
+ user, err := api.UserProviderClient.GetUser(context.TODO(), i)
+ if err != nil {
+ panic(err)
+ }
+ logger.Infof("response result: %+v", user)
+}
+```
+
+## 4. 启动服务
+
+开启两个终端,分别进入server client 目录
+
+分别执行;
+
+```shell
+export DUBBO_GO_CONFIG_PATH=dubbogo.yml
+go run .
+```
+
+先后启动服务端和客户端, 可在客户端看到输出:
+
+```shell
+response result: &{ID:1 Name:laurence Age:22 Time:2021-11-12 17:59:39.185 +0800 CST}
+```
+
+调用成功
+
+更多samples可以参阅 [【dubbo-go-samples】](../../samples/samples_repo/)
diff --git a/content/zh/docs3-building/golang-sdk/tasks/rpc/context.md b/content/zh/docs3-building/golang-sdk/tasks/rpc/context.md
new file mode 100644
index 0000000000..5dedd96146
--- /dev/null
+++ b/content/zh/docs3-building/golang-sdk/tasks/rpc/context.md
@@ -0,0 +1,16 @@
+---
+title: 使用 ctx 传递上下文信息
+type: docs
+weight: 6
+---
+
+## 1. 准备工作
+
+- dubbo-go cli 工具和依赖工具已安装
+- 创建一个新的 demo 应用
+
+## 2. 使用 context 传递附加信息
+
+参考 [dubbo-go-samples/context](https://github.com/apache/dubbo-go-samples/tree/master/context)
+
+
diff --git a/content/zh/docs3-building/golang-sdk/tasks/rpc/error.md b/content/zh/docs3-building/golang-sdk/tasks/rpc/error.md
new file mode 100644
index 0000000000..b672a86e34
--- /dev/null
+++ b/content/zh/docs3-building/golang-sdk/tasks/rpc/error.md
@@ -0,0 +1,124 @@
+---
+title: 异常信息回传
+type: docs
+weight: 8
+---
+
+## 1. 准备工作
+
+- dubbo-go cli 工具和依赖工具已安装
+- 创建一个新的 demo 应用
+
+## 2. 传递异常信息
+
+参考samples [dubbo-go-samples/error](https://github.com/apache/dubbo-go-samples/tree/master/error)
+
+### 用户异常回传介绍
+
+用户可以在 provider 端生成用户定义的异常信息,可以记录异常产生堆栈,triple 协议可保证将用户在客户端获取到异常 message ,并可以查看报错堆栈,便于定位问题。
+
+注意返回 error 非 nil 时,框架不负责其他返回值的传递。
+
+- 在Triple provider 端返回异常,以 pb 序列化为例:
+
+```go
+package main
+
+import (
+ "context"
+)
+
+import (
+ "dubbo.apache.org/dubbo-go/v3/common/logger"
+
+ // 使用可以记录堆栈的异常库,此处以 "github.com/pkg/errors" 为例
+ "github.com/pkg/errors"
+)
+
+import (
+ triplepb "github.com/apache/dubbo-go-samples/api"
+)
+
+
+// 一个实现了 pb 接口的服务提供结构
+type ErrorResponseProvider struct {
+ triplepb.UnimplementedGreeterServer
+}
+
+// 回传错误的接口
+func (s *ErrorResponseProvider) SayHello(ctx context.Context, in *triplepb.HelloRequest) (*triplepb.User, error) {
+ logger.Infof("Dubbo3 GreeterProvider get user name = %s\n" + in.Name)
+ // 返回用户自定义异常
+ return &triplepb.User{Name: "Hello " + in.Name, Id: "12345", Age: 21}, errors.New("user defined error")
+}
+
+```
+
+
+
+- 客户端打印异常和堆栈
+
+```go
+package main
+
+import (
+ "context"
+)
+
+import (
+ "dubbo.apache.org/dubbo-go/v3/common/logger"
+ "dubbo.apache.org/dubbo-go/v3/config"
+ _ "dubbo.apache.org/dubbo-go/v3/imports"
+
+ tripleCommon "github.com/dubbogo/triple/pkg/common"
+)
+
+import (
+ triplepb "github.com/apache/dubbo-go-samples/api"
+)
+
+var greeterProvider = new(triplepb.GreeterClientImpl)
+
+func init() {
+ config.SetConsumerService(greeterProvider)
+}
+
+func main() {
+ if err := config.Load(); err != nil {
+ panic(err)
+ }
+
+ req := triplepb.HelloRequest{
+ Name: "laurence",
+ }
+
+ // 发起调用
+ if user, err := greeterProvider.SayHello(context.TODO(), &req); err != nil {
+ // 打印异常信息,err.Error() 将返回用户定义的 message,即 user defined error
+ logger.Infof("response result: %v, error = %s", user, err)
+
+ // 打印异常堆栈,需断言为 tripleCommon.TripleError
+ logger.Infof("error details = %+v", err.(tripleCommon.TripleError).Stacks())
+ }
+}
+
+```
+
+```text
+2021-11-12T18:36:33.730+0800 INFO cmd/client.go:53 response result: , error = user defined error
+2021-11-12T18:36:33.730+0800 INFO cmd/client.go:54 error details = [type.googleapis.com/google.rpc.DebugInfo]:{stack_entries:"user defined error
+main.(*ErrorResponseProvider).SayHello
+ /dubbo-go-samples/error/triple/pb/go-server/cmd/error_reponse.go:40
+reflect.Value.call
+ /usr/local/go/src/reflect/value.go:543
+reflect.Value.Call
+ /usr/local/go/src/reflect/value.go:339
+dubbo.apache.org/dubbo-go/v3/common/proxy/proxy_factory.(*ProxyInvoker).Invoke
+ /Users/laurence/go/pkg/mod/dubbo.apache.org/dubbo-go/v3@v3.0.0-rc4-1/common/proxy/proxy_factory/default.go:145
+ ...
+
+```
+
+可看到报错信息和堆栈
+
+
diff --git a/content/zh/docs3-building/golang-sdk/tasks/rpc/generic.md b/content/zh/docs3-building/golang-sdk/tasks/rpc/generic.md
new file mode 100644
index 0000000000..a192af95fa
--- /dev/null
+++ b/content/zh/docs3-building/golang-sdk/tasks/rpc/generic.md
@@ -0,0 +1,102 @@
+---
+title: 泛化调用
+type: docs
+weight: 7
+---
+
+## 1. Dubbo-go 泛化调用 Java Server
+
+使用 Triple 协议 + hessian2 序列化方案
+
+### 1.1 Java-Server启动
+
+1. 传输结构定义
+
+```java
+package org.apache.dubbo;
+
+import java.io.Serializable;
+import java.util.Date;
+
+public class User implements Serializable {
+ private String id;
+
+ private String name;
+
+ private int age;
+
+ private Date time = new Date();
+}
+```
+
+2. 接口定义
+
+```java
+package org.apache.dubbo;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+//import org.apache.dubbo.rpc.filter.GenericFilter;
+
+public interface UserProvider {
+ User GetUser1(String userId);
+}
+```
+
+### 1.2 Go-Client 泛化调用
+
+此处展示以 API 的形式构造泛化接口引用
+
+```go
+// 初始化 Reference 配置
+refConf := config.NewReferenceConfigBuilder().
+ SetInterface("org.apache.dubbo.UserProvider").
+ SetRegistryIDs("zk").
+ SetProtocol(tripleConst.TRIPLE).
+ SetGeneric(true).
+ SetSerialization("hessian2").
+ Build()
+
+// 构造 Root 配置,引入注册中心模块
+rootConfig := config.NewRootConfigBuilder().
+ AddRegistry("zk", config.NewRegistryConfigWithProtocolDefaultPort("zookeeper")).
+ Build()
+
+// Reference 配置初始化,因为需要使用注册中心进行服务发现,需要传入经过配置的 rootConfig
+if err := refConf.Init(rootConfig); err != nil{
+ panic(err)
+}
+
+// 泛化调用加载、服务发现
+refConf.GenericLoad(appName)
+
+time.Sleep(time.Second)
+
+// 发起泛化调用
+resp, err := refConf.GetRPCService().(*generic.GenericService).Invoke(
+ context.TODO(),
+ "getUser1",
+ []string{"java.lang.String"},
+ []hessian.Object{"A003"},
+)
+
+if err != nil {
+ panic(err)
+}
+logger.Infof("GetUser1(userId string) res: %+v", resp)
+```
+
+GenericService 的 Invoke 方法包括三个参数:context.Context, []string, []hessian.Object,
+
+其中第二个参数为对应参数的 Java 类名,例如java.lang.String、org.apache.dubbo.User,第三个参数为参数列表,hessian.Object 即为 interface。第二、第三个参数应与方法签名一致,按顺序对应。
+
+获得map结构的返回结果
+
+```
+INFO cmd/client.go:89 GetUser1(userId string) res: map[age:48 class:org.apache.dubbo.User id:A003 name:Joe sex:MAN time:2021-10-04 14:03:03.37 +0800 CST]
+```
+
+
+
+
diff --git a/content/zh/docs3-building/golang-sdk/tasks/rpc/rpc_metrics.md b/content/zh/docs3-building/golang-sdk/tasks/rpc/rpc_metrics.md
new file mode 100644
index 0000000000..ffdf1f28bf
--- /dev/null
+++ b/content/zh/docs3-building/golang-sdk/tasks/rpc/rpc_metrics.md
@@ -0,0 +1,51 @@
+---
+title: 查看 RPC 调用的监控信息
+type: docs
+weight: 1
+---
+
+## 1. 准备工作
+
+- dubbo-go cli 工具和依赖工具已安装
+- 创建一个新的 demo 应用
+
+## 2. 修改客户端逻辑,重复发起调用
+
+go-client/cmd/client.go
+
+```go
+func main() {
+ config.SetConsumerService(grpcGreeterImpl)
+ if err := config.Load(); err != nil {
+ panic(err)
+ }
+
+ logger.Info("start to test dubbo")
+ req := &api.HelloRequest{
+ Name: "laurence",
+ }
+ for{ // 重复发起调用
+ reply, err := grpcGreeterImpl.SayHello(context.Background(), req)
+ if err != nil {
+ logger.Error(err)
+ }
+ logger.Infof("client response result: %v\n", reply)
+ }
+}
+```
+
+## 3. 查看请求 RT 信息
+
+先后启动服务端、客户端服务应用。浏览器查看 localhost:9090/metrics, 搜索 "dubbo", 即可查看服务端暴露接口的请求时延,单位 ns。
+
+```
+$ curl localhost:9090/metrics | grep dubbo
+
+# HELP dubbo_provider_service_rt
+# TYPE dubbo_provider_service_rt gauge
+dubbo_provider_service_rt{group="",method="SayHello",service="api.Greeter",timeout="",version="3.0.0"} 41084
+```
+
+可看到当前最近一次请求 rt 为 41084 ns。
+
+
diff --git a/content/zh/docs3-building/golang-sdk/tasks/rpc/timeout.md b/content/zh/docs3-building/golang-sdk/tasks/rpc/timeout.md
new file mode 100644
index 0000000000..2f4cb932a4
--- /dev/null
+++ b/content/zh/docs3-building/golang-sdk/tasks/rpc/timeout.md
@@ -0,0 +1,61 @@
+---
+title: 配置调用的超时
+type: docs
+weight: 1
+---
+
+## 1. 准备工作
+
+- dubbo-go cli 工具和依赖工具已安装
+- 创建一个新的 demo 应用
+
+## 2. 通过配置项修改 RPC 调用相关参数
+
+### 2.1 修改调用的超时,并验证
+
+```yaml
+dubbo:
+ consumer:
+ request-timeout: 15s # 配置客户端超时
+```
+
+Dubbo-go 应用默认 RPC 超时为 3s,请求超时后,客户端将会返回error 为 context deadline exceeded 的错误。在本任务中,您需要首先修改 demo 应用的 server 函数为较长耗时,然后查看客户端的超时报错;再通过配置客户端超时,使得耗时函数可以正常调用。
+
+1. go-server/cmd/server.go: 修改 demo 应用 server 的函数为耗时 10s 的函数
+
+ ```go
+ func (s *GreeterProvider) SayHello(ctx context.Context, in *api.HelloRequest) (*api.User, error) {
+ logger.Infof("Dubbo3 GreeterProvider get user name = %s\n", in.Name)
+ time.Sleep(time.Second*10) // sleep 10s
+ return &api.User{Name: "Hello " + in.Name, Id: "12345", Age: 21}, nil
+ }
+ ```
+
+2. 客户端发起调用,观察错误日志
+
+ ```
+ ERROR cmd/client.go:47 context deadline exceeded
+ ```
+
+3. go-client/conf/dubbogo.yaml: 客户端修改超时
+
+ ```yaml
+ dubbo:
+ consumer:
+ request-timeout: 15s # 配置客户端超时
+ references:
+ GreeterClientImpl:
+ protocol: tri
+ url: "tri://localhost:20000"
+ interface: "" # read from pb
+ ```
+
+4. 再次通过客户端发起调用,观察日志,正常返回:
+
+ ```bash
+ client response result: name:"Hello laurence" id:"12345" age:21
+ ```
+
+
+
+
diff --git a/content/zh/docs3-building/golang-sdk/tasks/rpc/tps_limiter.md b/content/zh/docs3-building/golang-sdk/tasks/rpc/tps_limiter.md
new file mode 100644
index 0000000000..d110dbca83
--- /dev/null
+++ b/content/zh/docs3-building/golang-sdk/tasks/rpc/tps_limiter.md
@@ -0,0 +1,105 @@
+---
+title: 为服务端设置限流
+type: docs
+weight: 3
+---
+
+## 1. 准备工作
+
+- dubbo-go cli 工具和依赖工具已安装
+- 创建一个新的 demo 应用
+
+## 2. 修改限流逻辑并验证
+
+Dubbo-go 为用户提供了内置的限流拒绝逻辑,并支持用户根据自己的业务场景,定义需要的限流机制、拒绝逻辑。
+
+正常情况下,不设置流量限制,当用户在 server 端配置了限流逻辑和参数后,将会
+
+### 2.1 配置限流参数
+
+go-server/conf/dubbogo.yaml: 配置限流参数
+
+```yaml
+dubbo:
+ protocols:
+ triple:
+ name: tri
+ port: 20000
+ provider:
+ services:
+ GreeterProvider:
+ interface: "" # read from pb
+ tps.limiter: "method-service"
+ tps.limit.strategy: "slidingWindow"
+ tps.limit.rejected.handler: "default"
+ tps.limit.interval: 1000
+ tps.limit.rate: 3
+
+```
+
+参数说明:
+
+- tps.limiter:限流器选择。method-service 为框架内置的一个限流器,可以配置服务和方法级别的限流逻辑,可自定义。
+- tps.limit.strategy:限流策略选择,slidingWindow 为框架内置的一个限流策略,可以按照滑动窗口的形式,拒绝掉窗口内超过流量限制的请求。
+- tps.limit.rejected.handler: 拒绝策略,default 为默认拒绝方式,返回空对象,可自定义
+- tps.limit.interval:限流窗口区间,单位是ms。
+- tps.limit.rate:窗口内流量限制,单位是请求次数。
+
+按照上述配置,服务端只允许当前接口在一秒内被调用三次。
+
+### 2.2 发起超流请求,验证限流能力
+
+将客户端的请求逻辑设置为每秒钟请求五次,并计算成功率。
+
+go-client/cmd/client.go
+
+```go
+
+func main() {
+ config.SetConsumerService(grpcGreeterImpl)
+ if err := config.Load(); err != nil {
+ panic(err)
+ }
+
+ logger.Info("start to test dubbo")
+ req := &api.HelloRequest{
+ Name: "laurence",
+ }
+
+ for {
+ goodCount := 0
+ badCount := 0
+ for{
+ time.Sleep(time.Millisecond*200)
+ reply, _ := grpcGreeterImpl.SayHello(context.Background(), req)
+ if reply.Name == "" {
+ badCount++
+ }else {
+ goodCount++
+ }
+ if badCount + goodCount ==5{
+ break
+ }
+ }
+ logger.Infof("Success rate = %v\n", float64(goodCount)/float64(goodCount + badCount))
+ }
+}
+```
+
+可在日志中看到请求成功率为0.6,每秒钟只允许三次请求被执行。
+
+```bash
+INFO cmd/client.go:62 Success rate = 0.6
+
+INFO cmd/client.go:62 Success rate = 0.6
+
+INFO cmd/client.go:62 Success rate = 0.6
+```
+
+在服务端日志中可以看到拒绝的信息:
+
+```bash
+ERROR tps/filter.go:84 The invocation was rejected due to over the limiter limitation...
+```
+
+
diff --git a/content/zh/docs3-building/golang-sdk/tasks/service_management/_index.md b/content/zh/docs3-building/golang-sdk/tasks/service_management/_index.md
new file mode 100644
index 0000000000..6756b2727f
--- /dev/null
+++ b/content/zh/docs3-building/golang-sdk/tasks/service_management/_index.md
@@ -0,0 +1,5 @@
+---
+type: docs
+title: "服务治理"
+weight: 4
+---
\ No newline at end of file
diff --git a/content/zh/docs3-building/golang-sdk/tasks/service_management/aop.md b/content/zh/docs3-building/golang-sdk/tasks/service_management/aop.md
new file mode 100644
index 0000000000..685738e422
--- /dev/null
+++ b/content/zh/docs3-building/golang-sdk/tasks/service_management/aop.md
@@ -0,0 +1,67 @@
+---
+title: 自定义服务调用中间件
+type: docs
+weight: 1
+---
+
+参考samples [dubbo-go-samples/filter](https://github.com/apache/dubbo-go-samples/tree/master/filter)
+
+## 1. 准备工作
+
+- dubbo-go cli 工具和依赖工具已安装
+- 阅读[【组件加载与可扩展性】](../../concept/service_management/aop_and_extension/)
+- 创建一个新的 demo 应用
+
+## 2. 配置指定 Filter
+
+指定filter时可用','分隔
+
+- Consumer 端
+
+ ```yaml
+ dubbo:
+ consumer:
+ filter: echo,token,tps,myCustomFilter # 可指定自定义filter
+ ```
+
+
+
+- Provider 端
+
+ ```yaml
+ dubbo:
+ provider:
+ services:
+ GreeterProvider:
+ filter: myCustomFilter,echo,tps
+ ```
+
+## 3. 自定义Filter
+
+用户可在代码中自定义 Filter,注册到框架上,并在配置中选择使用。
+
+```go
+func init() {
+ extension.SetFilter("myCustomFilter", NewMyClientFilter)
+}
+
+func NewMyClientFilter() filter.Filter {
+ return &MyClientFilter{}
+}
+
+type MyClientFilter struct {
+}
+
+func (f *MyClientFilter) Invoke(ctx context.Context, invoker protocol.Invoker, invocation protocol.Invocation) protocol.Result {
+ fmt.Println("MyClientFilter Invoke is called, method Name = ", invocation.MethodName())
+ return invoker.Invoke(ctx, invocation)
+}
+func (f *MyClientFilter) OnResponse(ctx context.Context, result protocol.Result, invoker protocol.Invoker, protocol protocol.Invocation) protocol.Result {
+ fmt.Println("MyClientFilter OnResponse is called")
+ return result
+}
+
+```
+
+
+
diff --git a/content/zh/docs3-building/golang-sdk/tasks/service_management/graceful_shutdown.md b/content/zh/docs3-building/golang-sdk/tasks/service_management/graceful_shutdown.md
new file mode 100644
index 0000000000..47825811a5
--- /dev/null
+++ b/content/zh/docs3-building/golang-sdk/tasks/service_management/graceful_shutdown.md
@@ -0,0 +1,10 @@
+---
+title: 优雅上下线
+type: docs
+weight: 2
+---
+
+# 优雅上下线
+
+
+
diff --git a/content/zh/docs3-building/golang-sdk/tasks/visualization/_index.md b/content/zh/docs3-building/golang-sdk/tasks/visualization/_index.md
new file mode 100644
index 0000000000..73e19c9a8e
--- /dev/null
+++ b/content/zh/docs3-building/golang-sdk/tasks/visualization/_index.md
@@ -0,0 +1,5 @@
+---
+type: docs
+title: "可视化"
+weight: 6
+---
\ No newline at end of file
diff --git a/content/zh/docs3-building/golang-sdk/tasks/visualization/logger.md b/content/zh/docs3-building/golang-sdk/tasks/visualization/logger.md
new file mode 100644
index 0000000000..ec868fa04f
--- /dev/null
+++ b/content/zh/docs3-building/golang-sdk/tasks/visualization/logger.md
@@ -0,0 +1,6 @@
+---
+title: 日志
+type: docs
+weight: 2
+---
+
diff --git a/content/zh/docs3-building/golang-sdk/tasks/visualization/metrics.md b/content/zh/docs3-building/golang-sdk/tasks/visualization/metrics.md
new file mode 100644
index 0000000000..fbc2348c54
--- /dev/null
+++ b/content/zh/docs3-building/golang-sdk/tasks/visualization/metrics.md
@@ -0,0 +1,8 @@
+---
+title: 基于 Prometheus 的数据上报
+type: docs
+weight: 3
+---
+
+# 基于 Prometheus 的数据上报
+
diff --git a/content/zh/docs3-building/golang-sdk/tasks/visualization/opentelementry.md b/content/zh/docs3-building/golang-sdk/tasks/visualization/opentelementry.md
new file mode 100644
index 0000000000..6ad2048dba
--- /dev/null
+++ b/content/zh/docs3-building/golang-sdk/tasks/visualization/opentelementry.md
@@ -0,0 +1,6 @@
+---
+title: 使用 Opentelmentry 协议
+type: docs
+weight: 1
+---
+
diff --git a/content/zh/docs3-building/golang-sdk/tasks/visualization/tracing.md b/content/zh/docs3-building/golang-sdk/tasks/visualization/tracing.md
new file mode 100644
index 0000000000..0c93679454
--- /dev/null
+++ b/content/zh/docs3-building/golang-sdk/tasks/visualization/tracing.md
@@ -0,0 +1,5 @@
+---
+title: 基于 Jaeger 的链路追踪
+type: docs
+weight: 1
+---