| <rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Apache Dubbo – 高级特性</title><link>https://dubbo.apache.org/zh-cn/overview/mannual/golang-sdk/tutorial/governance/features/</link><description>Recent content in 高级特性 on Apache Dubbo</description><generator>Hugo -- gohugo.io</generator><language>zh-cn</language><atom:link href="https://dubbo.apache.org/zh-cn/overview/mannual/golang-sdk/tutorial/governance/features/index.xml" rel="self" type="application/rss+xml"/><item><title>Overview: 配置调用的超时</title><link>https://dubbo.apache.org/zh-cn/overview/mannual/golang-sdk/tutorial/governance/features/timeout/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://dubbo.apache.org/zh-cn/overview/mannual/golang-sdk/tutorial/governance/features/timeout/</guid><description> |
| <h2 id="1-准备工作">1. 准备工作</h2> |
| <ul> |
| <li>dubbo-go cli 工具和依赖工具已安装</li> |
| <li>创建一个新的 demo 应用</li> |
| </ul> |
| <h2 id="2-通过配置项修改-rpc-调用相关参数">2. 通过配置项修改 RPC 调用相关参数</h2> |
| <h3 id="21-修改调用的超时并验证">2.1 修改调用的超时,并验证</h3> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-yaml" data-lang="yaml"><span style="display:flex;"><span><span style="color:#268bd2">dubbo</span>: |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">consumer</span>: |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">request-timeout</span>: 15s <span style="color:#586e75"># 配置客户端超时</span> |
| </span></span></code></pre></div><p>Dubbo-go 应用默认 RPC 超时为 3s,请求超时后,客户端将会返回error 为 context deadline exceeded 的错误。在本任务中,您需要首先修改 demo 应用的 server 函数为较长耗时,然后查看客户端的超时报错;再通过配置客户端超时,使得耗时函数可以正常调用。</p> |
| <ol> |
| <li> |
| <p>go-server/cmd/server.go: 修改 demo 应用 server 的函数为耗时 10s 的函数</p> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-go" data-lang="go"><span style="display:flex;"><span><span style="color:#268bd2">func</span> (s <span style="color:#719e07">*</span>GreeterProvider) <span style="color:#268bd2">SayHello</span>(ctx context.Context, in <span style="color:#719e07">*</span>api.HelloRequest) (<span style="color:#719e07">*</span>api.User, <span style="color:#dc322f">error</span>) { |
| </span></span><span style="display:flex;"><span> logger.<span style="color:#268bd2">Infof</span>(<span style="color:#2aa198">&#34;Dubbo3 GreeterProvider get user name = %s\n&#34;</span>, in.Name) |
| </span></span><span style="display:flex;"><span> time.<span style="color:#268bd2">Sleep</span>(time.Second<span style="color:#719e07">*</span><span style="color:#2aa198">10</span>) <span style="color:#586e75">// sleep 10s |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"></span> <span style="color:#719e07">return</span> <span style="color:#719e07">&amp;</span>api.User{Name: <span style="color:#2aa198">&#34;Hello &#34;</span> <span style="color:#719e07">+</span> in.Name, Id: <span style="color:#2aa198">&#34;12345&#34;</span>, Age: <span style="color:#2aa198">21</span>}, <span style="color:#cb4b16">nil</span> |
| </span></span><span style="display:flex;"><span>} |
| </span></span></code></pre></div></li> |
| <li> |
| <p>客户端发起调用,观察错误日志</p> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-fallback" data-lang="fallback"><span style="display:flex;"><span>ERROR cmd/client.go:47 context deadline exceeded |
| </span></span></code></pre></div></li> |
| <li> |
| <p>go-client/conf/dubbogo.yaml: 客户端修改超时</p> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-yaml" data-lang="yaml"><span style="display:flex;"><span><span style="color:#268bd2">dubbo</span>: |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">consumer</span>: |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">request-timeout</span>: 15s <span style="color:#586e75"># 配置客户端超时</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">references</span>: |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">GreeterClientImpl</span>: |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">protocol</span>: tri |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">url</span>: <span style="color:#2aa198">&#34;tri://localhost:20000&#34;</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">interface</span>: <span style="color:#2aa198">&#34;&#34;</span> <span style="color:#586e75"># read from pb</span> |
| </span></span></code></pre></div></li> |
| <li> |
| <p>再次通过客户端发起调用,观察日志,正常返回:</p> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>client response result: name:<span style="color:#2aa198">&#34;Hello laurence&#34;</span> id:<span style="color:#2aa198">&#34;12345&#34;</span> age:21 |
| </span></span></code></pre></div></li> |
| </ol></description></item><item><title>Overview: 自定义服务调用中间件</title><link>https://dubbo.apache.org/zh-cn/overview/mannual/golang-sdk/tutorial/governance/features/aop/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://dubbo.apache.org/zh-cn/overview/mannual/golang-sdk/tutorial/governance/features/aop/</guid><description> |
| <p>参考samples <a href="https://github.com/apache/dubbo-go-samples/tree/master/filter">dubbo-go-samples/filter</a></p> |
| <h2 id="1-准备工作">1. 准备工作</h2> |
| <ul> |
| <li>dubbo-go cli 工具和依赖工具已安装</li> |
| <li>阅读<a href="https://dubbo.apache.org/zh-cn/overview/mannual/golang-sdk/preface/design/aop_and_extension/">【组件加载与可扩展性】</a></li> |
| <li>创建一个新的 demo 应用</li> |
| </ul> |
| <h2 id="2-配置指定-filter">2. 配置指定 Filter</h2> |
| <p>指定filter时可用&rsquo;,&lsquo;分隔</p> |
| <ul> |
| <li> |
| <p>Consumer 端</p> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-yaml" data-lang="yaml"><span style="display:flex;"><span><span style="color:#268bd2">dubbo</span>: |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">consumer</span>: |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">filter</span>: echo,token,tps,myCustomFilter <span style="color:#586e75"># 可指定自定义filter</span> |
| </span></span></code></pre></div></li> |
| <li> |
| <p>Provider 端</p> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-yaml" data-lang="yaml"><span style="display:flex;"><span><span style="color:#268bd2">dubbo</span>: |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">provider</span>: |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">services</span>: |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">GreeterProvider</span>: |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">filter</span>: myCustomFilter,echo,tps |
| </span></span></code></pre></div></li> |
| </ul> |
| <h2 id="3-自定义filter">3. 自定义Filter</h2> |
| <p>用户可在代码中自定义 Filter,注册到框架上,并在配置中选择使用。</p> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-go" data-lang="go"><span style="display:flex;"><span><span style="color:#268bd2">func</span> <span style="color:#268bd2">init</span>() { |
| </span></span><span style="display:flex;"><span> extension.<span style="color:#268bd2">SetFilter</span>(<span style="color:#2aa198">&#34;myCustomFilter&#34;</span>, NewMyClientFilter) |
| </span></span><span style="display:flex;"><span>} |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span><span style="color:#268bd2">func</span> <span style="color:#268bd2">NewMyClientFilter</span>() filter.Filter { |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">return</span> <span style="color:#719e07">&amp;</span>MyClientFilter{} |
| </span></span><span style="display:flex;"><span>} |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span><span style="color:#268bd2">type</span> MyClientFilter <span style="color:#268bd2">struct</span> { |
| </span></span><span style="display:flex;"><span>} |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span><span style="color:#268bd2">func</span> (f <span style="color:#719e07">*</span>MyClientFilter) <span style="color:#268bd2">Invoke</span>(ctx context.Context, invoker protocol.Invoker, invocation protocol.Invocation) protocol.Result { |
| </span></span><span style="display:flex;"><span> fmt.<span style="color:#268bd2">Println</span>(<span style="color:#2aa198">&#34;MyClientFilter Invoke is called, method Name = &#34;</span>, invocation.<span style="color:#268bd2">MethodName</span>()) |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">return</span> invoker.<span style="color:#268bd2">Invoke</span>(ctx, invocation) |
| </span></span><span style="display:flex;"><span>} |
| </span></span><span style="display:flex;"><span><span style="color:#268bd2">func</span> (f <span style="color:#719e07">*</span>MyClientFilter) <span style="color:#268bd2">OnResponse</span>(ctx context.Context, result protocol.Result, invoker protocol.Invoker, protocol protocol.Invocation) protocol.Result { |
| </span></span><span style="display:flex;"><span> fmt.<span style="color:#268bd2">Println</span>(<span style="color:#2aa198">&#34;MyClientFilter OnResponse is called&#34;</span>) |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">return</span> result |
| </span></span><span style="display:flex;"><span>} |
| </span></span></code></pre></div></description></item><item><title>Overview: 自定义Filter组件</title><link>https://dubbo.apache.org/zh-cn/overview/mannual/golang-sdk/tutorial/governance/features/custom-filter/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://dubbo.apache.org/zh-cn/overview/mannual/golang-sdk/tutorial/governance/features/custom-filter/</guid><description> |
| <p>参考samples <a href="https://github.com/apache/dubbo-go-samples/tree/master/filter">dubbo-go-samples/filter</a></p> |
| <h2 id="1-filter-概念">1. Filter 概念</h2> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-go" data-lang="go"><span style="display:flex;"><span><span style="color:#586e75">// Filter interface defines the functions of a filter |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75">// Extension - Filter |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"></span><span style="color:#268bd2">type</span> Filter <span style="color:#268bd2">interface</span> { |
| </span></span><span style="display:flex;"><span> <span style="color:#586e75">// Invoke is the core function of a filter, it determines the process of the filter |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"></span> <span style="color:#268bd2">Invoke</span>(context.Context, protocol.Invoker, protocol.Invocation) protocol.Result |
| </span></span><span style="display:flex;"><span> <span style="color:#586e75">// OnResponse updates the results from Invoke and then returns the modified results. |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"></span> <span style="color:#268bd2">OnResponse</span>(context.Context, protocol.Result, protocol.Invoker, protocol.Invocation) protocol.Result |
| </span></span><span style="display:flex;"><span>} |
| </span></span></code></pre></div><p>Filter 可以加载在 Consumer 端或者 Provider端。当加载在 Consumer 端,其Invoke函数调用的下游为网络层,OnResponse 为请求结束从网络层获取到返回结果后被调用。当加载在 Provider 端,其 Invoke 函数调用的下游为用户代码,OnResponse 为用户代码执行结束后向下传递至网络层前被调用。</p> |
| <p>Filter 采用面向切面设计的思路,通过对 Filter 的合理扩展,可以记录日志、设置数据打点,记录 invoker 所对应服务端性能,限流等等工作。</p> |
| <h2 id="2-框架预定义-filter">2. 框架预定义 Filter</h2> |
| <p>框架预定义了一系列filter,可以在配置中直接使用,其代码实现位于<a href="https://github.com/apache/dubbo-go/tree/release-3.0/filter">filter</a></p> |
| <ul> |
| <li>accesslog</li> |
| <li>active</li> |
| <li>sign: AuthConsumerFilter</li> |
| <li>auth: AuthProviderFilter</li> |
| <li>echo</li> |
| <li>execute: ExecuteLimitFilter</li> |
| <li>generic: GenericFilter</li> |
| <li>generic_service: GenericServiceFilter</li> |
| <li>pshutdown: GracefulShutdownProviderFilter</li> |
| <li>cshutdown: GracefulShutdownConsumerFilter</li> |
| <li>hystrix_consumer: HystrixConsumerFilter</li> |
| <li>hystrix_provider: HystrixProviderFilter</li> |
| <li>metrics</li> |
| <li>seata</li> |
| <li>sentinel-provider</li> |
| <li>sentinel-consumer</li> |
| <li>token</li> |
| <li>tps</li> |
| <li>tracing</li> |
| </ul> |
| <h2 id="3-默认加载filter">3. 默认加载Filter</h2> |
| <p>用户在配置文件中配置了将要使用的 Filters 时,框架使用用户配置的 Filters 和默认 Filters,否则仅加载默认 Filters:</p> |
| <ul> |
| <li>Consumer: cshutdown</li> |
| <li>Provider: echo, metrics, token, accesslog, tps, generic_service, executivete, pshutdown</li> |
| </ul> |
| <h2 id="4-用户指定-filter">4. 用户指定 Filter</h2> |
| <p>指定filter时可用&rsquo;,&lsquo;分隔</p> |
| <ul> |
| <li> |
| <p>Consumer 端</p> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-yaml" data-lang="yaml"><span style="display:flex;"><span><span style="color:#268bd2">dubbo</span>: |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">consumer</span>: |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">filter</span>: echo,token,tps,myCustomFilter <span style="color:#586e75"># 可指定自定义filter</span> |
| </span></span></code></pre></div></li> |
| <li> |
| <p>Provider 端</p> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-yaml" data-lang="yaml"><span style="display:flex;"><span><span style="color:#268bd2">dubbo</span>: |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">provider</span>: |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">services</span>: |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">GreeterProvider</span>: |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">filter</span>: myCustomFilter,echo,tps |
| </span></span></code></pre></div></li> |
| </ul> |
| <h2 id="5-自定义filter">5. 自定义Filter</h2> |
| <p>用户可在代码中自定义 Filter,注册到框架上,并在配置中选择使用。</p> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-go" data-lang="go"><span style="display:flex;"><span><span style="color:#268bd2">func</span> <span style="color:#268bd2">init</span>() { |
| </span></span><span style="display:flex;"><span> extension.<span style="color:#268bd2">SetFilter</span>(<span style="color:#2aa198">&#34;myCustomFilter&#34;</span>, NewMyClientFilter) |
| </span></span><span style="display:flex;"><span>} |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span><span style="color:#268bd2">func</span> <span style="color:#268bd2">NewMyClientFilter</span>() filter.Filter { |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">return</span> <span style="color:#719e07">&amp;</span>MyClientFilter{} |
| </span></span><span style="display:flex;"><span>} |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span><span style="color:#268bd2">type</span> MyClientFilter <span style="color:#268bd2">struct</span> { |
| </span></span><span style="display:flex;"><span>} |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span><span style="color:#268bd2">func</span> (f <span style="color:#719e07">*</span>MyClientFilter) <span style="color:#268bd2">Invoke</span>(ctx context.Context, invoker protocol.Invoker, invocation protocol.Invocation) protocol.Result { |
| </span></span><span style="display:flex;"><span> fmt.<span style="color:#268bd2">Println</span>(<span style="color:#2aa198">&#34;MyClientFilter Invoke is called, method Name = &#34;</span>, invocation.<span style="color:#268bd2">MethodName</span>()) |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">return</span> invoker.<span style="color:#268bd2">Invoke</span>(ctx, invocation) |
| </span></span><span style="display:flex;"><span>} |
| </span></span><span style="display:flex;"><span><span style="color:#268bd2">func</span> (f <span style="color:#719e07">*</span>MyClientFilter) <span style="color:#268bd2">OnResponse</span>(ctx context.Context, result protocol.Result, invoker protocol.Invoker, protocol protocol.Invocation) protocol.Result { |
| </span></span><span style="display:flex;"><span> fmt.<span style="color:#268bd2">Println</span>(<span style="color:#2aa198">&#34;MyClientFilter OnResponse is called&#34;</span>) |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">return</span> result |
| </span></span><span style="display:flex;"><span>} |
| </span></span></code></pre></div></description></item></channel></rss> |