PageSourceSearch

https://go-doudou.github.io/assets/go_doudou_dubbo_go.html.0ea1084b.js

js go-doudou.github.io collected 2026-10-03 09:15:17 UTC 63,678 bytes, 251 lines download raw bytes

1import{r as l,o as p,a as o,b as s,e,F as r,f as n,g as c}from"./app.2025f35b.js";import{_ as t}from"./plugin-vue_export-helper.21dcd24c.js";const i={},D=s("h1",{id:"practical-guide-integrating-go-doudou-with-dubbo-go-via-grpc",tabindex:"-1"},[s("a",{class:"header-anchor",href:"#practical-guide-integrating-go-doudou-with-dubbo-go-via-grpc","aria-hidden":"true"},"#"),n(" Practical Guide: Integrating go-doudou with dubbo-go via gRPC")],-1),u=s("img",{src:"https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/3158223bb49441e695370bee3ae570a2~tplv-k3u1fbpfcp-watermark.image?",alt:"image.png"},null,-1),y=n(" Photo by "),b={href:"https://unsplash.com/@neom?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText",target:"_blank",rel:"noopener noreferrer"},d=n("NEOM"),m=n(" on "),g={href:"https://unsplash.com/photos/yUcH008GS6A?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText",target:"_blank",rel:"noopener noreferrer"},C=n("Unsplash"),h=c(`<p>In our practice and exchange of Go language microservices, we&#39;ve learned that some companies or technology teams that previously used Java are now developing microservices with the dubbo-go framework that, together with legacy Java services, form a heterogeneous system. Some technology teams also want to use the go-doudou microservice framework for agile development and rapid service delivery. But the question arises: Can go-doudou interoperate with existing dubbo ecosystem services and join the existing microservice architecture? Since version v2.0.8, go-doudou has implemented a zookeeper-based service registration and discovery mechanism that allows services written with the dubbo framework to interoperate via the gRPC protocol. This article demonstrates how to get started with the go-doudou microservice framework and achieve interoperability with services written in dubbo-go through a simple case. Example code repository address: https://github.com/unionj-cloud/go-doudou-tutorials/tree/master/dubbodemo</p><h2 id="project-structure-explanation" tabindex="-1"><a class="header-anchor" href="#project-structure-explanation" aria-hidden="true">#</a> Project Structure Explanation</h2><div class="language-bash ext-sh line-numbers-mode"><pre class="shiki" style="background-color:#1E1E1E;"><code><span class="line"><span style="color:#DCDCAA;">.</span></span>
2<span class="line"><span style="color:#D4D4D4;">\u251C\u2500\u2500 README.md</span></span>
3<span class="line"><span style="color:#D4D4D4;">\u251C\u2500\u2500 docker-compose.yml</span></span>
4<span class="line"><span style="color:#D4D4D4;">\u251C\u2500\u2500 dubbo</span></span>
5<span class="line"><span style="color:#D4D4D4;">\u2502   \u251C\u2500\u2500 go.mod</span></span>
6<span class="line"><span style="color:#D4D4D4;">\u2502   \u251C\u2500\u2500 go.sum</span></span>
7<span class="line"><span style="color:#D4D4D4;">\u2502   \u2514\u2500\u2500 rpc</span></span>
8<span class="line"><span style="color:#D4D4D4;">\u2502       \u2514\u2500\u2500 grpc</span></span>
9<span class="line"><span style="color:#D4D4D4;">\u2502           \u251C\u2500\u2500 go-client    </span><span style="color:#6A9955;"># dubbo gRPC service consumer</span></span>
10<span class="line"><span style="color:#D4D4D4;">\u2502           \u251C\u2500\u2500 go-server    </span><span style="color:#6A9955;"># dubbo gRPC service provider</span></span>
11<span class="line"><span style="color:#D4D4D4;">\u2502           \u251C\u2500\u2500 protobuf</span></span>
12<span class="line"><span style="color:#D4D4D4;">\u2502           \u2514\u2500\u2500 service-b</span></span>
13<span class="line"><span style="color:#D4D4D4;">\u251C\u2500\u2500 service-a                      </span><span style="color:#6A9955;"># go-doudou RESTful service a</span></span>
14<span class="line"><span style="color:#D4D4D4;">\u2514\u2500\u2500 service-b                      </span><span style="color:#6A9955;"># go-doudou gRPC service b</span></span>
15<span class="line"></span></code></pre><div class="line-numbers"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br></div></div><p>This demo project consists of three microservices and one client program.<br> The three microservices are:</p><ol><li>service-a: A RESTful service using the go-doudou framework, demonstrating how go-doudou calls dubbo-go&#39;s gRPC service through its interface;</li><li>service-b: A gRPC service using the go-doudou framework, used to demonstrate being called by dubbo-go&#39;s client;</li><li>go-server: A gRPC service using the dubbo-go framework, used to demonstrate being called by go-doudou&#39;s client;</li></ol><p>The client program is:</p><ol><li>go-client: A client program using the dubbo-go framework, used to demonstrate dubbo-go calling go-doudou&#39;s gRPC service;</li></ol><h2 id="starting-zookeeper" tabindex="-1"><a class="header-anchor" href="#starting-zookeeper" aria-hidden="true">
15#</a> Starting Zookeeper</h2><p>We first need to start a three-node zookeeper cluster through docker-compose, by executing the command <code>docker-compose -f docker-compose.yml up -d --remove-orphans</code>.</p><div class="language-yaml ext-yml line-numbers-mode"><pre class="shiki" style="background-color:#1E1E1E;"><code><span class="line"><span style="color:#6A9955;"># docker-compose.yml</span></span>
16<span class="line"><span style="color:#569CD6;">version</span><span style="color:#D4D4D4;">: </span><span style="color:#CE9178;">&#39;3.1&#39;</span></span>
17<span class="line"></span>
18<span class="line"><span style="color:#569CD6;">services</span><span style="color:#D4D4D4;">:</span></span>
19<span class="line"><span style="color:#D4D4D4;">  </span><span style="color:#569CD6;">zoo1</span><span style="color:#D4D4D4;">:</span></span>
20<span class="line"><span style="color:#D4D4D4;">    </span><span style="color:#569CD6;">image</span><span style="color:#D4D4D4;">: </span><span style="color:#CE9178;">zookeeper</span></span>
21<span class="line"><span style="color:#D4D4D4;">    </span><span style="color:#569CD6;">restart</span><span style="color:#D4D4D4;">: </span><span style="color:#CE9178;">always</span></span>
22<span class="line"><span style="color:#D4D4D4;">    </span><span style="color:#569CD6;">hostname</span><span style="color:#D4D4D4;">: </span><span style="color:#CE9178;">zoo1</span></span>
23<span class="line"><span style="color:#D4D4D4;">    </span><span style="color:#569CD6;">ports</span><span style="color:#D4D4D4;">:</span></span>
24<span class="line"><span style="color:#D4D4D4;">      - </span><span style="color:#CE9178;">2181:2181</span></span>
25<span class="line"><span style="color:#D4D4D4;">    </span><span style="color:#569CD6;">environment</span><span style="color:#D4D4D4;">:</span></span>
26<span class="line"><span style="color:#D4D4D4;">      </span><span style="color:#569CD6;">ZOO_MY_ID</span><span style="color:#D4D4D4;">: </span><span style="color:#B5CEA8;">1</span></span>
27<span class="line"><span style="color:#D4D4D4;">      </span><span style="color:#569CD6;">ZOO_SERVERS</span><span style="color:#D4D4D4;">: </span><span style="color:#CE9178;">server.1=zoo1:2888:3888;2181 server.2=zoo2:2888:3888;2181 server.3=zoo3:2888:3888;2181</span></span>
28<span class="line"></span>
29<span class="line"><span style="color:#D4D4D4;">  </span><span style="color:#569CD6;">zoo2</span><span style="color:#D4D4D4;">:</span></span>
30<span class="line"><span style="color:#D4D4D4;">    </span><span style="color:#569CD6;">image</span><span style="color:#D4D4D4;">: </span><span style="color:#CE9178;">zookeeper</span></span>
31<span class="line"><span style="color:#D4D4D4;">    </span><span style="color:#569CD6;">restart</span><span style="color:#D4D4D4;">: </span><span style="color:#CE9178;">always</span></span>
32<span class="line"><span style="color:#D4D4D4;">    </span><span style="color:#569CD6;">hostname</span><span style="color:#D4D4D4;">: </span><span style="color:#CE9178;">zoo2</span></span>
33<span class="line"><span style="color:#D4D4D4;">    </span><span style="color:#569CD6;">ports</span><span style="color:#D4D4D4;">:</span></span>
34<span class="line"><span style="color:#D4D4D4;">      - </span><span style="color:#CE9178;">2182:2181</span></span>
35<span class="line"><span style="color:#D4D4D4;">    </span><span style="color:#569CD6;">environment</span><span style="color:#D4D4D4;">:</span></span>
36<span class="line"><span style="color:#D4D4D4;">      </span><span style="color:#569CD6;">ZOO_MY_ID</span><span style="color:#D4D4D4;">: </span><span style="color:#B5CEA8;">2</span></span>
37<span class="line"><span style="color:#D4D4D4;">      </span><span style="color:#569CD6;">ZOO_SERVERS</span><span style="color:#D4D4D4;">: </span><span style="color:#CE9178;">server.1=zoo1:2888:3888;2181 server.2=zoo2:2888:3888;2181 server.3=zoo3:2888:3888;2181</span></span>
38<span class="line"></span>
39<span class="line"><span style="color:#D4D4D4;">  </span><span style="color:#569CD6;">zoo3</span><span style="color:#D4D4D4;">:</span></span>
40<span class="line"><span style="color:#D4D4D4;">    </span><span style="color:#569CD6;">image</span><span style="color:#D4D4D4;">: </span><span style="color:#CE9178;">zookeeper</span></span>
41<span class="line"><span style="color:#D4D4D4;">    </span><span style="color:#569CD6;">restart</span><span style="color:#D4D4D4;">: </span><span style="color:#CE9178;">
41always</span></span>
42<span class="line"><span style="color:#D4D4D4;">    </span><span style="color:#569CD6;">hostname</span><span style="color:#D4D4D4;">: </span><span style="color:#CE9178;">zoo3</span></span>
43<span class="line"><span style="color:#D4D4D4;">    </span><span style="color:#569CD6;">ports</span><span style="color:#D4D4D4;">:</span></span>
44<span class="line"><span style="color:#D4D4D4;">      - </span><span style="color:#CE9178;">2183:2181</span></span>
45<span class="line"><span style="color:#D4D4D4;">    </span><span style="color:#569CD6;">environment</span><span style="color:#D4D4D4;">:</span></span>
46<span class="line"><span style="color:#D4D4D4;">      </span><span style="color:#569CD6;">ZOO_MY_ID</span><span style="color:#D4D4D4;">: </span><span style="color:#B5CEA8;">3</span></span>
47<span class="line"><span style="color:#D4D4D4;">      </span><span style="color:#569CD6;">ZOO_SERVERS</span><span style="color:#D4D4D4;">: </span><span style="color:#CE9178;">server.1=zoo1:2888:3888;2181 server.2=zoo2:2888:3888;2181 server.3=zoo3:2888:3888;2181</span></span>
48<span class="line"></span></code></pre><div class="line-numbers"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br><span class="line-number">20</span><br><span class="line-number">21</span><br><span class="line-number">22</span><br><span class="line-number">23</span><br><span class="line-number">24</span><br><span class="line-number">25</span><br><span class="line-number">26</span><br><span class="line-number">27</span><br><span class="line-number">28</span><br><span class="line-number">29</span><br><span class="line-number">30</span><br><span class="line-number">31</span><br><span class="line-number">32</span><br><span class="line-number">33</span><br></div></div><p>After starting, we can connect to localhost:2181 using prettyZoo to view the nodes. Currently, no services are registered yet.</p><p><img src="https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/6c370c3df18c439a873ec5be02a1bcf8~tplv-k3u1fbpfcp-zoom-1.image" alt=""></p><h2 id="starting-service-b" tabindex="-1"><a class="header-anchor" href="#starting-service-b" aria-hidden="true">#</a> Starting service-b</h2><p>Go to the service-b path and execute the command <code>go run cmd/main.go</code>. When you see the three lines of log output in the red box below, it indicates that the service has started. <img src="https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/d97b13b2848f422896c63e1222a07b9a~tplv-k3u1fbpfcp-watermark.image?" alt="image.png"> Now if we look at prettyZoo again, we can see that the cloud.unionj.ServiceB_grpc service has been registered. <img src="https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/e799de7c45bc454f8834eb54f343d224~tplv-k3u1fbpfcp-watermark.image?" alt="image.png"> The node after providers, <code>grpc%3A%2F%2F192.168.189.126%3A50051%2Fcloud.unionj.ServiceB_grpc%3Fgroup%3Dgroup%26rootPath%3D%26version%3Dv2.2.2%26weight%3D1</code>, is a URL-escaped string. Before escaping, the content is <code>grpc://192.168.189.126:50051/cloud.unionj.ServiceB_grpc?group=group&amp;rootPath=&amp;version=v2.2.2&amp;weight=1</code>. The content and formatting rules of this node are compatible with the dubbo ecosystem, so services can discover each other. Further explanation is as follows:</p><ol><li><code>grpc://</code>: Indicates the communication protocol, which is the gRPC protocol here. go-doudou currently only supports http and gRPC;</li><li><code>192.168.189.126</code>: Indicates the service registration host, by default taking the host&#39;s private IP. This can be customized through the environment variable <code>GDD_REGISTER_HOST</code>;</li><li><code>50051</code>: Indicates the gRPC service port number, default 50051. This can be customized through the environment variable <code>GDD_GRPC_PORT</code>;</li><li><code>cloud.unionj.ServiceB_grpc</code>: Indicates the service name, formed by the user-configured service name + underscore 
48+ communication protocol. Since the go-doudou framework supports starting the same set of code to provide both http protocol RESTful services and gRPC protocol RPC services, the underscore + communication protocol is needed for distinction. In this example, the service name configured by the user through the environment variable <code>GDD_SERVICE_NAME</code> is cloud.unionj.ServiceB, and go-doudou added <code>_grpc</code>;</li><li><code>group</code>: Indicates the service group name, which can be customized through the environment variable <code>GDD_SERVICE_GROUP</code>;</li><li><code>version</code>: Indicates the service version, which can be customized through the environment variable <code>GDD_SERVICE_VERSION</code>. The service name + service group name + service version together uniquely identify a service, and if any one does not match, the service cannot be called;</li><li><code>rootPath</code>: Indicates the interface path prefix, only valid under the http protocol;</li><li><code>weight</code>: Indicates the weight of the service instance, used for client load balancing, default 1. This can be customized through the environment variable <code>GDD_WEIGHT</code>;</li></ol><p>Let&#39;s look at the RPC interface provided by ServiceB.</p><div class="language-go ext-go line-numbers-mode"><pre class="shiki" style="background-color:#1E1E1E;"><code><span class="line"><span style="color:#6A9955;">// svc.go</span></span>
49<span class="line"><span style="color:#569CD6;">package</span><span style="color:#D4D4D4;"> service</span></span>
50<span class="line"></span>
51<span class="line"><span style="color:#569CD6;">import</span><span style="color:#D4D4D4;"> (</span></span>
52<span class="line"><span style="color:#D4D4D4;">   </span><span style="color:#CE9178;">&quot;context&quot;</span></span>
53<span class="line"><span style="color:#D4D4D4;">   </span><span style="color:#CE9178;">&quot;service-b/dto&quot;</span></span>
54<span class="line"><span style="color:#D4D4D4;">)</span></span>
55<span class="line"></span>
56<span class="line"><span style="color:#6A9955;">//go:generate go-doudou svc http -c</span></span>
57<span class="line"><span style="color:#6A9955;">//go:generate go-doudou svc grpc</span></span>
58<span class="line"></span>
59<span class="line"><span style="color:#569CD6;">type</span><span style="color:#D4D4D4;"> </span><span style="color:#4EC9B0;">ServiceB</span><span style="color:#D4D4D4;"> </span><span style="color:#569CD6;">interface</span><span style="color:#D4D4D4;"> {</span></span>
60<span class="line"><span style="color:#D4D4D4;">   </span><span style="color:#DCDCAA;">GetDeptById</span><span style="color:#D4D4D4;">(ctx context.Context, deptId </span><span style="color:#4EC9B0;">int</span><span style="color:#D4D4D4;">) (dept dto.DeptDto, err </span><span style="color:#4EC9B0;">error</span><span style="color:#D4D4D4;">)</span></span>
61<span class="line"><span style="color:#D4D4D4;">}</span></span>
62<span class="line"></span></code></pre><div class="line-numbers"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br></div></div><p>From the svc.go file, we can see that ServiceB service defines only one RPC interface, with the department ID as input and the department DTO and error as output. Let&#39;s see how the interface is implemented.</p><div class="language-go ext-go line-numbers-mode"><pre class="shiki" style="background-color:#1E1E1E;"><code><span class="line"><span style="color:#6A9955;">// svcimpl.go</span></span>
63<span class="line"><span style="color:#569CD6;">func</span><span style="color:#D4D4D4;"> (receiver *ServiceBImpl) </span><span style="color:#DCDCAA;">GetDeptByIdRpc</span><span style="color:#D4D4D4;">(ctx context.Context, request *pb.GetDeptByIdRpcRequest) (*pb.DeptDto, </span><span style="color:#4EC9B0;">error</span><span style="color:#D4D4D4;">) {</span></span>
64<span class="line"><span style="color:#D4D4D4;">   </span><span style="color:#C586C0;">return</span><span style="color:#D4D4D4;"> &amp;pb.DeptDto{</span></span>
65<span class="line"><span style="color:#D4D4D4;">      Id:         request.DeptId,</span></span>
66<span class="line"><span style="color:#D4D4D4;">      Name:       </span><span style="color:#CE9178;">&quot;Test Department&quot;</span><span style="color:#D4D4D4;">,</span></span>
67<span class="line"><span style="color:#D4D4D4;">
67      StaffTotal: </span><span style="color:#B5CEA8;">10</span><span style="color:#D4D4D4;">,</span></span>
68<span class="line"><span style="color:#D4D4D4;">   }, </span><span style="color:#569CD6;">nil</span></span>
69<span class="line"><span style="color:#D4D4D4;">}</span></span>
70<span class="line"></span></code></pre><div class="line-numbers"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br></div></div><p>The implementation logic is very simple, the returned department name is always &quot;Test Department&quot;, and the department ID takes the value passed in.</p><h2 id="starting-go-server" tabindex="-1"><a class="header-anchor" href="#starting-go-server" aria-hidden="true">#</a> Starting go-server</h2><p>Go to the <code>dubbo/rpc/grpc/go-server</code> path and execute the command <code>go run cmd/server.go</code>.</p><p><img src="https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/a0a61f846978418bba1ac5a4e78f7bc0~tplv-k3u1fbpfcp-watermark.image?" alt="image.png"> The log output when dubbo-go service starts is quite long, but seeing the log output in the screenshot above indicates that the service has started and registered successfully.</p><p><img src="https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/218d6c3cc4974509b17be921d3fe7643~tplv-k3u1fbpfcp-watermark.image?" alt="image.png"> We can also see the nodes registered by dubbo-go through prettyZoo.<br> Regarding the usage of dubbo-go, colleagues who have used or are using dubbo-go do not need to be introduced, and it is not the focus of this article. Open the server.go file, let&#39;s look at the interface implementation provided by go-server.</p><div class="language-go ext-go line-numbers-mode"><pre class="shiki" style="background-color:#1E1E1E;"><code><span class="line"><span style="color:#569CD6;">type</span><span style="color:#D4D4D4;"> </span><span style="color:#4EC9B0;">GreeterProvider</span><span style="color:#D4D4D4;"> </span><span style="color:#569CD6;">struct</span><span style="color:#D4D4D4;"> {</span></span>
71<span class="line"><span style="color:#D4D4D4;">   pb.GreeterProviderBase</span></span>
72<span class="line"><span style="color:#D4D4D4;">}</span></span>
73<span class="line"></span>
74<span class="line"><span style="color:#569CD6;">func</span><span style="color:#D4D4D4;"> (g *GreeterProvider) </span><span style="color:#DCDCAA;">SayHello</span><span style="color:#D4D4D4;">(ctx context.Context, req *pb.HelloRequest) (reply *pb.HelloReply, err </span><span style="color:#4EC9B0;">error</span><span style="color:#D4D4D4;">) {</span></span>
75<span class="line"><span style="color:#D4D4D4;">   fmt.</span><span style="color:#DCDCAA;">Printf</span><span style="color:#D4D4D4;">(</span><span style="color:#CE9178;">&quot;req: </span><span style="color:#9CDCFE;">%v</span><span style="color:#CE9178;">&quot;</span><span style="color:#D4D4D4;">, req)</span></span>
76<span class="line"><span style="color:#D4D4D4;">   </span><span style="color:#C586C0;">return</span><span style="color:#D4D4D4;"> &amp;pb.HelloReply{Message: </span><span style="color:#CE9178;">&quot;this is message from reply&quot;</span><span style="color:#D4D4D4;">}, </span><span style="color:#569CD6;">nil</span></span>
77<span class="line"><span style="color:#D4D4D4;">}</span></span>
78<span class="line"></span></code></pre><div class="line-numbers"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br></div></div><p>Very simple, just an RPC interface called SayHello.</p><h2 id="starting-service-a" tabindex="-1"><a class="header-anchor" href="#starting-service-a" aria-hidden="true">#</a> Starting service-a</h2><p>Go to service-a and execute the command <code>go run cmd/main.go</code>.</p><p><img src="https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/bec098bca54e4667a5d428217075ccad~tplv-k3u1fbpfcp-watermark.image?" alt="image.png"> When you see the log output as shown in the figure above, it indicates that the service has started successfully. Let&#39;s look at the service registration node through prettyZoo again.</p><p><img src="https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/74b27985feae4846a119cbb00aed66d2~tplv-k3u1fbpfcp-watermark.image?" alt="image.png"> cloud.unionj.ServiceA_rest is the node that service-a registers to zookeeper.</p><p>Let&#39;s look at the RESTful interface provided by service-a.</p><div class="language-go ext-go line-numbers-mode"><pre class="shiki" style="background-color:#1E1E1E;"><code><span class="line"><span style="color:#569CD6;">package</span><span style="color:#D4D4D4;"> service</span></span>
79<span class="line"></span>
80<span class="line"><span style="color:#569CD6;">
80import</span><span style="color:#D4D4D4;"> (</span></span>
81<span class="line"><span style="color:#D4D4D4;">   </span><span style="color:#CE9178;">&quot;context&quot;</span></span>
82<span class="line"><span style="color:#D4D4D4;">   </span><span style="color:#CE9178;">&quot;service-a/dto&quot;</span></span>
83<span class="line"><span style="color:#D4D4D4;">)</span></span>
84<span class="line"></span>
85<span class="line"><span style="color:#6A9955;">//go:generate go-doudou svc http -c</span></span>
86<span class="line"><span style="color:#6A9955;">//go:generate go-doudou svc grpc</span></span>
87<span class="line"></span>
88<span class="line"><span style="color:#569CD6;">type</span><span style="color:#D4D4D4;"> </span><span style="color:#4EC9B0;">ServiceA</span><span style="color:#D4D4D4;"> </span><span style="color:#569CD6;">interface</span><span style="color:#D4D4D4;"> {</span></span>
89<span class="line"><span style="color:#D4D4D4;">   </span><span style="color:#DCDCAA;">GetUserById</span><span style="color:#D4D4D4;">(ctx context.Context, userId </span><span style="color:#4EC9B0;">int</span><span style="color:#D4D4D4;">) (user dto.UserDto, err </span><span style="color:#4EC9B0;">error</span><span style="color:#D4D4D4;">)</span></span>
90<span class="line"><span style="color:#D4D4D4;">   </span><span style="color:#DCDCAA;">GetRpcUserById</span><span style="color:#D4D4D4;">(ctx context.Context, userId </span><span style="color:#4EC9B0;">int</span><span style="color:#D4D4D4;">) (user dto.UserDto, err </span><span style="color:#4EC9B0;">error</span><span style="color:#D4D4D4;">)</span></span>
91<span class="line"><span style="color:#D4D4D4;">   </span><span style="color:#DCDCAA;">GetRpcSayHello</span><span style="color:#D4D4D4;">(ctx context.Context, name </span><span style="color:#4EC9B0;">string</span><span style="color:#D4D4D4;">) (reply </span><span style="color:#4EC9B0;">string</span><span style="color:#D4D4D4;">, err </span><span style="color:#4EC9B0;">error</span><span style="color:#D4D4D4;">)</span></span>
92<span class="line"><span style="color:#D4D4D4;">}</span></span>
93<span class="line"></span></code></pre><div class="line-numbers"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br></div></div><p>Let&#39;s focus on the two interfaces with the <code>GetRpc</code> prefix, which are interfaces used as clients to call gRPC services. <code>GetRpcUserById</code> calls the service-b service, and <code>GetRpcSayHello</code> calls the go-server service. Let&#39;s continue to look at the interface implementation code of ServiceA.</p><div class="language-go ext-go line-numbers-mode"><pre class="shiki" style="background-color:#1E1E1E;"><code><span class="line"><span style="color:#569CD6;">var</span><span style="color:#D4D4D4;"> </span><span style="color:#9CDCFE;">_</span><span style="color:#D4D4D4;"> ServiceA = (*ServiceAImpl)(</span><span style="color:#569CD6;">nil</span><span style="color:#D4D4D4;">)</span></span>
94<span class="line"></span>
95<span class="line"><span style="color:#569CD6;">type</span><span style="color:#D4D4D4;"> </span><span style="color:#4EC9B0;">ServiceAImpl</span><span style="color:#D4D4D4;"> </span><span style="color:#569CD6;">struct</span><span style="color:#D4D4D4;"> {</span></span>
96<span class="line"><span style="color:#D4D4D4;">   conf          *config.Config</span></span>
97<span class="line"><span style="color:#D4D4D4;">   bClient       client.IServiceBClient</span></span>
98<span class="line"><span style="color:#D4D4D4;">   grpcClient    pb.ServiceBServiceClient</span></span>
99<span class="line"><span style="color:#D4D4D4;">   greeterClient protobuf.GreeterClient</span></span>
100<span class="line"><span style="color:#D4D4D4;">}</span></span>
101<span class="line"></span></code></pre><div class="line-numbers"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br></div></div><p>The ServiceA interface implementation structure ServiceAImpl has two gRPC client member variables:</p><ol><li>grpcClient: service-b&#39;s gRPC client</li><li>greeterClient: go-server&#39;s gRPC client</li></ol><p>These two clients are injected in the main.go file:</p><div class="language-go ext-go line-numbers-mode"><pre class="shiki" style="background-color:#1E1E1E;"><code><span class="line"><span style="color:#6A9955;">// Establish a gRPC connection to ServiceB based on zk, with built-in smooth weighted load balancing</span></span>
102<span class="line"><span style="color:#9CDCFE;">grpcConn</span><span style="color:#D4D4D4;"> := zk.</span><span style="color:#DCDCAA;">NewSWRRGrpcClientConn</span><span style="color:#D4D4D4;">(zk.ServiceConfig{</span></span>
103<span class="line"><span style="color:#D4D4D4;">   Name:    </span><span style="color:#CE9178;">&quot;cloud.unionj.ServiceB_grpc&quot;</span><span style="color:#D4D4D4;">,</span></span>
104<span class="line"><span style="color:#D4D4D4;">   Group:   </span><span style="color:#CE9178;">&quot;group&quot;</span><span style="color:#D4D4D4;">,</span></span>
105<span class="line"><span style="color:#D4D4D4;">   Version: </span><span style="color:#CE9178;">&quot;v2.2.2&quot;</span><span style="color:#D4D4D4;">,</span></span>
106<span class="line"><span style="color:#D4D4D4;">}, dialOptions...)</span></span>
107<span class="line"><span style="color:#C586C0;">defer</span><span style="color:#D4D4D4;"> grpcConn.</span><span style="color:#DCDCAA;">Close</span><span style="color:#D4D4D4;">()</span></span>
108<span class="line"></span>
109<span class="line"><span style="color:#6A9955;">// Connect to ServiceB&#39;s gRPC server using the gRPC connection</span></span>
110<span class="line"><span style="color:#9CDCFE;">grpcClient</span><span style="color:#D4D4D4;"> := pb.</span><span style="color:#DCDCAA;">NewServiceBServiceClient</span><span style="color:#D4D4D4;">(grpcConn)</span></span>
111<span class="line"></span>
112<span class="line"><span style="color:#6A9955;">// Similarly, establish a gRPC connection to go-server based on zk, with built-in smooth weighted load balancing</span></span>
113<span class="line"><span style="color:#9CDCFE;">dubbo</span><span style="color:#D4D4D4;"> := zk.</span><span style="color:#DCDCAA;">NewSWRRGrpcClientConn</span><span style="color:#D4D4D4;">(zk.ServiceConfig{</span></span>
114<span class="line"><span style="color:#D4D4D4;">   Name:    </span><span style="color:#CE9178;">&quot;org.apache.dubbo.sample.GreeterProvider&quot;</span><span style="color:#D4D4D4;">,</span></span>
115<span class="line"><span style="color:#D4D4D4;">   Group:   </span><span style="color:#CE9178;">&quot;group&quot;</span><span style="color:#D4D4D4;">,</span></span>
116<span class="line"><span style="color:#D4D4D4;">   Version: </span><span style="color:#CE9178;">&quot;v2.2.2&quot;</span><span style="color:#D4D4D4;">,</span></span>
117<span class="line"><span style="color:#D4D4D4;">}, dialOptions...)</span></span>
118<span class="line"><span style="color:#C586C0;">defer</span><span style="color:#D4D4D4;"> dubbo.</span><span style="color:#DCDCAA;">Close</span><span style="color:#D4D4D4;">()</span></span>
119<span class="line"></span>
120<span class="line"><span style="color:#6A9955;">// Connect to go-server&#39;s gRPC server using the gRPC connection</span></span>
121<span class="line"><span style="color:#9CDCFE;">greeterClient</span><span style="color:#D4D4D4;"> := protobuf.</span><span style="color:#DCDCAA;">NewGreeterClient</span><span style="color:#D4D4D4;">(dubbo)</span></span>
122<span class="line"></span></code></pre><div class="line-numbers"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br><span class="line-number">20</span><br><span class="line-number">21</span><br></div></div><p>So far, the go-doudou service client has successfully connected to both the go-doudou gRPC service and the dubbo-go gRPC service. Let&#39;s look at the implementation code for <code>GetRpcUserById</code> and <code>GetRpcSayHello</code>:</p><div class="language-go ext-go line-numbers-mode"><pre class="shiki" style="background-color:#1E1E1E;"><code><span class="line"><span style="color:#569CD6;">func</span><span style="color:#D4D4D4;"> (receiver *ServiceAImpl) </span><span style="color:#DCDCAA;">GetRpcUserById</span><span style="color:#D4D4D4;">(ctx context.Context, userId </span><span style="color:#4EC9B0;">int</span><span style="color:#D4D4D4;">) (user dto.UserDto, err </span><span style="color:#4EC9B0;">error</span><span style="color:#D4D4D4;">) {</span></span>
123<span class="line"><span style="color:#D4D4D4;">   </span><span style="color:#6A9955;">// Use the gRPC client to call service-b through the gRPC protocol</span></span>
124<span class="line"><span style="color:#D4D4D4;">   </span><span style="color:#9CDCFE;">output</span><span style="color:#D4D4D4;">, </span><span style="color:#9CDCFE;">err</span><span style="color:#D4D4D4;"> := receiver.grpcClient.</span><span style="color:#DCDCAA;">GetDeptByIdRpc</span><span style="color:#D4D4D4;">(ctx, &amp;pb.GetDeptByIdRpcRequest{</span></span>
125<span class="line"><span style="color:#D4D4D4;">      DeptId: </span><span style="color:#DCDCAA;">int32</span><span style="color:#D4D4D4;">(userId),</span></span>
126<span class="line"><span style="color:#D4D4D4;">   })</span></span>
127<span class="line"><span style="color:#D4D4D4;">   </span><span style="color:#C586C0;">if</span><span style="color:#D4D4D4;"> err != </span><span style="color:#569CD6;">nil</span><span style="color:#D4D4D4;"> {</span></span>
128<span class="line"><span style="color:#D4D4D4;">      </span><span style="color:#C586C0;">return</span></span>
129<span class="line"><span style="color:#D4D4D4;">   }</span></span>
130<span class="line"><span style="color:#D4D4D4;">   </span><span style="color:#9CDCFE;">user</span><span style="color:#D4D4D4;"> = dto.UserDto{</span></span>
131<span class="line"><span style="color:#D4D4D4;">      Id:       </span><span style="color:#DCDCAA;">int</span><span style="color:#D4D4D4;">(output.Id),</span></span>
132<span class="line"><span style="color:#D4D4D4;">      Name:     </span><span style="color:#CE9178;">&quot;test&quot;</span><span style="color:#D4D4D4;">,</span></span>
133<span class="line"><span style="color:#D4D4D4;">      DeptId:   </span><span style="color:#DCDCAA;">int</span><span style="color:#D4D4D4;">(output.Id),</span></span>
134<span class="line"><span style="color:#D4D4D4;">      DeptName: output.Name,</span></span>
135<span class="line"><span style="color:#D4D4D4;">   }</span></span>
136<span class="line"><span style="color:#D4D4D4;">   </span><span style="color:#C586C0;">return</span></span>
137<span class="line"><span style="color:#D4D4D4;">}</span></span>
138<span class="line"></span>
139<span class="line"><span style="color:#569CD6;">func</span><span style="color:#D4D4D4;"> (receiver *ServiceAImpl) </span><span style="color:#DCDCAA;">GetRpcSayHello</span><span style="color:#D4D4D4;">(ctx context.Context, name </span><span style="color:#4EC9B0;">string</span><span style="color:#D4D4D4;">) (reply </span><span style="color:#4EC9B0;">string</span><span style="color:#D4D4D4;">, err </span><span style="color:#4EC9B0;">error</span><span style="color:#D4D4D4;">) {</span></span>
140<span class="line"><span style="color:#D4D4D4;">   </span><span style="color:#6A9955;">// Use the gRPC client to call go-server through the gRPC protocol</span></span>
141<span class="line"><span style="color:#D4D4D4;">   </span><span style="color:#9CDCFE;">output</span><span style="color:#D4D4D4;">, </span><span style="color:#9CDCFE;">err</span><span style="color:#D4D4D4;"> := receiver.greeterClient.</span><span style="color:#DCDCAA;">SayHello</span><span style="color:#D4D4D4;">(ctx, &amp;protobuf.HelloRequest{</span></span>
142<span class="line"><span style="color:#D4D4D4;">      Name: name,</span></span>
143<span class="line"><span style="color:#D4D4D4;">   })</span></span>
144<span class="line"><span style="color:#D4D4D4;">   </span><span style="color:#C586C0;">if</span><span style="color:#D4D4D4;"> err != </span><span style="color:#569CD6;">nil</span><span style="color:#D4D4D4;"> {</span></span>
145<span class="line"><span style="color:#D4D4D4;">      </span><span style="color:#C586C0;">return</span></span>
146<span class="line"><span style="color:#D4D4D4;">   }</span></span>
147<span class="line"><span style="color:#D4D4D4;">   </span><span style="color:#9CDCFE;">reply</span><span style="color:#D4D4D4;"> = output.Message</span></span>
148<span class="line"><span style="color:#D4D4D4;">   </span><span style="color:#C586C0;">return</span></span>
149<span class="line"><span style="color:#D4D4D4;">}</span></span>
150<span class="line"></span></code></pre><div class="line-numbers"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br><span class="line-number">20</span><br><span class="line-number">21</span><br><span class="line-number">22</span><br><span class="line-number">23</span><br><span class="line-number">24</span><br><span class="line-number">25</span><br><span class="line-number">26</span><br><span class="line-number">27</span><br><span class="line-number">28</span><br></div></div><p>Testing service-a&#39;s implementation call to service-b:</p><div class="language-bash ext-sh line-numbers-mode"><pre class="shiki" style="background-color:#1E1E1E;"><code><span class="line"><span style="color:#D4D4D4;">curl -X </span><span style="color:#CE9178;">&#39;GET&#39;</span><span style="color:#D4D4D4;"> \\</span></span>
151<span class="line"><span style="color:#D4D4D4;">  </span><span style="color:#CE9178;">&#39;http://localhost:6060/v1/rpcdept?userId=1&#39;</span><span style="color:#D4D4D4;"> \\</span></span>
152<span class="line"><span style="color:#D4D4D4;">  -H </span><span style="color:#CE9178;">&#39;accept: application/json&#39;</span></span>
153<span class="line"></span></code></pre><div class="line-numbers"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br></div></div><p>And we get the response:</p><div class="language-json ext-json line-numbers-mode"><pre class="shiki" style="background-color:#1E1E1E;"><code><span class="line"><span style="color:#D4D4D4;">{</span></span>
154<span class="line"><span style="color:#D4D4D4;">  </span><span style="color:#9CDCFE;">&quot;id&quot;</span><span style="color:#D4D4D4;">: </span><span style="color:#B5CEA8;">1</span><span style="color:#D4D4D4;">,</span></span>
155<span class="line"><span style=
155"color:#D4D4D4;">  </span><span style="color:#9CDCFE;">&quot;name&quot;</span><span style="color:#D4D4D4;">: </span><span style="color:#CE9178;">&quot;test&quot;</span><span style="color:#D4D4D4;">,</span></span>
156<span class="line"><span style="color:#D4D4D4;">  </span><span style="color:#9CDCFE;">&quot;deptId&quot;</span><span style="color:#D4D4D4;">: </span><span style="color:#B5CEA8;">1</span><span style="color:#D4D4D4;">,</span></span>
157<span class="line"><span style="color:#D4D4D4;">  </span><span style="color:#9CDCFE;">&quot;deptName&quot;</span><span style="color:#D4D4D4;">: </span><span style="color:#CE9178;">&quot;Test Department&quot;</span></span>
158<span class="line"><span style="color:#D4D4D4;">}</span></span>
159<span class="line"></span></code></pre><div class="line-numbers"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br></div></div><p>Now, let&#39;s test service-a&#39;s implementation call to go-server:</p><div class="language-bash ext-sh line-numbers-mode"><pre class="shiki" style="background-color:#1E1E1E;"><code><span class="line"><span style="color:#D4D4D4;">curl -X </span><span style="color:#CE9178;">&#39;GET&#39;</span><span style="color:#D4D4D4;"> \\</span></span>
160<span class="line"><span style="color:#D4D4D4;">  </span><span style="color:#CE9178;">&#39;http://localhost:6060/v1/rpchello?name=yongchang&#39;</span><span style="color:#D4D4D4;"> \\</span></span>
161<span class="line"><span style="color:#D4D4D4;">  -H </span><span style="color:#CE9178;">&#39;accept: application/json&#39;</span></span>
162<span class="line"></span></code></pre><div class="line-numbers"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br></div></div><p>And we get the response:</p><div class="language-json ext-json line-numbers-mode"><pre class="shiki" style="background-color:#1E1E1E;"><code><span class="line"><span style="color:#CE9178;">&quot;this is message from reply&quot;</span></span>
163<span class="line"></span></code></pre><div class="line-numbers"><span class="line-number">1</span><br></div></div><h2 id="starting-go-client" tabindex="-1"><a class="header-anchor" href="#starting-go-client" aria-hidden="true">#</a> Starting go-client</h2><p>Go to the <code>dubbo/rpc/grpc/go-client</code> path and execute the command <code>go run cmd/client.go</code>:</p><p><img src="https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/51e69e37b8e041a6b4e4a7cb10dd9e75~tplv-k3u1fbpfcp-watermark.image?" alt="image.png"></p><p>When you see the log output as shown in the figure above, it indicates that the client has started successfully, successfully called service-b, and got the return value <code>{Id:1 Name:Test Department StaffTotal:10}</code>.</p><p>Let&#39;s look at the code implementation of go-client:</p><div class="language-go ext-go line-numbers-mode"><pre class="shiki" style="background-color:#1E1E1E;"><code><span class="line"><span style="color:#569CD6;">import</span><span style="color:#D4D4D4;"> (</span></span>
164<span class="line"><span style="color:#D4D4D4;">	</span><span style="color:#CE9178;">&quot;context&quot;</span></span>
165<span class="line"><span style="color:#D4D4D4;">	</span><span style="color:#CE9178;">&quot;fmt&quot;</span></span>
166<span class="line"><span style="color:#D4D4D4;">	</span><span style="color:#CE9178;">&quot;os&quot;</span></span>
167<span class="line"><span style="color:#D4D4D4;">	</span><span style="color:#CE9178;">&quot;os/signal&quot;</span></span>
168<span class="line"><span style="color:#D4D4D4;">	</span><span style="color:#CE9178;">&quot;syscall&quot;</span></span>
169<span class="line"><span style="color:#D4D4D4;">	</span><span style="color:#CE9178;">&quot;time&quot;</span></span>
170<span class="line"></span>
171<span class="line"><span style="color:#D4D4D4;">	</span><span style="color:#CE9178;">&quot;dubbo.apache.org/dubbo-go/v3/common/constant&quot;</span></span>
172<span class="line"><span style="color:#D4D4D4;">	</span><span style="color:#CE9178;">&quot;dubbo.apache.org/dubbo-go/v3/common/logger&quot;</span></span>
173<span class="line"><span style="color:#D4D4D4;">	</span><span style="color:#CE9178;">&quot;dubbo.apache.org/dubbo-go/v3/config&quot;</span></span>
174<span class="line"><span style="color:#D4D4D4;">	_ </span><span style="color:#CE9178;">&quot;dubbo.apache.org/dubbo-go/v3/imports&quot;</span></span>
175<span class="line"></span>
176<span class="line"><span style="color:#D4D4D4;">	_ </span><span style="color:#CE9178;">&quot;github.com/dubbogo/gost/log/logrus&quot;</span></span>
177<span class="line"></span>
178<span class="line"><span style="color:#D4D4D4;">	</span><span style="color:#CE9178;">&quot;github.com/unionj-cloud/go-doudou-tutorials/dubbodemo/dubbo/rpc/grpc/service-b&quot;</span></span>
179<span class="line"><span style="color:#D4D4D4;">)</span></span>
180<span class="line"></span>
181<span class="line"><span style="color:#569CD6;">type</span><span style="color:#D4D4D4;"> </span><span style="color:#4EC9B0;">Client</span><span style="color:#D4D4D4;"> </span><span style="color:#569CD6;">struct</span><span style="color:#D4D4D4;"> {</span></span>
182<span class="line"><span style="color:#D4D4D4;">	ServiceBClientImpl service_b.ServiceBClientImpl</span></span>
183<span class="line"><span style="color:#D4D4D4;">}</span></span>
184<span class="line"></span>
185<span class="line"><span style="color:#569CD6;">func</span><span style="color:#D4D4D4;"> </span><span style="color:#DCDCAA;">main</span><span style="color:#D4D4D4;">() {</span></span>
186<span class="line"><span style="color:#D4D4D4;">	config.</span><span style="color:#DCDCAA;">SetConsumerService</span><span style="color:#D4D4D4;">(&amp;Client{})</span></span>
187<span class="line"><span style="color:#D4D4D4;">	</span><span style="color:#C586C0;">if</span><span style="color:#D4D4D4;"> </span><span style="color:#9CDCFE;">err</span><span style="color:#D4D4D4;"> := config.</span><span style="color:#DCDCAA;">Load</span><span style="color:#D4D4D4;">(); err != </span><span style="color:#569CD6;">nil</span><span style="color:#D4D4D4;"> {</span></span>
188<span class="line"><span style="color:#D4D4D4;">		</span><span style="color:#DCDCAA;">panic</span><span style="color:#D4D4D4;">(err)</span></span>
189<span class="line"><span style="color:#D4D4D4;">	}</span></span>
190<span class="line"></span>
191<span class="line"><span style="color:#D4D4D4;">	logger.</span><span style="color:#DCDCAA;">Info</span><span style="color:#D4D4D4;">(</span><span style="color:#CE9178;">&quot;start to test dubbo&quot;</span><span style="color:#D4D4D4;">)</span></span>
192<span class="line"><span style="color:#D4D4D4;">	</span><span style="color:#9CDCFE;">client</span><span style="color:#D4D4D4;"> := &amp;Client{}</span></span>
193<span class="line"><span style="color:#D4D4D4;">	</span><span style="color:#C586C0;">
193for</span><span style="color:#D4D4D4;"> </span><span style="color:#9CDCFE;">i</span><span style="color:#D4D4D4;"> := </span><span style="color:#B5CEA8;">0</span><span style="color:#D4D4D4;">; i &lt; </span><span style="color:#B5CEA8;">10</span><span style="color:#D4D4D4;">; i++ {</span></span>
194<span class="line"><span style="color:#D4D4D4;">		</span><span style="color:#9CDCFE;">deptDto</span><span style="color:#D4D4D4;">, </span><span style="color:#9CDCFE;">err</span><span style="color:#D4D4D4;"> := client.ServiceBClientImpl.</span><span style="color:#DCDCAA;">GetDeptById</span><span style="color:#D4D4D4;">(context.</span><span style="color:#DCDCAA;">TODO</span><span style="color:#D4D4D4;">(), </span><span style="color:#B5CEA8;">1</span><span style="color:#D4D4D4;">)</span></span>
195<span class="line"><span style="color:#D4D4D4;">		</span><span style="color:#C586C0;">if</span><span style="color:#D4D4D4;"> err != </span><span style="color:#569CD6;">nil</span><span style="color:#D4D4D4;"> {</span></span>
196<span class="line"><span style="color:#D4D4D4;">			fmt.</span><span style="color:#DCDCAA;">Printf</span><span style="color:#D4D4D4;">(</span><span style="color:#CE9178;">&quot;error: </span><span style="color:#9CDCFE;">%v</span><span style="color:#CE9178;">&quot;</span><span style="color:#D4D4D4;">, err)</span></span>
197<span class="line"><span style="color:#D4D4D4;">			</span><span style="color:#C586C0;">return</span></span>
198<span class="line"><span style="color:#D4D4D4;">		}</span></span>
199<span class="line"><span style="color:#D4D4D4;">		fmt.</span><span style="color:#DCDCAA;">Printf</span><span style="color:#D4D4D4;">(</span><span style="color:#CE9178;">&quot;response result: </span><span style="color:#9CDCFE;">%v</span><span style="color:#D7BA7D;">\\n</span><span style="color:#CE9178;">&quot;</span><span style="color:#D4D4D4;">, deptDto)</span></span>
200<span class="line"><span style="color:#D4D4D4;">		time.</span><span style="color:#DCDCAA;">Sleep</span><span style="color:#D4D4D4;">(</span><span style="color:#B5CEA8;">1</span><span style="color:#D4D4D4;"> * time.Second)</span></span>
201<span class="line"><span style="color:#D4D4D4;">	}</span></span>
202<span class="line"></span>
203<span class="line"><span style="color:#D4D4D4;">	</span><span style="color:#DCDCAA;">initSignal</span><span style="color:#D4D4D4;">()</span></span>
204<span class="line"><span style="color:#D4D4D4;">}</span></span>
205<span class="line"></span>
206<span class="line"><span style="color:#569CD6;">func</span><span style="color:#D4D4D4;"> </span><span style="color:#DCDCAA;">initSignal</span><span style="color:#D4D4D4;">() {</span></span>
207<span class="line"><span style="color:#D4D4D4;">	</span><span style="color:#9CDCFE;">signals</span><span style="color:#D4D4D4;"> := </span><span style="color:#DCDCAA;">make</span><span style="color:#D4D4D4;">(</span><span style="color:#569CD6;">chan</span><span style="color:#D4D4D4;"> os.Signal, </span><span style="color:#B5CEA8;">1</span><span style="color:#D4D4D4;">)</span></span>
208<span class="line"><span style="color:#D4D4D4;">	</span><span style="color:#6A9955;">// It is not possible to block SIGKILL or syscall.SIGSTOP</span></span>
209<span class="line"><span style="color:#D4D4D4;">	signal.</span><span style="color:#DCDCAA;">Notify</span><span style="color:#D4D4D4;">(signals, os.Interrupt, syscall.SIGHUP, syscall.SIGQUIT, syscall.SIGTERM)</span></span>
210<span class="line"><span style="color:#D4D4D4;">	</span><span style="color:#C586C0;">for</span><span style="color:#D4D4D4;"> {</span></span>
211<span class="line"><span style="color:#D4D4D4;">		</span><span style="color:#9CDCFE;">sig</span><span style="color:#D4D4D4;"> := &lt;-signals</span></span>
212<span class="line"><span style="color:#D4D4D4;">		logger.</span><span style="color:#DCDCAA;">Infof</span><span style="color:#D4D4D4;">(</span><span style="color:#CE9178;">&quot;get signal </span><span style="color:#9CDCFE;">%s</span><span style="color:#CE9178;">&quot;</span><span style="color:#D4D4D4;">, sig.</span><span style="color:#DCDCAA;">String</span><span style="color:#D4D4D4;">())</span></span>
213<span class="line"><span style="color:#D4D4D4;">		</span><span style="color:#C586C0;">switch</span><span style="color:#D4D4D4;"> sig {</span></span>
214<span class="line"><span style="color:#D4D4D4;">		</span><span style="color:#C586C0;">case</span><span style="color:#D4D4D4;"> syscall.SIGHUP:</span></span>
215<span class="line"><span style="color:#D4D4D4;">			</span><span style="color:#6A9955;">// reload()</span></span>
216<span class="line"><span style="color:#D4D4D4;">		</span><span style="color:#C586C0;">default</span><span style="color:#D4D4D4;">:</span></span>
217<span class="line"><span style="color:#D4D4D4;">			time.</span><span style="color:#DCDCAA;">AfterFunc</span><span style="color:#D4D4D4;">(time.</span><span style="color:#DCDCAA;">Duration</span><span style="color:#D4D4D4;">(</span><span style="color:#DCDCAA;">int</span><span style="color:#D4D4D4;">(</span><span style="color:#B5CEA8;">3e9</span><span style="color:#D4D4D4;">)), </span><span style="color:#569CD6;">func</span><span style="color:#D4D4D4;">() {</span></span>
218<span class="line"><span style="color:#D4D4D4;">				logger.</span><span style="color:#DCDCAA;">Warnf</span><span style="color:#D4D4D4;">(</span><span style="color:#CE9178;">&quot;app exit now&quot;</span><span style="color:#D4D4D4;">)</span></span>
219<span class="line"><span style="color:#D4D4D4;">
219				os.</span><span style="color:#DCDCAA;">Exit</span><span style="color:#D4D4D4;">(</span><span style="color:#B5CEA8;">0</span><span style="color:#D4D4D4;">)</span></span>
220<span class="line"><span style="color:#D4D4D4;">			})</span></span>
221<span class="line"></span>
222<span class="line"><span style="color:#D4D4D4;">			</span><span style="color:#6A9955;">// The program exits normally or timeout forcibly exits.</span></span>
223<span class="line"><span style="color:#D4D4D4;">			fmt.</span><span style="color:#DCDCAA;">Println</span><span style="color:#D4D4D4;">(</span><span style="color:#CE9178;">&quot;provider app exit now&quot;</span><span style="color:#D4D4D4;">)</span></span>
224<span class="line"><span style="color:#D4D4D4;">			</span><span style="color:#C586C0;">return</span></span>
225<span class="line"><span style="color:#D4D4D4;">		}</span></span>
226<span class="line"><span style="color:#D4D4D4;">	}</span></span>
227<span class="line"><span style="color:#D4D4D4;">}</span></span>
228<span class="line"></span></code></pre><div class="line-numbers"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br><span class="line-number">20</span><br><span class="line-number">21</span><br><span class="line-number">22</span><br><span class="line-number">23</span><br><span class="line-number">24</span><br><span class="line-number">25</span><br><span class="line-number">26</span><br><span class="line-number">27</span><br><span class="line-number">28</span><br><span class="line-number">29</span><br><span class="line-number">30</span><br><span class="line-number">31</span><br><span class="line-number">32</span><br><span class="line-number">33</span><br><span class="line-number">34</span><br><span class="line-number">35</span><br><span class="line-number">36</span><br><span class="line-number">37</span><br><span class="line-number">38</span><br><span class="line-number">39</span><br><span class="line-number">40</span><br><span class="line-number">41</span><br><span class="line-number">42</span><br><span class="line-number">43</span><br><span class="line-number">44</span><br><span class="line-number">45</span><br><span class="line-number">46</span><br><span class="line-number">47</span><br><span class="line-number">48</span><br><span class="line-number">49</span><br><span class="line-number">50</span><br><span class="line-number">51</span><br><span class="line-number">52</span><br><span class="line-number">53</span><br><span class="line-number">54</span><br><span class="line-number">55</span><br><span class="line-number">56</span><br><span class="line-number">57</span><br><span class="line-number">58</span><br><span class="line-number">59</span><br><span class="line-number">60</span><br><span class="line-number">61</span><br><span class="line-number">62</span><br><span class="line-number">63</span><br><span class="line-number">64</span><br><span class="line-number">65</span><br></div></div><p>Looking at the ServiceBClientImpl interface definition and the Dubbo configuration file, we can understand how a Dubbo client calls a go-doudou service:</p><div class="language-go ext-go line-numbers-mode"><pre class="shiki" style="background-color:#1E1E1E;"><code><span class="line"><span style="color:#6A9955;">// dubbo/rpc/grpc/service-b/service.go</span></span>
229<span class="line"><span style="color:#569CD6;">type</span><span style="color:#D4D4D4;"> </span><span style="color:#4EC9B0;">ServiceBClientImpl</span><span style="color:#D4D4D4;"> </span><span style="color:#569CD6;">struct</span><span style="color:#D4D4D4;"> {</span></span>
230<span class="line"><span style="color:#D4D4D4;">	GetDeptById </span><span style="color:#569CD6;">func</span><span style="color:#D4D4D4;">(ctx context.Context, id </span><span style="color:#4EC9B0;">int32</span><span style="color:#D4D4D4;">) (*DeptDto, </span><span style="color:#4EC9B0;">error</span><span style="color:#D4D4D4;">) </span><span style="color:#CE9178;">\`dubbo:&quot;GetDeptByIdRpc&quot;\`</span></span>
231<span class="line"><span style="color:#D4D4D4;">}</span></span>
232<span class="line"></span>
233<span class="line"><span style="color:#569CD6;">func</span><span style="color:#D4D4D4;"> (u *ServiceBClientImpl) </span><span style="color:#DCDCAA;">Reference</span><span style="color:#D4D4D4;">() </span><span style="color:#4EC9B0;">string</span><span style="color:#D4D4D4;"> {</span></span>
234<span class="line"><span style="color:#D4D4D4;">	</span><span style="color:#C586C0;">return</span><span style="color:#D4D4D4;"> </span><span style="color:#CE9178;">&quot;ServiceBClientImpl&quot;</span></span>
235<span class="line"><span style="color:#D4D4D4;">}</span></span>
236<span class="line"></span></code></pre><div class="line-numbers"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br></div></div><div class="language-yaml ext-yml line-numbers-mode"><pre class="shiki" style="background-color:#1E1E1E;"><code><span class="line"><span style="color:#6A9955;"># dubbo/rpc/grpc/go-client/conf/dubbogo.yml</span></span>
237<span class="line"><span style="color:#569CD6;">dubbo</span><span style="color:#D4D4D4;">:</span></span>
238<span class="line"><span style="color:#D4D4D4;">  </span><span style="color:#569CD6;">registries</span><span style="color:#D4D4D4;">:</span></span>
239<span class="line"><span style="color:#D4D4D4;">    </span><span style="color:#569CD6;">demoZK</span><span style="color:#D4D4D4;">:</span></span>
240<span class="line"><span style="color:#D4D4D4;">      </span><span style="color:#569CD6;">protocol</span><span style="color:#D4D4D4;">: </span><span style="color:#CE9178;">zookeeper</span></span>
241<span class="line"><span style="color:#D4D4D4;">      </span><span style="color:#569CD6;">address</span><span style="color:#D4D4D4;">: </span><span style="color:#CE9178;">localhost:2181,localhost:2182,localhost:2183</span></span>
242<span class="line"><span style="color:#D4D4D4;">  </span><span style="color:#569CD6;">consumer</span><span style="color:#D4D4D4;">:</span></span>
243<span class="line"><span style="color:#D4D4D4;">    </span><span style="color:#569CD6;">references</span><span style="color:#D4D4D4;">:</span></span>
244<span class="line"><span style="color:#D4D4D4;">      </span><span style="color:#569CD6;">ServiceBClientImpl</span><span style="color:#D4D4D4;">:</span></span>
245<span class="line"><span style="color:#D4D4D4;">        </span><span style="color:#569CD6;">protocol</span><span style="color:#D4D4D4;">: </span><span style="color:#CE9178;">grpc</span></span>
246<span class="line"><span style="color:#D4D4D4;">        </span><span style="color:#569CD6;">interface</span><span style="color:#D4D4D4;">: </span><span style="color:#CE9178;">cloud.unionj.ServiceB_grpc</span></span>
247<span class="line"><span style="color:#D4D4D4;">        </span><span style="color:#569CD6;">group</span><span style="color:#D4D4D4;">: </span><span style="color:#CE9178;">group</span></span>
248<span class="line"><span style="color:#D4D4D4;">        </span><span style="color:#569CD6;">version</span><span style="color:#D4D4D4;">: </span><span style="color:#CE9178;">v2.2.2</span></span>
249<span class="line"><span style="color:#D4D4D4;">        </span><span style="color:#569CD6;">retries</span><span style="color:#D4D4D4;">: </span><span style="color:#B5CEA8;">3</span></span>
250<span class="line"><span style="color:#D4D4D4;">        </span><span style="color:#569CD6;">cluster</span><span style="color:#D4D4D4;">: </span><span style="color:#CE9178;">failover</span></span>
251<span class="line"></span></code></pre><div class="line-numbers"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br></div></div><p>From these configuration files, we can see that dubbo-go is configured to call the cloud.unionj.ServiceB_grpc service registered in ZooKeeper, with group name &quot;group&quot; and version &quot;v2.2.2&quot;. The reference field in the ServiceBClientImpl interface corresponds to the RPC service name, and the <code>dubbo:&quot;GetDeptByIdRpc&quot;</code>
251 annotation maps the local method name GetDeptById to the remote RPC method name GetDeptByIdRpc.</p><h2 id="summary" tabindex="-1"><a class="header-anchor" href="#summary" aria-hidden="true">#</a> Summary</h2><p>From the demo we&#39;ve analyzed, we can see:</p><ol><li>go-doudou can call dubbo-go services through gRPC.</li><li>dubbo-go can also call go-doudou services through gRPC.</li><li>The implementation is very simple, and the interoperability based on ZooKeeper is complete, using the gRPC protocol as a bridge.</li></ol><p>This case verifies that go-doudou, as a new-generation Go microservice framework, can seamlessly integrate with the traditional dubbo ecosystem, supporting hybrid deployments and gradual migrations.</p>`,62),v=n("For more detailed information, please refer to the example code repository: "),E={href:"https://github.com/unionj-cloud/go-doudou-tutorials/tree/master/dubbodemo",target:"_blank",rel:"noopener noreferrer"},f=n("go-doudou-tutorials/dubbodemo");function A(k,q){const a=l("ExternalLinkIcon");return p(),o(r,null,[D,s("p",null,[u,y,s("a",b,[d,e(a)]),m,s("a",g,[C,e(a)])]),h,s("p",null,[v,s("a",E,[f,e(a)])])],64)}var w=t(i,[["render",A]]);export{w as default};

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.