<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>RPC框架 on Apache Dubbo</title><link>https://deploy-preview-3199--dubbo.netlify.app/zh-cn/overview/mannual/golang-sdk/tutorial/rpc/</link><description>Recent content in RPC框架 on Apache Dubbo</description><generator>Hugo</generator><language>zh-cn</language><atom:link href="https://deploy-preview-3199--dubbo.netlify.app/zh-cn/overview/mannual/golang-sdk/tutorial/rpc/index.xml" rel="self" type="application/rss+xml"/><item><title>流式通信</title><link>https://deploy-preview-3199--dubbo.netlify.app/zh-cn/overview/mannual/golang-sdk/tutorial/rpc/streaming/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://deploy-preview-3199--dubbo.netlify.app/zh-cn/overview/mannual/golang-sdk/tutorial/rpc/streaming/</guid><description>&lt;p>Streaming 流式通信是 Dubbo3 新提供的一种 RPC 数据传输模式，适用于以下场景:&lt;/p>
&lt;ul>
&lt;li>接口需要发送大量数据，这些数据无法被放在一个 RPC 的请求或响应中，需要分批发送，但应用层如果按照传统的多次 RPC 方式无法解决顺序和性能的问题，如果需要保证有序，则只能串行发送&lt;/li>
&lt;li>流式场景，数据需要按照发送顺序处理, 数据本身是没有确定边界的&lt;/li>
&lt;li>推送类场景，多个消息在同一个调用的上下文中被发送和处理&lt;/li>
&lt;/ul>
&lt;p>Streaming 流式通信类型分为以下三种:&lt;/p>
&lt;ul>
&lt;li>SERVER_STREAM(服务端流)&lt;/li>
&lt;li>CLIENT_STREAM(客户端流)&lt;/li>
&lt;li>BIDIRECTIONAL_STREAM(双向流)&lt;/li>
&lt;/ul>
&lt;h2 id="1介绍">1.介绍&lt;/h2>
&lt;p>本文档演示如何在 Dubbo-go 中使用流式通信，可在此查看 &lt;a href="https://github.com/apache/dubbo-go-samples/tree/main/streaming" target="_blank">完整示例源码地址&lt;/a>。&lt;/p>
&lt;h2 id="2如何使用dubbo-go流式通信">2.如何使用Dubbo-go流式通信&lt;/h2>
&lt;p>在proto文件中需要流式通信的方法的参数前面添加stream，使用proto-gen-triple生成相应文件&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-protobuf" data-lang="protobuf">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">service&lt;/span> GreetService {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">rpc&lt;/span> Greet(GreetRequest) &lt;span style="color:#719e07">returns&lt;/span> (GreetResponse) {}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">rpc&lt;/span> GreetStream(stream GreetStreamRequest) &lt;span style="color:#719e07">returns&lt;/span> (stream GreetStreamResponse) {}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">rpc&lt;/span> GreetClientStream(stream GreetClientStreamRequest) &lt;span style="color:#719e07">returns&lt;/span> (GreetClientStreamResponse) {}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">rpc&lt;/span> GreetServerStream(GreetServerStreamRequest) &lt;span style="color:#719e07">returns&lt;/span> (stream GreetServerStreamResponse) {}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>编写服务端handler文件&lt;/p>
&lt;p>源文件路径: dubbo-go-sample/streaming/go-server/cmd/server.go&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-go" data-lang="go">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">type&lt;/span> GreetTripleServer &lt;span style="color:#268bd2">struct&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">func&lt;/span> (srv &lt;span style="color:#719e07">*&lt;/span>GreetTripleServer) &lt;span style="color:#268bd2">Greet&lt;/span>(ctx context.Context, req &lt;span style="color:#719e07">*&lt;/span>greet.GreetRequest) (&lt;span style="color:#719e07">*&lt;/span>greet.GreetResponse, &lt;span style="color:#dc322f">error&lt;/span>) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>	resp &lt;span style="color:#719e07">:=&lt;/span> &lt;span style="color:#719e07">&amp;amp;&lt;/span>greet.GreetResponse{Greeting: req.Name}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>	&lt;span style="color:#719e07">return&lt;/span> resp, &lt;span style="color:#cb4b16">nil&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">func&lt;/span> (srv &lt;span style="color:#719e07">*&lt;/span>GreetTripleServer) &lt;span style="color:#268bd2">GreetStream&lt;/span>(ctx context.Context, stream greet.GreetService_GreetStreamServer) &lt;span style="color:#dc322f">error&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>	&lt;span style="color:#719e07">for&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>		req, err &lt;span style="color:#719e07">:=&lt;/span> stream.&lt;span style="color:#268bd2">Recv&lt;/span>()
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>		&lt;span style="color:#719e07">if&lt;/span> err &lt;span style="color:#719e07">!=&lt;/span> &lt;span style="color:#cb4b16">nil&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>			&lt;span style="color:#719e07">if&lt;/span> triple.&lt;span style="color:#268bd2">IsEnded&lt;/span>(err) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>				&lt;span style="color:#719e07">break&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>			}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>			&lt;span style="color:#719e07">return&lt;/span> fmt.&lt;span style="color:#268bd2">Errorf&lt;/span>(&lt;span style="color:#2aa198">&amp;#34;triple BidiStream recv error: %s&amp;#34;&lt;/span>, err)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>		}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>		&lt;span style="color:#719e07">if&lt;/span> err &lt;span style="color:#719e07">:=&lt;/span> stream.&lt;span style="color:#268bd2">Send&lt;/span>(&lt;span style="color:#719e07">&amp;amp;&lt;/span>greet.GreetStreamResponse{Greeting: req.Name}); err &lt;span style="color:#719e07">!=&lt;/span> &lt;span style="color:#cb4b16">nil&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>			&lt;span style="color:#719e07">return&lt;/span> fmt.&lt;span style="color:#268bd2">Errorf&lt;/span>(&lt;span style="color:#2aa198">&amp;#34;triple BidiStream send error: %s&amp;#34;&lt;/span>, err)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>		}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>	}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>	&lt;span style="color:#719e07">return&lt;/span> &lt;span style="color:#cb4b16">nil&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">func&lt;/span> (srv &lt;span style="color:#719e07">*&lt;/span>GreetTripleServer) &lt;span style="color:#268bd2">GreetClientStream&lt;/span>(ctx context.Context, stream greet.GreetService_GreetClientStreamServer) (&lt;span style="color:#719e07">*&lt;/span>greet.GreetClientStreamResponse, &lt;span style="color:#dc322f">error&lt;/span>) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>	&lt;span style="color:#268bd2">var&lt;/span> reqs []&lt;span style="color:#dc322f">string&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>	&lt;span style="color:#719e07">for&lt;/span> stream.&lt;span style="color:#268bd2">Recv&lt;/span>() {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>		reqs = &lt;span style="color:#b58900">append&lt;/span>(reqs, stream.&lt;span style="color:#268bd2">Msg&lt;/span>().Name)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>	}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>	&lt;span style="color:#719e07">if&lt;/span> stream.&lt;span style="color:#268bd2">Err&lt;/span>() &lt;span style="color:#719e07">!=&lt;/span> &lt;span style="color:#cb4b16">nil&lt;/span> &lt;span style="color:#719e07">&amp;amp;&amp;amp;&lt;/span> !triple.&lt;span style="color:#268bd2">IsEnded&lt;/span>(stream.&lt;span style="color:#268bd2">Err&lt;/span>()) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>		&lt;span style="color:#719e07">return&lt;/span> &lt;span style="color:#cb4b16">nil&lt;/span>, fmt.&lt;span style="color:#268bd2">Errorf&lt;/span>(&lt;span style="color:#2aa198">&amp;#34;triple ClientStream recv err: %s&amp;#34;&lt;/span>, stream.&lt;span style="color:#268bd2">Err&lt;/span>())
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>	}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>	resp &lt;span style="color:#719e07">:=&lt;/span> &lt;span style="color:#719e07">&amp;amp;&lt;/span>greet.GreetClientStreamResponse{
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>		Greeting: strings.&lt;span style="color:#268bd2">Join&lt;/span>(reqs, &lt;span style="color:#2aa198">&amp;#34;,&amp;#34;&lt;/span>),
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>	}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>	&lt;span style="color:#719e07">return&lt;/span> resp, &lt;span style="color:#cb4b16">nil&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">func&lt;/span> (srv &lt;span style="color:#719e07">*&lt;/span>GreetTripleServer) &lt;span style="color:#268bd2">GreetServerStream&lt;/span>(ctx context.Context, req &lt;span style="color:#719e07">*&lt;/span>greet.GreetServerStreamRequest, stream greet.GreetService_GreetServerStreamServer) &lt;span style="color:#dc322f">error&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>	&lt;span style="color:#719e07">for&lt;/span> i &lt;span style="color:#719e07">:=&lt;/span> &lt;span style="color:#2aa198">0&lt;/span>; i &amp;lt; &lt;span style="color:#2aa198">5&lt;/span>; i&lt;span style="color:#719e07">++&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>		&lt;span style="color:#719e07">if&lt;/span> err &lt;span style="color:#719e07">:=&lt;/span> stream.&lt;span style="color:#268bd2">Send&lt;/span>(&lt;span style="color:#719e07">&amp;amp;&lt;/span>greet.GreetServerStreamResponse{Greeting: req.Name}); err &lt;span style="color:#719e07">!=&lt;/span> &lt;span style="color:#cb4b16">nil&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>			&lt;span style="color:#719e07">return&lt;/span> fmt.&lt;span style="color:#268bd2">Errorf&lt;/span>(&lt;span style="color:#2aa198">&amp;#34;triple ServerStream send err: %s&amp;#34;&lt;/span>, err)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>		}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>	}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>	&lt;span style="color:#719e07">return&lt;/span> &lt;span style="color:#cb4b16">nil&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>编写客户端client文件&lt;/p></description></item><item><title>超时时间</title><link>https://deploy-preview-3199--dubbo.netlify.app/zh-cn/overview/mannual/golang-sdk/tutorial/rpc/timeout/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://deploy-preview-3199--dubbo.netlify.app/zh-cn/overview/mannual/golang-sdk/tutorial/rpc/timeout/</guid><description>&lt;h2 id="1介绍">1.介绍&lt;/h2>
&lt;p>本示例演示如何在 Dubbo-go 客户端发起调用时设置请求超时时间。可在此查看 &lt;a href="https://github.com/apache/dubbo-go-samples/tree/main/timeout" target="_blank">完整示例源码地址&lt;/a>&lt;/p>
&lt;h2 id="2如何设置请求超时时间">2.如何设置请求超时时间&lt;/h2>
&lt;p>在创建客户端时，可以使用 &lt;code>client.WithRequestTimeout()&lt;/code> 方法设置全局超时时间（所有使用改 client 的服务代理共享）。&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-go" data-lang="go">&lt;span style="display:flex;">&lt;span> cli, err &lt;span style="color:#719e07">:=&lt;/span> client.&lt;span style="color:#268bd2">NewClient&lt;/span>(
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> client.&lt;span style="color:#268bd2">WithClientURL&lt;/span>(&lt;span style="color:#2aa198">&amp;#34;tri://127.0.0.1:20000&amp;#34;&lt;/span>),
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> client.&lt;span style="color:#268bd2">WithClientRequestTimeout&lt;/span>(&lt;span style="color:#2aa198">3&lt;/span> &lt;span style="color:#719e07">*&lt;/span> time.Second),
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> )
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>可以使用 &lt;code>client.WithRequestTimeout()&lt;/code> 创建服务粒度的超时时间（以下服务代理 &lt;code>svc&lt;/code> 发起的方法调用都使用这个时间）。&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-go" data-lang="go">&lt;span style="display:flex;">&lt;span> svc, err &lt;span style="color:#719e07">:=&lt;/span> greet.&lt;span style="color:#268bd2">NewGreetService&lt;/span>(cli, client.&lt;span style="color:#268bd2">WithRequestTimeout&lt;/span>(&lt;span style="color:#2aa198">5&lt;/span> &lt;span style="color:#719e07">*&lt;/span> time.Second))
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>也可以在调用发起时，使用 &lt;code>client.WithCallRequestTimeout()&lt;/code> 指定一个超时时间&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-go" data-lang="go">&lt;span style="display:flex;">&lt;span>resp, err &lt;span style="color:#719e07">:=&lt;/span> svc.&lt;span style="color:#268bd2">GreetTimeout&lt;/span>(context.&lt;span style="color:#268bd2">Background&lt;/span>(), &lt;span style="color:#719e07">&amp;amp;&lt;/span>greet.GreetRequest{Name: &lt;span style="color:#2aa198">&amp;#34;hello world&amp;#34;&lt;/span>}, client.&lt;span style="color:#268bd2">WithCallRequestTimeout&lt;/span>(&lt;span style="color:#2aa198">10&lt;/span> &lt;span style="color:#719e07">*&lt;/span> time.Second))
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>从上往下，以上三种方式的优先级逐步提高，&lt;code>client.WithCallRequestTimeout()&lt;/code> 指定的超时时间优先级最高。&lt;/p>
&lt;h2 id="3示例详解">3.示例详解&lt;/h2>
&lt;h3 id="31服务端介绍">3.1服务端介绍&lt;/h3>
&lt;h4 id="服务端proto文件">服务端proto文件&lt;/h4>
&lt;p>源文件路径：dubbo-go-sample/timeout/proto/greet.proto&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-protobuf" data-lang="protobuf">&lt;span style="display:flex;">&lt;span>syntax &lt;span style="color:#719e07">=&lt;/span> &lt;span style="color:#2aa198">&amp;#34;proto3&amp;#34;&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">package&lt;/span> greet;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">option&lt;/span> go_package &lt;span style="color:#719e07">=&lt;/span> &lt;span style="color:#2aa198">&amp;#34;github.com/apache/dubbo-go-samples/timeout/proto;greet&amp;#34;&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">message&lt;/span> &lt;span style="color:#268bd2">GreetRequest&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#dc322f">string&lt;/span> name &lt;span style="color:#719e07">=&lt;/span> &lt;span style="color:#2aa198">1&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">message&lt;/span> &lt;span style="color:#268bd2">GreetResponse&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#dc322f">string&lt;/span> greeting &lt;span style="color:#719e07">=&lt;/span> &lt;span style="color:#2aa198">1&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">service&lt;/span> GreetService {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">rpc&lt;/span> Greet(GreetRequest) &lt;span style="color:#719e07">returns&lt;/span> (GreetResponse) {}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">rpc&lt;/span> GreetTimeout(GreetRequest) &lt;span style="color:#719e07">returns&lt;/span> (GreetResponse) {}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h4 id="服务端handler文件">服务端handler文件&lt;/h4>
&lt;p>&lt;code>Greet&lt;/code>方法直接响应，&lt;code>GreetTimeout&lt;/code>方法等待五秒后响应（模拟超时）。&lt;/p></description></item><item><title>健康检查</title><link>https://deploy-preview-3199--dubbo.netlify.app/zh-cn/overview/mannual/golang-sdk/tutorial/rpc/healthcheck/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://deploy-preview-3199--dubbo.netlify.app/zh-cn/overview/mannual/golang-sdk/tutorial/rpc/healthcheck/</guid><description>&lt;h2 id="背景">背景&lt;/h2>
&lt;p>Dubbo-go 内置了基于 triple 协议的健康检查服务，帮助用户管理和监测服务健康状态，可在此查看 &lt;a href="https://github.com/apache/dubbo-go-samples/tree/main/healthcheck" target="_blank">完整示例源码&lt;/a>。&lt;/p>
&lt;h2 id="使用方法">使用方法&lt;/h2>
&lt;ul>
&lt;li>框架在通过 &lt;code>instance&lt;/code> 启动后会自动向框架中注册健康检查服务 &lt;code>grpc.health.v1.Health&lt;/code>，用于记录并对外暴露每个triple服务的健康状态。&lt;/li>
&lt;li>健康检查服务可以通过发起 http 请求检查框架中服务的状态，也可以通过客户端调用该健康检查服务，调用的接口为&lt;code>grpc.health.v1.Health&lt;/code>，方法为 &lt;code>check&lt;/code>。&lt;/li>
&lt;/ul>
&lt;h2 id="1通过客户端调用健康检查服务">1、通过客户端调用健康检查服务&lt;/h2>
&lt;p>启动 dubbo-go-samples/healthcheck/go-server 中的服务，通过下方客户端即可查看 &lt;code>greet.GreetService&lt;/code> 的状态。&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-go" data-lang="go">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">package&lt;/span> main
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">import&lt;/span> (
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>	&lt;span style="color:#2aa198">&amp;#34;context&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>	&lt;span style="color:#2aa198">&amp;#34;dubbo.apache.org/dubbo-go/v3/client&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>	_ &lt;span style="color:#2aa198">&amp;#34;dubbo.apache.org/dubbo-go/v3/imports&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>	health &lt;span style="color:#2aa198">&amp;#34;dubbo.apache.org/dubbo-go/v3/protocol/triple/health/triple_health&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>	&lt;span style="color:#2aa198">&amp;#34;github.com/dubbogo/gost/log/logger&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">func&lt;/span> &lt;span style="color:#268bd2">main&lt;/span>() {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>	cli, err &lt;span style="color:#719e07">:=&lt;/span> client.&lt;span style="color:#268bd2">NewClient&lt;/span>(
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>		client.&lt;span style="color:#268bd2">WithClientURL&lt;/span>(&lt;span style="color:#2aa198">&amp;#34;tri://127.0.0.1:20000&amp;#34;&lt;/span>),
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>	)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>	&lt;span style="color:#719e07">if&lt;/span> err &lt;span style="color:#719e07">!=&lt;/span> &lt;span style="color:#cb4b16">nil&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>		&lt;span style="color:#b58900">panic&lt;/span>(err)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>	}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>	svc, err &lt;span style="color:#719e07">:=&lt;/span> health.&lt;span style="color:#268bd2">NewHealth&lt;/span>(cli)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>	&lt;span style="color:#719e07">if&lt;/span> err &lt;span style="color:#719e07">!=&lt;/span> &lt;span style="color:#cb4b16">nil&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>		&lt;span style="color:#b58900">panic&lt;/span>(err)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>	}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>	check, err &lt;span style="color:#719e07">:=&lt;/span> svc.&lt;span style="color:#268bd2">Check&lt;/span>(context.&lt;span style="color:#268bd2">Background&lt;/span>(), &lt;span style="color:#719e07">&amp;amp;&lt;/span>health.HealthCheckRequest{Service: &lt;span style="color:#2aa198">&amp;#34;greet.GreetService&amp;#34;&lt;/span>})
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>	&lt;span style="color:#719e07">if&lt;/span> err &lt;span style="color:#719e07">!=&lt;/span> &lt;span style="color:#cb4b16">nil&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>		logger.&lt;span style="color:#268bd2">Error&lt;/span>(err)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>	} &lt;span style="color:#719e07">else&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>		logger.&lt;span style="color:#268bd2">Info&lt;/span>(&lt;span style="color:#2aa198">&amp;#34;greet.GreetService&amp;#39;s health&amp;#34;&lt;/span>, check.&lt;span style="color:#268bd2">String&lt;/span>())
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>	}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>	watch, err &lt;span style="color:#719e07">:=&lt;/span> svc.&lt;span style="color:#268bd2">Watch&lt;/span>(context.&lt;span style="color:#268bd2">Background&lt;/span>(), &lt;span style="color:#719e07">&amp;amp;&lt;/span>health.HealthCheckRequest{Service: &lt;span style="color:#2aa198">&amp;#34;greet.GreetService&amp;#34;&lt;/span>})
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>	&lt;span style="color:#719e07">if&lt;/span> err &lt;span style="color:#719e07">!=&lt;/span> &lt;span style="color:#cb4b16">nil&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>		logger.&lt;span style="color:#268bd2">Error&lt;/span>(err)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>	} &lt;span style="color:#719e07">else&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>		&lt;span style="color:#719e07">if&lt;/span> watch.&lt;span style="color:#268bd2">Recv&lt;/span>() {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>			logger.&lt;span style="color:#268bd2">Info&lt;/span>(&lt;span style="color:#2aa198">&amp;#34;greet.GreetService&amp;#39;s health&amp;#34;&lt;/span>, watch.&lt;span style="color:#268bd2">Msg&lt;/span>().&lt;span style="color:#268bd2">String&lt;/span>())
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>		}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>	}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>启动后会有以下输出&lt;/p></description></item><item><title>请求重试</title><link>https://deploy-preview-3199--dubbo.netlify.app/zh-cn/overview/mannual/golang-sdk/tutorial/rpc/retry/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://deploy-preview-3199--dubbo.netlify.app/zh-cn/overview/mannual/golang-sdk/tutorial/rpc/retry/</guid><description>&lt;p>当一次服务调用失败时，我们可以让框架选择自动重试几次，这样能提高用户侧看到的请求成功率。在 failover cluster 模式下 dubbo-go 支持自动重试。&lt;/p>
&lt;h2 id="1介绍">1.介绍&lt;/h2>
&lt;p>本示例演示如何在 client 端调用失败时配置重试功能，&lt;a href="https://github.com/apache/dubbo-go-samples/tree/main/retry" target="_blank">完整示例源码地址&lt;/a>&lt;/p>
&lt;h2 id="2如何使用重试功能">2.如何使用重试功能&lt;/h2>
&lt;p>在使用 &lt;code>client.NewClient()&lt;/code> 创建客户端时，可以使用 &lt;code>client.WithClientRetries()&lt;/code> 方法设置重试次数。&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-go" data-lang="go">&lt;span style="display:flex;">&lt;span>cli, err &lt;span style="color:#719e07">:=&lt;/span> client.&lt;span style="color:#268bd2">NewClient&lt;/span>(
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>	client.&lt;span style="color:#268bd2">WithClientURL&lt;/span>(&lt;span style="color:#2aa198">&amp;#34;tri://127.0.0.1:20000&amp;#34;&lt;/span>),
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>	client.&lt;span style="color:#268bd2">WithClientRetries&lt;/span>(&lt;span style="color:#2aa198">3&lt;/span>),
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>)
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>或者，可以使用 &lt;code>client.WithRequestTimeout()&lt;/code> 设置服务粒度的超时时间（以下配置对服务 &lt;code>svc&lt;/code> 起作用）。&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-go" data-lang="go">&lt;span style="display:flex;">&lt;span>svc, err &lt;span style="color:#719e07">:=&lt;/span> greet.&lt;span style="color:#268bd2">NewGreetService&lt;/span>(cli, client.&lt;span style="color:#268bd2">WithClientRetries&lt;/span>(&lt;span style="color:#2aa198">5&lt;/span>))
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>也可以在调用发起时，使用 &lt;code>client.WithCallRetries()&lt;/code> 指定重试次数&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-go" data-lang="go">&lt;span style="display:flex;">&lt;span>resp, err &lt;span style="color:#719e07">:=&lt;/span> svc.&lt;span style="color:#268bd2">Greet&lt;/span>(context.&lt;span style="color:#268bd2">Background&lt;/span>(), &lt;span style="color:#719e07">&amp;amp;&lt;/span>greet.GreetRequest{Name: &lt;span style="color:#2aa198">&amp;#34;hello world&amp;#34;&lt;/span>}, client.&lt;span style="color:#268bd2">WithCallRetries&lt;/span>(&lt;span style="color:#2aa198">6&lt;/span>))
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>从上往下，以上三种方式的优先级逐步提高，&lt;code>client.WithCallRetries()&lt;/code> 指定的重试次数优先级最高。&lt;/p>
&lt;h2 id="3示例解读">3.示例解读&lt;/h2>
&lt;h3 id="31服务端介绍">3.1服务端介绍&lt;/h3>
&lt;h4 id="服务端proto文件">服务端proto文件&lt;/h4>
&lt;p>源文件路径：dubbo-go-sample/retry/proto/greet.proto&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-protobuf" data-lang="protobuf">&lt;span style="display:flex;">&lt;span>syntax &lt;span style="color:#719e07">=&lt;/span> &lt;span style="color:#2aa198">&amp;#34;proto3&amp;#34;&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">package&lt;/span> greet;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">option&lt;/span> go_package &lt;span style="color:#719e07">=&lt;/span> &lt;span style="color:#2aa198">&amp;#34;github.com/apache/dubbo-go-samples/retry/proto;greet&amp;#34;&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">message&lt;/span> &lt;span style="color:#268bd2">GreetRequest&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#dc322f">string&lt;/span> name &lt;span style="color:#719e07">=&lt;/span> &lt;span style="color:#2aa198">1&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">message&lt;/span> &lt;span style="color:#268bd2">GreetResponse&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#dc322f">string&lt;/span> greeting &lt;span style="color:#719e07">=&lt;/span> &lt;span style="color:#2aa198">1&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">service&lt;/span> GreetService {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">rpc&lt;/span> Greet(GreetRequest) &lt;span style="color:#719e07">returns&lt;/span> (GreetResponse) {}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">rpc&lt;/span> GreetTimeout(GreetRequest) &lt;span style="color:#719e07">returns&lt;/span> (GreetResponse) {}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h4 id="服务端handler文件">服务端handler文件&lt;/h4>
&lt;p>&lt;code>Greet&lt;/code>方法直接响应，&lt;code>GreetRetry&lt;/code>方法用于模拟重试。&lt;/p></description></item><item><title>通信协议</title><link>https://deploy-preview-3199--dubbo.netlify.app/zh-cn/overview/mannual/golang-sdk/tutorial/rpc/protocol/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://deploy-preview-3199--dubbo.netlify.app/zh-cn/overview/mannual/golang-sdk/tutorial/rpc/protocol/</guid><description>&lt;p>Dubbo-go 框架内置提供了两款协议：triple、dubbo，除此之外，框架还提供了多种协议扩展接入方式。&lt;/p>
&lt;ul>
&lt;li>triple，基于 HTTP/1、HTTP/2 的高性能通信协议，100% 兼容 gRPC，支持 Unary、Streming 等通信模式；支持发布 REST 风格的 HTTP 服务。&lt;/li>
&lt;li>dubbo，基于 TCP 的高性能私有通信协议，缺点是通用性较差，更适合在 Dubbo SDK 间使用；&lt;/li>
&lt;li>任意协议扩展，通过扩展 protocol 可以之前任意 RPC 协议，官方生态库提供 JsonRPC、thrift 等支持。&lt;/li>
&lt;/ul>
&lt;p>本篇文档中，我们将介绍关于 triple 协议的使用方式、如何实现与已有 dubbo2 系统的互相调用、扩展更多协议支持等。更多原理性介绍请参考 &lt;a href="https://deploy-preview-3199--dubbo.netlify.app/zh-cn/overview/reference/protocols/triple-spec/">协议规范&lt;/a> 或者 &lt;a href="https://deploy-preview-3199--dubbo.netlify.app/zh-cn/overview/mannual/java-sdk/tasks/protocols/protocol/">dubbo java 中相关描述文档&lt;/a>。&lt;/p>
&lt;h2 id="triple-协议">triple 协议&lt;/h2>
&lt;p>triple 协议支持使用 protobuf 和 non-protobuf 两种开发模式，我们 &lt;strong>推荐使用 protobuf 模式开发服务&lt;/strong>。&lt;/p>
&lt;p>目前我们大部分示例都是使用这个模式开发，可查看 &lt;a href="https://deploy-preview-3199--dubbo.netlify.app/zh-cn/overview/mannual/golang-sdk/quickstart/rpc/">快速开始&lt;/a> 学习完整开发示例，以下是基本步骤：&lt;/p>
&lt;ol>
&lt;li>先使用 protobuf 定义服务&lt;/li>
&lt;/ol>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-protobuf" data-lang="protobuf">&lt;span style="display:flex;">&lt;span>syntax &lt;span style="color:#719e07">=&lt;/span> &lt;span style="color:#2aa198">&amp;#34;proto3&amp;#34;&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">package&lt;/span> greet;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">option&lt;/span> go_package &lt;span style="color:#719e07">=&lt;/span> &lt;span style="color:#2aa198">&amp;#34;github.com/apache/dubbo-go-samples/helloworld/proto;greet&amp;#34;&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">message&lt;/span> &lt;span style="color:#268bd2">GreetRequest&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#dc322f">string&lt;/span> name &lt;span style="color:#719e07">=&lt;/span> &lt;span style="color:#2aa198">1&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">message&lt;/span> &lt;span style="color:#268bd2">GreetResponse&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#dc322f">string&lt;/span> greeting &lt;span style="color:#719e07">=&lt;/span> &lt;span style="color:#2aa198">1&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">service&lt;/span> GreetService {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">rpc&lt;/span> Greet(GreetRequest) &lt;span style="color:#719e07">returns&lt;/span> (GreetResponse) {}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;ol start="2">
&lt;li>&lt;a href="https://deploy-preview-3199--dubbo.netlify.app/zh-cn/overview/mannual/golang-sdk/quickstart/rpc/#%E5%89%8D%E7%BD%AE%E6%9D%A1%E4%BB%B6">安装 protoc 插件&lt;/a>，编译生成代码：&lt;/li>
&lt;/ol>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-shell" data-lang="shell">&lt;span style="display:flex;">&lt;span>protoc --go_out&lt;span style="color:#719e07">=&lt;/span>. --go_opt&lt;span style="color:#719e07">=&lt;/span>&lt;span style="color:#268bd2">paths&lt;/span>&lt;span style="color:#719e07">=&lt;/span>source_relative &lt;span style="color:#cb4b16">\
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#cb4b16">&lt;/span> --go-triple_out&lt;span style="color:#719e07">=&lt;/span>. --go-triple_opt&lt;span style="color:#719e07">=&lt;/span>&lt;span style="color:#268bd2">paths&lt;/span>&lt;span style="color:#719e07">=&lt;/span>source_relative &lt;span style="color:#cb4b16">\
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#cb4b16">&lt;/span> proto/greet.proto
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;ol start="3">
&lt;li>server 端发布服务&lt;/li>
&lt;/ol>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-go" data-lang="go">&lt;span style="display:flex;">&lt;span>srv, err &lt;span style="color:#719e07">:=&lt;/span> server.&lt;span style="color:#268bd2">NewServer&lt;/span>(
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>	server.&lt;span style="color:#268bd2">WithServerProtocol&lt;/span>(
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>		protocol.&lt;span style="color:#268bd2">WithPort&lt;/span>(&lt;span style="color:#2aa198">20000&lt;/span>),
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>		protocol.&lt;span style="color:#268bd2">WithTriple&lt;/span>(),
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>	),
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>greet.&lt;span style="color:#268bd2">RegisterGreetServiceHandler&lt;/span>(srv, &lt;span style="color:#719e07">&amp;amp;&lt;/span>GreetTripleServer{})
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;ol start="4">
&lt;li>client 端调用服务&lt;/li>
&lt;/ol>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-go" data-lang="go">&lt;span style="display:flex;">&lt;span>cli, err &lt;span style="color:#719e07">:=&lt;/span> client.&lt;span style="color:#268bd2">NewClient&lt;/span>(
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>	client.&lt;span style="color:#268bd2">WithClientURL&lt;/span>(&lt;span style="color:#2aa198">&amp;#34;127.0.0.1:20000&amp;#34;&lt;/span>),
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>svc, err &lt;span style="color:#719e07">:=&lt;/span> greet.&lt;span style="color:#268bd2">NewGreetService&lt;/span>(cli)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>resp, err &lt;span style="color:#719e07">:=&lt;/span> svc.&lt;span style="color:#268bd2">Greet&lt;/span>(context.&lt;span style="color:#268bd2">Background&lt;/span>(), &lt;span style="color:#719e07">&amp;amp;&lt;/span>greet.GreetRequest{Name: &lt;span style="color:#2aa198">&amp;#34;hello world&amp;#34;&lt;/span>})
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="dubbo-java-体系互调">dubbo-java 体系互调&lt;/h2>
&lt;p>如果 java 和 go 都使用 triple+protobuf 模式，很明显他们是可以直接互调通信的。&lt;/p></description></item><item><title>异常类型返回值</title><link>https://deploy-preview-3199--dubbo.netlify.app/zh-cn/overview/mannual/golang-sdk/tutorial/rpc/error/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://deploy-preview-3199--dubbo.netlify.app/zh-cn/overview/mannual/golang-sdk/tutorial/rpc/error/</guid><description>&lt;h2 id="1介绍">1.介绍&lt;/h2>
&lt;p>本文档演示如何在 RPC 调用过程中处理 error 错误类型响应，可在此查看 &lt;a href="https://github.com/apache/dubbo-go-samples/tree/main/error" target="_blank">完整示例源码地址&lt;/a>。&lt;/p>
&lt;h2 id="2示例详解">2.示例详解&lt;/h2>
&lt;h3 id="21-服务端">2.1 服务端&lt;/h3>
&lt;h4 id="服务端proto文件">服务端proto文件&lt;/h4>
&lt;p>源文件路径：dubbo-go-sample/error/proto/greet.proto&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-protobuf" data-lang="protobuf">&lt;span style="display:flex;">&lt;span>syntax &lt;span style="color:#719e07">=&lt;/span> &lt;span style="color:#2aa198">&amp;#34;proto3&amp;#34;&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">package&lt;/span> greet;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">option&lt;/span> go_package &lt;span style="color:#719e07">=&lt;/span> &lt;span style="color:#2aa198">&amp;#34;github.com/apache/dubbo-go-samples/error/proto;greet&amp;#34;&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">message&lt;/span> &lt;span style="color:#268bd2">GreetRequest&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#dc322f">string&lt;/span> name &lt;span style="color:#719e07">=&lt;/span> &lt;span style="color:#2aa198">1&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">message&lt;/span> &lt;span style="color:#268bd2">GreetResponse&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#dc322f">string&lt;/span> greeting &lt;span style="color:#719e07">=&lt;/span> &lt;span style="color:#2aa198">1&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">service&lt;/span> GreetService {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">rpc&lt;/span> Greet(GreetRequest) &lt;span style="color:#719e07">returns&lt;/span> (GreetResponse) {}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h4 id="服务端handler文件">服务端handler文件&lt;/h4>
&lt;p>请注意，在本程序设计中，Greet方法只有接收到 &lt;code>name=&amp;quot;right name&amp;quot;&lt;/code> 时才会认为是正确请求，否则会返回错误。&lt;/p>
&lt;p>源文件路径：dubbo-go-sample/context/go-server/main.go&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-go" data-lang="go">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">package&lt;/span> main
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">import&lt;/span> (
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>	&lt;span style="color:#2aa198">&amp;#34;context&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>	&lt;span style="color:#2aa198">&amp;#34;fmt&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>	&lt;span style="color:#2aa198">&amp;#34;github.com/pkg/errors&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>	_ &lt;span style="color:#2aa198">&amp;#34;dubbo.apache.org/dubbo-go/v3/imports&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>	&lt;span style="color:#2aa198">&amp;#34;dubbo.apache.org/dubbo-go/v3/protocol&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>	&lt;span style="color:#2aa198">&amp;#34;dubbo.apache.org/dubbo-go/v3/server&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>	greet &lt;span style="color:#2aa198">&amp;#34;github.com/apache/dubbo-go-samples/helloworld/proto&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>	&lt;span style="color:#2aa198">&amp;#34;github.com/dubbogo/gost/log/logger&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">type&lt;/span> GreetTripleServer &lt;span style="color:#268bd2">struct&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">func&lt;/span> (srv &lt;span style="color:#719e07">*&lt;/span>GreetTripleServer) &lt;span style="color:#268bd2">Greet&lt;/span>(ctx context.Context, req &lt;span style="color:#719e07">*&lt;/span>greet.GreetRequest) (&lt;span style="color:#719e07">*&lt;/span>greet.GreetResponse, &lt;span style="color:#dc322f">error&lt;/span>) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>	name &lt;span style="color:#719e07">:=&lt;/span> req.Name
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>	&lt;span style="color:#719e07">if&lt;/span> name &lt;span style="color:#719e07">!=&lt;/span> &lt;span style="color:#2aa198">&amp;#34;right name&amp;#34;&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>		errInfo &lt;span style="color:#719e07">:=&lt;/span> fmt.&lt;span style="color:#268bd2">Sprintf&lt;/span>(&lt;span style="color:#2aa198">&amp;#34;name is not right: %s&amp;#34;&lt;/span>, name)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>		logger.&lt;span style="color:#268bd2">Error&lt;/span>(errInfo)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>		&lt;span style="color:#719e07">return&lt;/span> &lt;span style="color:#cb4b16">nil&lt;/span>, errors.&lt;span style="color:#268bd2">New&lt;/span>(errInfo)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>	}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>	resp &lt;span style="color:#719e07">:=&lt;/span> &lt;span style="color:#719e07">&amp;amp;&lt;/span>greet.GreetResponse{Greeting: req.Name}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>	&lt;span style="color:#719e07">return&lt;/span> resp, &lt;span style="color:#cb4b16">nil&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">func&lt;/span> &lt;span style="color:#268bd2">main&lt;/span>() {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>	srv, err &lt;span style="color:#719e07">:=&lt;/span> server.&lt;span style="color:#268bd2">NewServer&lt;/span>(
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>		server.&lt;span style="color:#268bd2">WithServerProtocol&lt;/span>(
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>			protocol.&lt;span style="color:#268bd2">WithPort&lt;/span>(&lt;span style="color:#2aa198">20000&lt;/span>),
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>			protocol.&lt;span style="color:#268bd2">WithTriple&lt;/span>(),
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>		),
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>	)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>	&lt;span style="color:#719e07">if&lt;/span> err &lt;span style="color:#719e07">!=&lt;/span> &lt;span style="color:#cb4b16">nil&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>		&lt;span style="color:#b58900">panic&lt;/span>(err)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>	}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>	&lt;span style="color:#719e07">if&lt;/span> err = greet.&lt;span style="color:#268bd2">RegisterGreetServiceHandler&lt;/span>(srv, &lt;span style="color:#719e07">&amp;amp;&lt;/span>GreetTripleServer{}); err &lt;span style="color:#719e07">!=&lt;/span> &lt;span style="color:#cb4b16">nil&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>		&lt;span style="color:#b58900">panic&lt;/span>(err)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>	}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>	&lt;span style="color:#719e07">if&lt;/span> err = srv.&lt;span style="color:#268bd2">Serve&lt;/span>(); err &lt;span style="color:#719e07">!=&lt;/span> &lt;span style="color:#cb4b16">nil&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>		logger.&lt;span style="color:#268bd2">Error&lt;/span>(err)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>	}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>从 rpc 方法签名中，我们可以看到 &lt;code>func (srv *GreetTripleServer) Greet(ctx context.Context, req *greet.GreetRequest) (*greet.GreetResponse, error)&lt;/code> 包含 error 返回值。&lt;/p></description></item><item><title>传递附加参数</title><link>https://deploy-preview-3199--dubbo.netlify.app/zh-cn/overview/mannual/golang-sdk/tutorial/rpc/attachments/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://deploy-preview-3199--dubbo.netlify.app/zh-cn/overview/mannual/golang-sdk/tutorial/rpc/attachments/</guid><description>&lt;p>&lt;strong>理解隐式参数传递的最直接方式 http header，它的工作方式与 http header 完全一致，在 GET 或 POST 请求体之外可以传递任意多个 header 参数&lt;/strong>。而对于 RPC 调用而言，context就是在方法签名的参数之外提供附加参数传递能力，在实现原理上，对于不同的协议，attachment 的实现方式略有不同：&lt;/p>
&lt;ul>
&lt;li>对于 triple 协议，attachment 会转换为标准的 http header 进行传输。&lt;/li>
&lt;li>对于 dubbo 协议，attachment 是编码在协议体的固定位置进行传输，具体请参见 dubbo 协议规范。、&lt;/li>
&lt;/ul>
&lt;p>&lt;img alt="/user-guide/images/context.png" src="https://deploy-preview-3199--dubbo.netlify.app/imgs/user/context.png">&lt;/p>


&lt;div class="alert alert-primary" role="alert">
&lt;h4 class="alert-heading">注意&lt;/h4>

 &lt;ul>
&lt;li>在使用 triple 协议时，由于 http header 的限制，仅支持小写的 ascii 字符&lt;/li>
&lt;li>path, group, version, dubbo, token, timeout 等一些 key 是保留字段，传递 attachment 时应避免使用，尽量通过业务前缀等确保 key 的唯一性。&lt;/li>
&lt;/ul>


&lt;/div>

&lt;h2 id="1介绍">1.介绍&lt;/h2>
&lt;p>本文档演示如何在 Dubbo-go 框架中使用 context 上下文传递和读取附加参数，来实现上下文信息传递，可在此查看 &lt;a href="https://github.com/apache/dubbo-go-samples/tree/main/context" target="_blank">完整示例源码地址&lt;/a>&lt;/p>
&lt;h2 id="2使用说明">2.使用说明&lt;/h2>
&lt;h3 id="21客户端使用说明">2.1客户端使用说明&lt;/h3>
&lt;p>在客户端中，使用下述方式传递字段, 示例中 key 为 &lt;code>constant.AttachmentKey&lt;/code> 即 &amp;ldquo;attachment&amp;rdquo;:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-go" data-lang="go">&lt;span style="display:flex;">&lt;span>	ctx &lt;span style="color:#719e07">:=&lt;/span> context.&lt;span style="color:#268bd2">Background&lt;/span>()
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>	ctx = context.&lt;span style="color:#268bd2">WithValue&lt;/span>(ctx, constant.AttachmentKey, &lt;span style="color:#268bd2">map&lt;/span>[&lt;span style="color:#dc322f">string&lt;/span>]&lt;span style="color:#268bd2">interface&lt;/span>{}{
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#2aa198">&amp;#34;key1&amp;#34;&lt;/span>: &lt;span style="color:#2aa198">&amp;#34;user defined value 1&amp;#34;&lt;/span>,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#2aa198">&amp;#34;key2&amp;#34;&lt;/span>: &lt;span style="color:#2aa198">&amp;#34;user defined value 2&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>	})
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="22服务端使用说明">2.2服务端使用说明&lt;/h3>
&lt;p>在服务端中，使用下述方式获取字段, value的类型为 map[string]interface{}：&lt;/p></description></item><item><title>启动时检查</title><link>https://deploy-preview-3199--dubbo.netlify.app/zh-cn/overview/mannual/golang-sdk/tutorial/rpc/start-check/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://deploy-preview-3199--dubbo.netlify.app/zh-cn/overview/mannual/golang-sdk/tutorial/rpc/start-check/</guid><description>&lt;p>Dubbo 框架缺省会在启动时检查依赖的服务是否可用（注册中心是否有可用地址），不可用时会抛出异常，阻止应用初始化完成，以便上线时，能及早发现问题，默认 check=&amp;ldquo;true&amp;rdquo;，并等待3s。&lt;/p>
&lt;p>可以通过 check=&amp;ldquo;false&amp;rdquo; 关闭检查，比如，测试时，有些服务不关心，或者出现了循环依赖，必须有一方先启动。&lt;/p>
&lt;p>关闭 check 后，请注意 provider数量比较多时， consumer 订阅 provider 生成服务地址可能会有一定延迟，如果 consumer 一启动就对外提供服务，可能会造成&amp;quot;冷启动&amp;quot;。所以在这个时候，请对服务进行预热。&lt;/p>
&lt;p>示例：&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-yaml" data-lang="yaml">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">dubbo&lt;/span>:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">consumer&lt;/span>:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">check &lt;/span>: &lt;span style="color:#cb4b16">false&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">reference&lt;/span>: 
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">myserivce&lt;/span>:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">check&lt;/span>: &lt;span style="color:#cb4b16">true&lt;/span> 
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>或者&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-go" data-lang="go">&lt;span style="display:flex;">&lt;span>cli, err &lt;span style="color:#719e07">:=&lt;/span> client.&lt;span style="color:#268bd2">NewClient&lt;/span>(
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>	client.&lt;span style="color:#268bd2">WithClientCheck&lt;/span>(&lt;span style="color:#cb4b16">false&lt;/span>),
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>)
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>或者&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-go" data-lang="go">&lt;span style="display:flex;">&lt;span>svc, err &lt;span style="color:#719e07">:=&lt;/span> health.&lt;span style="color:#268bd2">NewHealth&lt;/span>(cli)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>svc.&lt;span style="color:#268bd2">Check&lt;/span>(context.&lt;span style="color:#268bd2">Background&lt;/span>(), &lt;span style="color:#719e07">&amp;amp;&lt;/span>health.HealthCheckRequest{Service: &lt;span style="color:#2aa198">&amp;#34;greet.GreetService&amp;#34;&lt;/span>}, client.&lt;span style="color:#268bd2">WithCheck&lt;/span>(&lt;span style="color:#cb4b16">false&lt;/span>))
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div></description></item><item><title>filter拦截器</title><link>https://deploy-preview-3199--dubbo.netlify.app/zh-cn/overview/mannual/golang-sdk/tutorial/rpc/filter/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://deploy-preview-3199--dubbo.netlify.app/zh-cn/overview/mannual/golang-sdk/tutorial/rpc/filter/</guid><description>&lt;p>Filter 过滤器动态拦截请求（request）或响应（response）以转换或使用请求或响应中包含的信息。过滤器本身通常不会创建响应，而是提供可以“附加”到任何一次 RPC 请求的通用函数。Dubbo Filter 是可插拔的，我们可以在一次 RPC 请求中插入任意类型的、任意多个 Filter。&lt;/p>
&lt;p>Filter 工作原理如下图所示：&lt;/p>
&lt;img style="max-width:800px;height:auto;" src="https://deploy-preview-3199--dubbo.netlify.app/imgs/v3/tasks/framework/filter.png"/>
&lt;h2 id="使用方式">使用方式&lt;/h2>
&lt;h3 id="1-filter-拦截器概念">1. Filter 拦截器概念&lt;/h3>
&lt;p>Filter 定义如下：&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-go" data-lang="go">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75">// Filter interface defines the functions of a filter
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75">// Extension - Filter
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75">&lt;/span>&lt;span style="color:#268bd2">type&lt;/span> Filter &lt;span style="color:#268bd2">interface&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>	&lt;span style="color:#586e75">// Invoke is the core function of a filter, it determines the process of the filter
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75">&lt;/span>	&lt;span style="color:#268bd2">Invoke&lt;/span>(context.Context, protocol.Invoker, protocol.Invocation) protocol.Result
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>	&lt;span style="color:#586e75">// OnResponse updates the results from Invoke and then returns the modified results.
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75">&lt;/span>	&lt;span style="color:#268bd2">OnResponse&lt;/span>(context.Context, protocol.Result, protocol.Invoker, protocol.Invocation) protocol.Result
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Filter 可以加载在 Consumer 端或者 Provider端。当加载在 Consumer 端，其Invoke函数调用的下游为网络层，OnResponse 为请求结束从网络层获取到返回结果后被调用。当加载在 Provider 端，其 Invoke 函数调用的下游为用户代码，OnResponse 为用户代码执行结束后向下传递至网络层前被调用。&lt;/p></description></item></channel></rss>