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'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'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's client;</li><li>go-server: A gRPC service using the dubbo-go framework, used to demonstrate being called by go-doudou'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'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;">'3.1'</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&rootPath=&version=v2.2.2&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'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'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;">"context"</span></span> 53<span class="line"><span style="color:#D4D4D4;"> </span><span style="color:#CE9178;">"service-b/dto"</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'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;"> &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;">"Test Department"</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 "Test Department", 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'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;">"req: </span><span style="color:#9CDCFE;">%v</span><span style="color:#CE9178;">"</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;"> &pb.HelloReply{Message: </span><span style="color:#CE9178;">"this is message from reply"</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'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'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;">"context"</span></span> 82<span class="line"><span style="color:#D4D4D4;"> </span><span style="color:#CE9178;">"service-a/dto"</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'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'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's gRPC client</li><li>greeterClient: go-server'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;">"cloud.unionj.ServiceB_grpc"</span><span style="color:#D4D4D4;">,</span></span> 104<span class="line"><span style="color:#D4D4D4;"> Group: </span><span style="color:#CE9178;">"group"</span><span style="color:#D4D4D4;">,</span></span> 105<span class="line"><span style="color:#D4D4D4;"> Version: </span><span style="color:#CE9178;">"v2.2.2"</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'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;">"org.apache.dubbo.sample.GreeterProvider"</span><span style="color:#D4D4D4;">,</span></span> 115<span class="line"><span style="color:#D4D4D4;"> Group: </span><span style="color:#CE9178;">"group"</span><span style="color:#D4D4D4;">,</span></span> 116<span class="line"><span style="color:#D4D4D4;"> Version: </span><span style="color:#CE9178;">"v2.2.2"</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'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'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, &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;">"test"</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, &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'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;">'GET'</span><span style="color:#D4D4D4;"> \\</span></span> 151<span class="line"><span style="color:#D4D4D4;"> </span><span style="color:#CE9178;">'http://localhost:6060/v1/rpcdept?userId=1'</span><span style="color:#D4D4D4;"> \\</span></span> 152<span class="line"><span style="color:#D4D4D4;"> -H </span><span style="color:#CE9178;">'accept: application/json'</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;">"id"</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;">"name"</span><span style="color:#D4D4D4;">: </span><span style="color:#CE9178;">"test"</span><span style="color:#D4D4D4;">,</span></span> 156<span class="line"><span style="color:#D4D4D4;"> </span><span style="color:#9CDCFE;">"deptId"</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;">"deptName"</span><span style="color:#D4D4D4;">: </span><span style="color:#CE9178;">"Test Department"</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's test service-a'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;">'GET'</span><span style="color:#D4D4D4;"> \\</span></span> 160<span class="line"><span style="color:#D4D4D4;"> </span><span style="color:#CE9178;">'http://localhost:6060/v1/rpchello?name=yongchang'</span><span style="color:#D4D4D4;"> \\</span></span> 161<span class="line"><span style="color:#D4D4D4;"> -H </span><span style="color:#CE9178;">'accept: application/json'</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;">"this is message from reply"</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'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;">"context"</span></span> 165<span class="line"><span style="color:#D4D4D4;"> </span><span style="color:#CE9178;">"fmt"</span></span> 166<span class="line"><span style="color:#D4D4D4;"> </span><span style="color:#CE9178;">"os"</span></span> 167<span class="line"><span style="color:#D4D4D4;"> </span><span style="color:#CE9178;">"os/signal"</span></span> 168<span class="line"><span style="color:#D4D4D4;"> </span><span style="color:#CE9178;">"syscall"</span></span> 169<span class="line"><span style="color:#D4D4D4;"> </span><span style="color:#CE9178;">"time"</span></span> 170<span class="line"></span> 171<span class="line"><span style="color:#D4D4D4;"> </span><span style="color:#CE9178;">"dubbo.apache.org/dubbo-go/v3/common/constant"</span></span> 172<span class="line"><span style="color:#D4D4D4;"> </span><span style="color:#CE9178;">"dubbo.apache.org/dubbo-go/v3/common/logger"</span></span> 173<span class="line"><span style="color:#D4D4D4;"> </span><span style="color:#CE9178;">"dubbo.apache.org/dubbo-go/v3/config"</span></span> 174<span class="line"><span style="color:#D4D4D4;"> _ </span><span style="color:#CE9178;">"dubbo.apache.org/dubbo-go/v3/imports"</span></span> 175<span class="line"></span> 176<span class="line"><span style="color:#D4D4D4;"> _ </span><span style="color:#CE9178;">"github.com/dubbogo/gost/log/logrus"</span></span> 177<span class="line"></span> 178<span class="line"><span style="color:#D4D4D4;"> </span><span style="color:#CE9178;">"github.com/unionj-cloud/go-doudou-tutorials/dubbodemo/dubbo/rpc/grpc/service-b"</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;">(&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;">"start to test dubbo"</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;"> := &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 < </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;">"error: </span><span style="color:#9CDCFE;">%v</span><span style="color:#CE9178;">"</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;">"response result: </span><span style="color:#9CDCFE;">%v</span><span style="color:#D7BA7D;">\\n</span><span style="color:#CE9178;">"</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;"> := <-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;">"get signal </span><span style="color:#9CDCFE;">%s</span><span style="color:#CE9178;">"</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;">"app exit now"</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;">"provider app exit now"</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:"GetDeptByIdRpc"\`</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;">"ServiceBClientImpl"</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 "group" and version "v2.2.2". The reference field in the ServiceBClientImpl interface corresponds to the RPC service name, and the <code>dubbo:"GetDeptByIdRpc"</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'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.