| <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/tasks/extensibility/</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/tasks/extensibility/index.xml" rel="self" type="application/rss+xml"/><item><title>Overview: Filter</title><link>https://dubbo.apache.org/zh-cn/overview/tasks/extensibility/filter/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://dubbo.apache.org/zh-cn/overview/tasks/extensibility/filter/</guid><description> |
| <p>通过自定义过滤器,可以对返回的结果进行统一的处理、验证等,减少对开发人员的打扰。</p> |
| <h2 id="开始之前">开始之前</h2> |
| <p>有两种部署运行方式,二选一</p> |
| <h3 id="基于kubernetes">基于Kubernetes</h3> |
| <ul> |
| <li>安装<a href="https://kubernetes.io/docs/tasks/tools/">Kubernetes</a>环境</li> |
| <li>修改<a href="https://github.com/apache/dubbo-samples/blob/master/10-task/dubbo-samples-extensibility/dubbo-samples-extensibility-filter-provider/src/main/resources/application.properties">Provider</a>中的配置文件,启用Kubernetes中部署的nacos的地址 |
| <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-properties" data-lang="properties"><span style="display:flex;"><span><span style="color:#586e75"># Specify the application name of Dubbo</span> |
| </span></span><span style="display:flex;"><span>dubbo.application.name<span style="color:#719e07">=</span><span style="color:#2aa198">extensibility-filter-provider</span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span><span style="color:#586e75"># Enable token verification for each invocation</span> |
| </span></span><span style="display:flex;"><span>dubbo.provider.token<span style="color:#719e07">=</span><span style="color:#2aa198">true</span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span><span style="color:#586e75"># Specify the registry address</span> |
| </span></span><span style="display:flex;"><span><span style="color:#586e75"># dubbo.registry.address=nacos://localhost:8848?username=nacos&amp;password=nacos</span> |
| </span></span><span style="display:flex;"><span><span style="color:#586e75"># 启用Kubernetes中部署的nacos的地址</span> |
| </span></span><span style="display:flex;"><span>dubbo.registry.address<span style="color:#719e07">=</span><span style="color:#2aa198">nacos://${nacos.address:localhost}:8848?username=nacos&amp;password=nacos</span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span><span style="color:#586e75"># Specify the port of Dubbo protocol</span> |
| </span></span><span style="display:flex;"><span>dubbo.protocol.port<span style="color:#719e07">=</span><span style="color:#2aa198">20881</span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span><span style="color:#586e75"># Apply AppendedFilter</span> |
| </span></span><span style="display:flex;"><span>dubbo.provider.filter<span style="color:#719e07">=</span><span style="color:#2aa198">appended</span> |
| </span></span></code></pre></div></li> |
| <li>修改<a href="https://github.com/apache/dubbo-samples/blob/master/10-task/dubbo-samples-extensibility/dubbo-samples-extensibility-filter-consumer/src/main/resources/application.properties">Consumer</a>中的配置文件,启用Kubernetes中部署的nacos的地址 |
| <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-properties" data-lang="properties"><span style="display:flex;"><span><span style="color:#586e75"># Specify the application name of Dubbo</span> |
| </span></span><span style="display:flex;"><span>dubbo.application.name<span style="color:#719e07">=</span><span style="color:#2aa198">extensibility-filter-consumer</span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span><span style="color:#586e75"># Enable token verification for each invocation</span> |
| </span></span><span style="display:flex;"><span>dubbo.provider.token<span style="color:#719e07">=</span><span style="color:#2aa198">true</span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span><span style="color:#586e75"># Specify the registry address</span> |
| </span></span><span style="display:flex;"><span><span style="color:#586e75"># dubbo.registry.address=nacos://localhost:8848?username=nacos&amp;password=nacos</span> |
| </span></span><span style="display:flex;"><span><span style="color:#586e75"># 启用Kubernetes中部署的nacos的地址</span> |
| </span></span><span style="display:flex;"><span>dubbo.registry.address<span style="color:#719e07">=</span><span style="color:#2aa198">nacos://${nacos.address:localhost}:8848?username=nacos&amp;password=nacos</span> |
| </span></span></code></pre></div></li> |
| <li>部署<code>[Extensibility Filter Task](https://github.com/apache/dubbo-samples/blob/master/10-task/dubbo-samples-extensibility/deploy/All.yml)</code></li> |
| </ul> |
| <h3 id="使用本地ide">使用本地IDE</h3> |
| <ul> |
| <li>部署<a href="https://nacos.io/zh-cn/docs/quick-start.html">Nacos</a>2.2.0版本</li> |
| <li>修改<a href="https://github.com/apache/dubbo-samples/blob/master/10-task/dubbo-samples-extensibility/dubbo-samples-extensibility-filter-provider/src/main/resources/application.properties">Provider</a>中的配置文件,启用本地nacos的地址 |
| <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-properties" data-lang="properties"><span style="display:flex;"><span><span style="color:#586e75"># Specify the application name of Dubbo</span> |
| </span></span><span style="display:flex;"><span>dubbo.application.name<span style="color:#719e07">=</span><span style="color:#2aa198">extensibility-filter-provider</span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span><span style="color:#586e75"># Enable token verification for each invocation</span> |
| </span></span><span style="display:flex;"><span>dubbo.provider.token<span style="color:#719e07">=</span><span style="color:#2aa198">true</span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span><span style="color:#586e75"># Specify the registry address</span> |
| </span></span><span style="display:flex;"><span><span style="color:#586e75"># 启用本地nacos的地址</span> |
| </span></span><span style="display:flex;"><span>dubbo.registry.address<span style="color:#719e07">=</span><span style="color:#2aa198">nacos://localhost:8848?username=nacos&amp;password=nacos</span> |
| </span></span><span style="display:flex;"><span><span style="color:#586e75"># dubbo.registry.address=nacos://${nacos.address:localhost}:8848?username=nacos&amp;password=nacos</span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span><span style="color:#586e75"># Specify the port of Dubbo protocol</span> |
| </span></span><span style="display:flex;"><span>dubbo.protocol.port<span style="color:#719e07">=</span><span style="color:#2aa198">20881</span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span><span style="color:#586e75"># Apply AppendedFilter</span> |
| </span></span><span style="display:flex;"><span>dubbo.provider.filter<span style="color:#719e07">=</span><span style="color:#2aa198">appended</span> |
| </span></span></code></pre></div></li> |
| <li>修改<a href="https://github.com/apache/dubbo-samples/blob/master/10-task/dubbo-samples-extensibility/dubbo-samples-extensibility-filter-consumer/src/main/resources/application.properties">Consumer</a>中的配置文件,启用本地nacos的地址 |
| <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-properties" data-lang="properties"><span style="display:flex;"><span><span style="color:#586e75"># Specify the application name of Dubbo</span> |
| </span></span><span style="display:flex;"><span>dubbo.application.name<span style="color:#719e07">=</span><span style="color:#2aa198">extensibility-filter-consumer</span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span><span style="color:#586e75"># Enable token verification for each invocation</span> |
| </span></span><span style="display:flex;"><span>dubbo.provider.token<span style="color:#719e07">=</span><span style="color:#2aa198">true</span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span><span style="color:#586e75"># Specify the registry address</span> |
| </span></span><span style="display:flex;"><span><span style="color:#586e75"># 启用本地nacos的地址</span> |
| </span></span><span style="display:flex;"><span>dubbo.registry.address<span style="color:#719e07">=</span><span style="color:#2aa198">nacos://localhost:8848?username=nacos&amp;password=nacos</span> |
| </span></span><span style="display:flex;"><span><span style="color:#586e75"># dubbo.registry.address=nacos://${nacos.address:localhost}:8848?username=nacos&amp;password=nacos</span> |
| </span></span></code></pre></div></li> |
| </ul> |
| <h2 id="任务详情">任务详情</h2> |
| <p>对所有调用Provider服务的请求在返回的结果的后面统一添加<code>'s customized AppendedFilter</code>。</p> |
| <h2 id="实现方式">实现方式</h2> |
| <p>在Provider中自定义一个Filter,在Filter中修改返回结果。</p> |
| <h4 id="代码结构">代码结构</h4> |
| <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-properties" data-lang="properties"><span style="display:flex;"><span>src |
| </span></span><span style="display:flex;"><span> |-main |
| </span></span><span style="display:flex;"><span> |-java |
| </span></span><span style="display:flex;"><span> |-org |
| </span></span><span style="display:flex;"><span> |-apache |
| </span></span><span style="display:flex;"><span> |-dubbo |
| </span></span><span style="display:flex;"><span> |-samples |
| </span></span><span style="display:flex;"><span> |-extensibility |
| </span></span><span style="display:flex;"><span> |-filter |
| </span></span><span style="display:flex;"><span> |-provider |
| </span></span><span style="display:flex;"><span> |-AppendedFilter.java <span style="color:#2aa198">(实现Filter接口)</span> |
| </span></span><span style="display:flex;"><span> |-resources |
| </span></span><span style="display:flex;"><span> |-META-INF |
| </span></span><span style="display:flex;"><span> |-application.properties <span style="color:#2aa198">(Dubbo Provider配置文件)</span> |
| </span></span><span style="display:flex;"><span> |-dubbo |
| </span></span><span style="display:flex;"><span> |-org.apache.dubbo.rpc.Filter <span style="color:#2aa198">(纯文本文件)</span> |
| </span></span></code></pre></div><h4 id="代码详情">代码详情</h4> |
| <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-java" data-lang="java"><span style="display:flex;"><span><span style="color:#719e07">package</span> org.apache.dubbo.samples.extensibility.filter.provider; |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">import</span> org.apache.dubbo.rpc.Filter; |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">import</span> org.apache.dubbo.rpc.Result; |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">import</span> org.apache.dubbo.rpc.Invoker; |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">import</span> org.apache.dubbo.rpc.Invocation; |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">import</span> org.apache.dubbo.rpc.RpcException; |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">import</span> org.apache.dubbo.rpc.AsyncRpcResult; |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span><span style="color:#268bd2">public</span> <span style="color:#268bd2">class</span> <span style="color:#268bd2">AppendedFilter</span> <span style="color:#268bd2">implements</span> Filter { |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">@Override</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">public</span> Result <span style="color:#268bd2">invoke</span>(Invoker<span style="color:#719e07">&lt;?&gt;</span> invoker, Invocation invocation) <span style="color:#268bd2">throws</span> RpcException { |
| </span></span><span style="display:flex;"><span> Result result<span style="color:#719e07">=</span> invoker.invoke(invocation); |
| </span></span><span style="display:flex;"><span> <span style="color:#586e75">// Obtain the returned value</span> |
| </span></span><span style="display:flex;"><span> Result appResponse <span style="color:#719e07">=</span> ((AsyncRpcResult) result).getAppResponse(); |
| </span></span><span style="display:flex;"><span> <span style="color:#586e75">// Appended value</span> |
| </span></span><span style="display:flex;"><span> appResponse.setValue(appResponse.getValue()<span style="color:#719e07">+</span><span style="color:#2aa198">&#34;&#39;s customized AppendedFilter&#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><span style="display:flex;"><span>} |
| </span></span></code></pre></div><h4 id="spi配置">SPI配置</h4> |
| <p>在<code>resources/META-INF/dubbo/org.apache.dubbo.rpc.Filter</code>文件中添加如下配置:</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-properties" data-lang="properties"><span style="display:flex;"><span>appended<span style="color:#719e07">=</span><span style="color:#2aa198">org.apache.dubbo.samples.extensibility.filter.provider.AppendedFilter</span> |
| </span></span></code></pre></div><h4 id="配置文件">配置文件</h4> |
| <p>在<code>resources/application.properties</code>文件中添加如下配置:</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-properties" data-lang="properties"><span style="display:flex;"><span><span style="color:#586e75"># Apply AppendedFilter</span> |
| </span></span><span style="display:flex;"><span>dubbo.provider.filter<span style="color:#719e07">=</span><span style="color:#2aa198">appended</span> |
| </span></span></code></pre></div><h2 id="运行结果">运行结果</h2> |
| <p>以<strong>使用本地IDE</strong>的方式来运行任务,结果如下:</p> |
| <p><img src="https://dubbo.apache.org/imgs/v3/tasks/extensibility/dubbo-samples-extensibility-filter-output.jpg" alt="dubbo-samples-extensibility-filter-output.jpg"></p></description></item><item><title>Overview: Protocol</title><link>https://dubbo.apache.org/zh-cn/overview/tasks/extensibility/protocol/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://dubbo.apache.org/zh-cn/overview/tasks/extensibility/protocol/</guid><description> |
| <p>Dubbo 通过协议扩展实现了很多内置的功能,同时也支持很多常用的协议。所有的自定义协议在<code>org.apache.dubbo.rpc.Protocol</code>文件中可以看到,以Dubbo 3为例,具体如下:</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-properties" data-lang="properties"><span style="display:flex;"><span><span style="color:#586e75"># Dubbo通过协议扩展实现的内置功能</span> |
| </span></span><span style="display:flex;"><span>filter<span style="color:#719e07">=</span><span style="color:#2aa198">org.apache.dubbo.rpc.cluster.filter.ProtocolFilterWrapper</span> |
| </span></span><span style="display:flex;"><span>qos<span style="color:#719e07">=</span><span style="color:#2aa198">org.apache.dubbo.qos.protocol.QosProtocolWrapper</span> |
| </span></span><span style="display:flex;"><span>registry<span style="color:#719e07">=</span><span style="color:#2aa198">org.apache.dubbo.registry.integration.InterfaceCompatibleRegistryProtocol</span> |
| </span></span><span style="display:flex;"><span>service-discovery-registry<span style="color:#719e07">=</span><span style="color:#2aa198">org.apache.dubbo.registry.integration.RegistryProtocol</span> |
| </span></span><span style="display:flex;"><span>listener<span style="color:#719e07">=</span><span style="color:#2aa198">org.apache.dubbo.rpc.protocol.ProtocolListenerWrapper</span> |
| </span></span><span style="display:flex;"><span>mock<span style="color:#719e07">=</span><span style="color:#2aa198">org.apache.dubbo.rpc.support.MockProtocol</span> |
| </span></span><span style="display:flex;"><span>serializationwrapper<span style="color:#719e07">=</span><span style="color:#2aa198">org.apache.dubbo.rpc.protocol.ProtocolSerializationWrapper</span> |
| </span></span><span style="display:flex;"><span>securitywrapper<span style="color:#719e07">=</span><span style="color:#2aa198">org.apache.dubbo.rpc.protocol.ProtocolSecurityWrapper</span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span><span style="color:#586e75"># Dubbo对外支持的常用协议</span> |
| </span></span><span style="display:flex;"><span>dubbo<span style="color:#719e07">=</span><span style="color:#2aa198">org.apache.dubbo.rpc.protocol.dubbo.DubboProtocol</span> |
| </span></span><span style="display:flex;"><span>injvm<span style="color:#719e07">=</span><span style="color:#2aa198">org.apache.dubbo.rpc.protocol.injvm.InjvmProtocol</span> |
| </span></span><span style="display:flex;"><span>rest<span style="color:#719e07">=</span><span style="color:#2aa198">org.apache.dubbo.rpc.protocol.rest.RestProtocol</span> |
| </span></span><span style="display:flex;"><span>grpc<span style="color:#719e07">=</span><span style="color:#2aa198">org.apache.dubbo.rpc.protocol.grpc.GrpcProtocol</span> |
| </span></span><span style="display:flex;"><span>tri<span style="color:#719e07">=</span><span style="color:#2aa198">org.apache.dubbo.rpc.protocol.tri.TripleProtocol</span> |
| </span></span></code></pre></div><p>我们可以看到,在Dubbo中通过协议扩展的能力实现了过滤、监控数据采集、服务发现、监听器、mock、序列化、安全等一系列能力,同时对外提供了<code>dubbo</code>,<code>injvm</code>,<code>rest</code>,<code>grpc</code>和<code>tri</code>协议。</p> |
| <p>自定义一套私有协议有两种方式,第一种是对原有的协议进行包装,添加一些特定的业务逻辑。另外一种是完全自定义一套协议。前者实现简单,在<code>dubbo</code>中也是有广泛的使用,比如:<code>ProtocolFilterWrapper</code>, <code>QosProtocolWrapper</code>, <code>ProtocolListenerWrapper</code>等。后者实现复杂,一般常见的协议<code>dubbo</code>都实现了,并且通过了大量生产实践的验证。</p> |
| <p>本文会通过示例演示如何通过现有协议实现一套自定义协议。</p> |
| <h2 id="开始之前">开始之前</h2> |
| <p>有两种部署运行方式,二选一</p> |
| <h3 id="基于kubernetes">基于Kubernetes</h3> |
| <ul> |
| <li>安装<a href="https://kubernetes.io/docs/tasks/tools/">Kubernetes</a>环境</li> |
| <li>修改<a href="https://github.com/apache/dubbo-samples/blob/master/10-task/dubbo-samples-extensibility/dubbo-samples-extensibility-protocol-provider/src/main/resources/application.properties">Provider</a>中的配置文件,启用Kubernetes中部署的nacos的地址 |
| <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-properties" data-lang="properties"><span style="display:flex;"><span><span style="color:#586e75"># Specify the application name of Dubbo</span> |
| </span></span><span style="display:flex;"><span>dubbo.application.name<span style="color:#719e07">=</span><span style="color:#2aa198">extensibility-protocol-provider</span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span><span style="color:#586e75"># Enable token verification for each invocation</span> |
| </span></span><span style="display:flex;"><span>dubbo.provider.token<span style="color:#719e07">=</span><span style="color:#2aa198">true</span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span><span style="color:#586e75"># Specify the registry address</span> |
| </span></span><span style="display:flex;"><span><span style="color:#586e75"># dubbo.registry.address=nacos://localhost:8848?username=nacos&amp;password=nacos</span> |
| </span></span><span style="display:flex;"><span>dubbo.registry.address<span style="color:#719e07">=</span><span style="color:#2aa198">nacos://${nacos.address:localhost}:8848?username=nacos&amp;password=nacos</span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span><span style="color:#586e75"># 自定义协议edubbo</span> |
| </span></span><span style="display:flex;"><span>dubbo.provider.protocol<span style="color:#719e07">=</span><span style="color:#2aa198">edubbo</span> |
| </span></span></code></pre></div></li> |
| <li>修改<a href="https://github.com/apache/dubbo-samples/blob/master/10-task/dubbo-samples-extensibility/dubbo-samples-extensibility-protocol-consumer/src/main/resources/application.properties">Consumer</a>中的配置文件,启用Kubernetes中部署的nacos的地址 |
| <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-properties" data-lang="properties"><span style="display:flex;"><span><span style="color:#586e75"># Specify the application name of Dubbo</span> |
| </span></span><span style="display:flex;"><span>dubbo.application.name<span style="color:#719e07">=</span><span style="color:#2aa198">extensibility-protocol-consumer</span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span><span style="color:#586e75"># Enable token verification for each invocation</span> |
| </span></span><span style="display:flex;"><span>dubbo.provider.token<span style="color:#719e07">=</span><span style="color:#2aa198">true</span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span><span style="color:#586e75"># Specify the registry address</span> |
| </span></span><span style="display:flex;"><span><span style="color:#586e75"># dubbo.registry.address=nacos://localhost:8848?username=nacos&amp;password=nacos</span> |
| </span></span><span style="display:flex;"><span>dubbo.registry.address<span style="color:#719e07">=</span><span style="color:#2aa198">nacos://${nacos.address:localhost}:8848?username=nacos&amp;password=nacos</span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span><span style="color:#586e75"># 自定义协议edubbo</span> |
| </span></span><span style="display:flex;"><span>dubbo.consumer.protocol<span style="color:#719e07">=</span><span style="color:#2aa198">edubbo</span> |
| </span></span></code></pre></div></li> |
| <li>部署<code>[Extensibility Protocol Task](https://github.com/apache/dubbo-samples/blob/master/10-task/dubbo-samples-extensibility/deploy/All.yml)</code></li> |
| </ul> |
| <h3 id="使用本地ide">使用本地IDE</h3> |
| <ul> |
| <li>部署<a href="https://nacos.io/zh-cn/docs/quick-start.html">Nacos</a>2.2.0版本</li> |
| <li>修改<a href="https://github.com/apache/dubbo-samples/blob/master/10-task/dubbo-samples-extensibility/dubbo-samples-extensibility-protocol-provider/src/main/resources/application.properties">Provider</a>中的配置文件,启用本地nacos的地址 |
| <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-properties" data-lang="properties"><span style="display:flex;"><span><span style="color:#586e75"># Specify the application name of Dubbo</span> |
| </span></span><span style="display:flex;"><span>dubbo.application.name<span style="color:#719e07">=</span><span style="color:#2aa198">extensibility-protocol-provider</span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span><span style="color:#586e75"># Enable token verification for each invocation</span> |
| </span></span><span style="display:flex;"><span>dubbo.provider.token<span style="color:#719e07">=</span><span style="color:#2aa198">true</span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span><span style="color:#586e75"># Specify the registry address</span> |
| </span></span><span style="display:flex;"><span><span style="color:#586e75"># 启用本地nacos的地址</span> |
| </span></span><span style="display:flex;"><span>dubbo.registry.address<span style="color:#719e07">=</span><span style="color:#2aa198">nacos://localhost:8848?username=nacos&amp;password=nacos</span> |
| </span></span><span style="display:flex;"><span><span style="color:#586e75"># dubbo.registry.address=nacos://${nacos.address:localhost}:8848?username=nacos&amp;password=nacos</span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span><span style="color:#586e75"># 自定义协议edubbo</span> |
| </span></span><span style="display:flex;"><span>dubbo.provider.protocol<span style="color:#719e07">=</span><span style="color:#2aa198">edubbo</span> |
| </span></span></code></pre></div></li> |
| <li>修改<a href="https://github.com/apache/dubbo-samples/blob/master/10-task/dubbo-samples-extensibility/dubbo-samples-extensibility-protocol-consumer/src/main/resources/application.properties">Consumer</a>中的配置文件,启用本地nacos的地址 |
| <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-properties" data-lang="properties"><span style="display:flex;"><span><span style="color:#586e75"># Specify the application name of Dubbo</span> |
| </span></span><span style="display:flex;"><span>dubbo.application.name<span style="color:#719e07">=</span><span style="color:#2aa198">extensibility-protocol-consumer</span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span><span style="color:#586e75"># Enable token verification for each invocation</span> |
| </span></span><span style="display:flex;"><span>dubbo.provider.token<span style="color:#719e07">=</span><span style="color:#2aa198">true</span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span><span style="color:#586e75"># Specify the registry address</span> |
| </span></span><span style="display:flex;"><span><span style="color:#586e75"># 启用本地nacos的地址</span> |
| </span></span><span style="display:flex;"><span>dubbo.registry.address<span style="color:#719e07">=</span><span style="color:#2aa198">nacos://localhost:8848?username=nacos&amp;password=nacos</span> |
| </span></span><span style="display:flex;"><span><span style="color:#586e75"># dubbo.registry.address=nacos://${nacos.address:localhost}:8848?username=nacos&amp;password=nacos</span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span><span style="color:#586e75"># 自定义协议edubbo</span> |
| </span></span><span style="display:flex;"><span>dubbo.consumer.protocol<span style="color:#719e07">=</span><span style="color:#2aa198">edubbo</span> |
| </span></span></code></pre></div></li> |
| </ul> |
| <h2 id="任务详情">任务详情</h2> |
| <p>基于现有的<code>dubbo</code>协议来实现自定义协议<code>edubbo</code>。</p> |
| <h2 id="实现方式">实现方式</h2> |
| <p>通过对<code>dubbo</code>协议进行包装来实现<code>edubbo</code>协议。</p> |
| <h4 id="代码结构">代码结构</h4> |
| <h5 id="common">Common</h5> |
| <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-properties" data-lang="properties"><span style="display:flex;"><span>src |
| </span></span><span style="display:flex;"><span> |-main |
| </span></span><span style="display:flex;"><span> |-java |
| </span></span><span style="display:flex;"><span> |-org |
| </span></span><span style="display:flex;"><span> |-apache |
| </span></span><span style="display:flex;"><span> |-dubbo |
| </span></span><span style="display:flex;"><span> |-samples |
| </span></span><span style="display:flex;"><span> |-extensibility |
| </span></span><span style="display:flex;"><span> |-protocol |
| </span></span><span style="display:flex;"><span> |-common |
| </span></span><span style="display:flex;"><span> |-EnhancedProtocol.java <span style="color:#2aa198">(实现Protocol接口)</span> |
| </span></span></code></pre></div><h5 id="provider">Provider</h5> |
| <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-properties" data-lang="properties"><span style="display:flex;"><span>src |
| </span></span><span style="display:flex;"><span> |-main |
| </span></span><span style="display:flex;"><span> |-java |
| </span></span><span style="display:flex;"><span> |-org |
| </span></span><span style="display:flex;"><span> |-apache |
| </span></span><span style="display:flex;"><span> |-dubbo |
| </span></span><span style="display:flex;"><span> |-samples |
| </span></span><span style="display:flex;"><span> |-extensibility |
| </span></span><span style="display:flex;"><span> |-protocol |
| </span></span><span style="display:flex;"><span> |-provider |
| </span></span><span style="display:flex;"><span> |-ExtensibilityProtocolProviderApplication.java |
| </span></span><span style="display:flex;"><span> |-ExtensibilityProtocolServiceImpl.java |
| </span></span><span style="display:flex;"><span> |-resources |
| </span></span><span style="display:flex;"><span> |-META-INF |
| </span></span><span style="display:flex;"><span> |-application.properties <span style="color:#2aa198">(Dubbo Provider配置文件)</span> |
| </span></span><span style="display:flex;"><span> |-dubbo |
| </span></span><span style="display:flex;"><span> |-org.apache.dubbo.rpc.Protocol <span style="color:#2aa198">(纯文本文件)</span> |
| </span></span></code></pre></div><h5 id="consumer">Consumer</h5> |
| <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-properties" data-lang="properties"><span style="display:flex;"><span>src |
| </span></span><span style="display:flex;"><span> |-main |
| </span></span><span style="display:flex;"><span> |-java |
| </span></span><span style="display:flex;"><span> |-org |
| </span></span><span style="display:flex;"><span> |-apache |
| </span></span><span style="display:flex;"><span> |-dubbo |
| </span></span><span style="display:flex;"><span> |-samples |
| </span></span><span style="display:flex;"><span> |-extensibility |
| </span></span><span style="display:flex;"><span> |-protocol |
| </span></span><span style="display:flex;"><span> |-consumer |
| </span></span><span style="display:flex;"><span> |-ExtensibilityProtocolConsumerApplication.java |
| </span></span><span style="display:flex;"><span> |-ExtensibilityProtocolConsumerTask.java |
| </span></span><span style="display:flex;"><span> |-resources |
| </span></span><span style="display:flex;"><span> |-META-INF |
| </span></span><span style="display:flex;"><span> |-application.properties <span style="color:#2aa198">(Dubbo Consumer配置文件)</span> |
| </span></span><span style="display:flex;"><span> |-dubbo |
| </span></span><span style="display:flex;"><span> |-org.apache.dubbo.rpc.Protocol <span style="color:#2aa198">(纯文本文件)</span> |
| </span></span></code></pre></div><h4 id="代码详情">代码详情</h4> |
| <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-java" data-lang="java"><span style="display:flex;"><span><span style="color:#719e07">package</span> org.apache.dubbo.samples.extensibility.protocol.common; |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">import</span> org.apache.dubbo.common.URL; |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">import</span> org.apache.dubbo.rpc.Protocol; |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">import</span> org.apache.dubbo.rpc.Invoker; |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">import</span> org.apache.dubbo.rpc.Exporter; |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">import</span> org.apache.dubbo.rpc.ProtocolServer; |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">import</span> org.apache.dubbo.rpc.RpcException; |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">import</span> org.apache.dubbo.rpc.model.FrameworkModel; |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">import</span> org.apache.dubbo.rpc.protocol.dubbo.DubboProtocol; |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">import</span> java.util.List; |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span><span style="color:#268bd2">public</span> <span style="color:#268bd2">class</span> <span style="color:#268bd2">EnhancedProtocol</span> <span style="color:#268bd2">implements</span> Protocol { |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">public</span> <span style="color:#268bd2">EnhancedProtocol</span>(FrameworkModel frameworkModel) { |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">this</span>.protocol <span style="color:#719e07">=</span> <span style="color:#719e07">new</span> DubboProtocol(frameworkModel); |
| </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">private</span> <span style="color:#268bd2">final</span> Protocol protocol; |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">@Override</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">public</span> <span style="color:#dc322f">int</span> <span style="color:#268bd2">getDefaultPort</span>() { |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">return</span> <span style="color:#719e07">this</span>.protocol.getDefaultPort(); |
| </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">@Override</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">public</span> <span style="color:#719e07">&lt;</span>T<span style="color:#719e07">&gt;</span> Exporter<span style="color:#719e07">&lt;</span>T<span style="color:#719e07">&gt;</span> <span style="color:#268bd2">export</span>(Invoker<span style="color:#719e07">&lt;</span>T<span style="color:#719e07">&gt;</span> invoker) <span style="color:#268bd2">throws</span> RpcException { |
| </span></span><span style="display:flex;"><span> <span style="color:#586e75">// do something</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">return</span> <span style="color:#719e07">this</span>.protocol.export(invoker); |
| </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">@Override</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">public</span> <span style="color:#719e07">&lt;</span>T<span style="color:#719e07">&gt;</span> Invoker<span style="color:#719e07">&lt;</span>T<span style="color:#719e07">&gt;</span> <span style="color:#268bd2">refer</span>(Class<span style="color:#719e07">&lt;</span>T<span style="color:#719e07">&gt;</span> type, URL url) <span style="color:#268bd2">throws</span> RpcException { |
| </span></span><span style="display:flex;"><span> <span style="color:#586e75">// do something</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">return</span> <span style="color:#719e07">this</span>.protocol.refer(type, url); |
| </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">@Override</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">public</span> <span style="color:#dc322f">void</span> <span style="color:#268bd2">destroy</span>() { |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">this</span>.protocol.destroy(); |
| </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">@Override</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">public</span> List<span style="color:#719e07">&lt;</span>ProtocolServer<span style="color:#719e07">&gt;</span> <span style="color:#268bd2">getServers</span>() { |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">return</span> protocol.getServers(); |
| </span></span><span style="display:flex;"><span> } |
| </span></span><span style="display:flex;"><span>} |
| </span></span></code></pre></div><h4 id="spi配置">SPI配置</h4> |
| <h5 id="provider-1">Provider</h5> |
| <p>在<code>resources/META-INF/dubbo/org.apache.dubbo.rpc.Protocol</code>文件中添加如下配置:</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-properties" data-lang="properties"><span style="display:flex;"><span>edubbo<span style="color:#719e07">=</span><span style="color:#2aa198">org.apache.dubbo.samples.extensibility.protocol.common.EnhancedProtocol</span> |
| </span></span></code></pre></div><h5 id="consumer-1">Consumer</h5> |
| <p>在<code>resources/META-INF/dubbo/org.apache.dubbo.rpc.Protocol</code>文件中添加如下配置:</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-properties" data-lang="properties"><span style="display:flex;"><span>edubbo<span style="color:#719e07">=</span><span style="color:#2aa198">org.apache.dubbo.samples.extensibility.protocol.common.EnhancedProtocol</span> |
| </span></span></code></pre></div><h4 id="配置文件">配置文件</h4> |
| <h5 id="provider-2">Provider</h5> |
| <p>在<code>resources/application.properties</code>文件中添加如下配置:</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-properties" data-lang="properties"><span style="display:flex;"><span><span style="color:#586e75"># 自定义协议</span> |
| </span></span><span style="display:flex;"><span>dubbo.provider.protocol<span style="color:#719e07">=</span><span style="color:#2aa198">edubbo</span> |
| </span></span></code></pre></div><h5 id="consumer-2">Consumer</h5> |
| <p>在<code>resources/application.properties</code>文件中添加如下配置:</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-properties" data-lang="properties"><span style="display:flex;"><span><span style="color:#586e75"># 自定义协议</span> |
| </span></span><span style="display:flex;"><span>dubbo.consumer.protocol<span style="color:#719e07">=</span><span style="color:#2aa198">edubbo</span> |
| </span></span></code></pre></div><h2 id="运行结果">运行结果</h2> |
| <p>以<strong>使用本地IDE</strong>的方式来运行任务,结果如下:</p> |
| <h4 id="注册协议">注册协议</h4> |
| <p><img src="https://dubbo.apache.org/imgs/v3/tasks/extensibility/dubbo-samples-extensibility-protocol-output2.jpg" alt="dubbo-samples-extensibility-protocol-output2.jpg"></p> |
| <h4 id="输出结果">输出结果</h4> |
| <p><img src="https://dubbo.apache.org/imgs/v3/tasks/extensibility/dubbo-samples-extensibility-protocol-output1.png" alt="dubbo-samples-extensibility-protocol-output1.png"></p></description></item><item><title>Overview: Registry</title><link>https://dubbo.apache.org/zh-cn/overview/tasks/extensibility/registry/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://dubbo.apache.org/zh-cn/overview/tasks/extensibility/registry/</guid><description> |
| <p>文档编写中&hellip;</p></description></item><item><title>Overview: Router</title><link>https://dubbo.apache.org/zh-cn/overview/tasks/extensibility/router/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://dubbo.apache.org/zh-cn/overview/tasks/extensibility/router/</guid><description> |
| <p>通过自定义路由,可以根据业务场景的特点来实现特定的路由方式。</p> |
| <h2 id="开始之前">开始之前</h2> |
| <p>有两种部署运行方式,二选一</p> |
| <h3 id="基于kubernetes">基于Kubernetes</h3> |
| <ul> |
| <li>安装<a href="https://kubernetes.io/docs/tasks/tools/">Kubernetes</a>环境</li> |
| <li>修改<a href="https://github.com/apache/dubbo-samples/blob/master/10-task/dubbo-samples-extensibility/dubbo-samples-extensibility-router-provider/src/main/resources/application.properties">Provider</a>中的配置文件,启用Kubernetes中部署的nacos的地址 |
| <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-properties" data-lang="properties"><span style="display:flex;"><span><span style="color:#586e75"># Specify the application name of Dubbo</span> |
| </span></span><span style="display:flex;"><span>dubbo.application.name<span style="color:#719e07">=</span><span style="color:#2aa198">extensibility-router-provider</span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span><span style="color:#586e75"># Enable token verification for each invocation</span> |
| </span></span><span style="display:flex;"><span>dubbo.provider.token<span style="color:#719e07">=</span><span style="color:#2aa198">true</span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span><span style="color:#586e75"># Specify the registry address</span> |
| </span></span><span style="display:flex;"><span><span style="color:#586e75"># dubbo.registry.address=nacos://localhost:8848?username=nacos&amp;password=nacos</span> |
| </span></span><span style="display:flex;"><span><span style="color:#586e75"># 启用Kubernetes中部署的nacos的地址</span> |
| </span></span><span style="display:flex;"><span>dubbo.registry.address<span style="color:#719e07">=</span><span style="color:#2aa198">nacos://${nacos.address:localhost}:8848?username=nacos&amp;password=nacos</span> |
| </span></span><span style="display:flex;"><span><span style="color:#586e75"># Specify the port of Dubbo protocol</span> |
| </span></span><span style="display:flex;"><span>dubbo.protocol.port<span style="color:#719e07">=</span><span style="color:#2aa198">20881</span> |
| </span></span></code></pre></div></li> |
| <li>修改<a href="https://github.com/apache/dubbo-samples/blob/master/10-task/dubbo-samples-extensibility/dubbo-samples-extensibility-filter-consumer/src/main/resources/application.properties">Consumer</a>中的配置文件,启用Kubernetes中部署的nacos的地址 |
| <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-properties" data-lang="properties"><span style="display:flex;"><span><span style="color:#586e75"># Specify the application name of Dubbo</span> |
| </span></span><span style="display:flex;"><span>dubbo.application.name<span style="color:#719e07">=</span><span style="color:#2aa198">extensibility-filter-consumer</span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span><span style="color:#586e75"># Enable token verification for each invocation</span> |
| </span></span><span style="display:flex;"><span>dubbo.provider.token<span style="color:#719e07">=</span><span style="color:#2aa198">true</span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span><span style="color:#586e75"># Specify the registry address</span> |
| </span></span><span style="display:flex;"><span><span style="color:#586e75">#dubbo.registry.address=nacos://localhost:8848?username=nacos&amp;password=nacos</span> |
| </span></span><span style="display:flex;"><span><span style="color:#586e75"># 启用Kubernetes中部署的nacos的地址</span> |
| </span></span><span style="display:flex;"><span>dubbo.registry.address<span style="color:#719e07">=</span><span style="color:#2aa198">nacos://${nacos.address:localhost}:8848?username=nacos&amp;password=nacos</span> |
| </span></span><span style="display:flex;"><span><span style="color:#586e75"># 配置自定义路由</span> |
| </span></span><span style="display:flex;"><span>dubbo.consumer.router<span style="color:#719e07">=</span><span style="color:#2aa198">stickfirst</span> |
| </span></span></code></pre></div></li> |
| <li>部署<a href="https://github.com/apache/dubbo-samples/blob/master/10-task/dubbo-samples-extensibility/deploy/All.yml">Extensibility Router Task</a></li> |
| </ul> |
| <h3 id="使用本地ide">使用本地IDE</h3> |
| <ul> |
| <li>部署<a href="https://nacos.io/zh-cn/docs/quick-start.html">Nacos</a>2.2.0版本</li> |
| <li>修改<a href="https://github.com/apache/dubbo-samples/blob/master/10-task/dubbo-samples-extensibility/dubbo-samples-extensibility-filter-provider/src/main/resources/application.properties">Provider</a>中的配置文件,启用本地nacos的地址 |
| <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-properties" data-lang="properties"><span style="display:flex;"><span><span style="color:#586e75"># Specify the application name of Dubbo</span> |
| </span></span><span style="display:flex;"><span>dubbo.application.name<span style="color:#719e07">=</span><span style="color:#2aa198">extensibility-router-provider</span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span><span style="color:#586e75"># Enable token verification for each invocation</span> |
| </span></span><span style="display:flex;"><span>dubbo.provider.token<span style="color:#719e07">=</span><span style="color:#2aa198">true</span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span><span style="color:#586e75"># Specify the registry address</span> |
| </span></span><span style="display:flex;"><span><span style="color:#586e75"># 启用本地nacos的地址</span> |
| </span></span><span style="display:flex;"><span>dubbo.registry.address<span style="color:#719e07">=</span><span style="color:#2aa198">nacos://localhost:8848?username=nacos&amp;password=nacos</span> |
| </span></span><span style="display:flex;"><span><span style="color:#586e75"># dubbo.registry.address=nacos://${nacos.address:localhost}:8848?username=nacos&amp;password=nacos</span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span><span style="color:#586e75"># Specify the port of Dubbo protocol</span> |
| </span></span><span style="display:flex;"><span>dubbo.protocol.port<span style="color:#719e07">=</span><span style="color:#2aa198">20881</span> |
| </span></span></code></pre></div></li> |
| <li>修改<a href="https://github.com/apache/dubbo-samples/blob/master/10-task/dubbo-samples-extensibility/dubbo-samples-extensibility-filter-consumer/src/main/resources/application.properties">Consumer</a>中的配置文件,启用本地nacos的地址 |
| <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-properties" data-lang="properties"><span style="display:flex;"><span><span style="color:#586e75"># Specify the application name of Dubbo</span> |
| </span></span><span style="display:flex;"><span>dubbo.application.name<span style="color:#719e07">=</span><span style="color:#2aa198">extensibility-filter-consumer</span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span><span style="color:#586e75"># Enable token verification for each invocation</span> |
| </span></span><span style="display:flex;"><span>dubbo.provider.token<span style="color:#719e07">=</span><span style="color:#2aa198">true</span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span><span style="color:#586e75"># Specify the registry address</span> |
| </span></span><span style="display:flex;"><span><span style="color:#586e75"># 启用本地nacos的地址</span> |
| </span></span><span style="display:flex;"><span>dubbo.registry.address<span style="color:#719e07">=</span><span style="color:#2aa198">nacos://localhost:8848?username=nacos&amp;password=nacos</span> |
| </span></span><span style="display:flex;"><span><span style="color:#586e75">#dubbo.registry.address=nacos://${nacos.address:localhost}:8848?username=nacos&amp;password=nacos</span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span><span style="color:#586e75"># 配置自定义路由</span> |
| </span></span><span style="display:flex;"><span>dubbo.consumer.router<span style="color:#719e07">=</span><span style="color:#2aa198">stickfirst</span> |
| </span></span></code></pre></div></li> |
| </ul> |
| <h2 id="任务详情">任务详情</h2> |
| <p>对所有的请求都使用第一提供服务的Provider,如果该Provider下线,则从新选择一个新的Provider。</p> |
| <h2 id="实现方式">实现方式</h2> |
| <p>在Consumer中自定义一个Router,在Router中将第一次调用的Provider保存下来,如果后续有请求调用且Provider列表中包含第一次调用时使用的Provider,则继续使用第一次调用时使用的Provider,否则重新选去一个Provider。</p> |
| <h4 id="代码结构">代码结构</h4> |
| <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-properties" data-lang="properties"><span style="display:flex;"><span>src |
| </span></span><span style="display:flex;"><span> |-main |
| </span></span><span style="display:flex;"><span> |-java |
| </span></span><span style="display:flex;"><span> |-org |
| </span></span><span style="display:flex;"><span> |-apache |
| </span></span><span style="display:flex;"><span> |-dubbo |
| </span></span><span style="display:flex;"><span> |-samples |
| </span></span><span style="display:flex;"><span> |-extensibility |
| </span></span><span style="display:flex;"><span> |-router |
| </span></span><span style="display:flex;"><span> |-consumer |
| </span></span><span style="display:flex;"><span> |-router |
| </span></span><span style="display:flex;"><span> |-StickFirstStateRouter.java <span style="color:#2aa198">(实现StateRouter接口)</span> |
| </span></span><span style="display:flex;"><span> |-StickFirstStateRouterFactory.java <span style="color:#2aa198">(实现StateRouterFactory接口)</span> |
| </span></span><span style="display:flex;"><span> |-resources |
| </span></span><span style="display:flex;"><span> |-META-INF |
| </span></span><span style="display:flex;"><span> |-application.properties <span style="color:#2aa198">(Dubbo Consumer配置文件)</span> |
| </span></span><span style="display:flex;"><span> |-dubbo |
| </span></span><span style="display:flex;"><span> |-org.apache.dubbo.rpc.cluster.router.state.StateRouterFactory <span style="color:#2aa198">(纯文本文件)</span> |
| </span></span></code></pre></div><h4 id="代码详情">代码详情</h4> |
| <ul> |
| <li>StickFirstStateRouter</li> |
| </ul> |
| <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-java" data-lang="java"><span style="display:flex;"><span><span style="color:#719e07">package</span> org.apache.dubbo.samples.extensibility.router.consumer.router; |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">import</span> org.apache.dubbo.common.URL; |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">import</span> org.apache.dubbo.common.config.configcenter.ConfigChangeType; |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">import</span> org.apache.dubbo.common.config.configcenter.ConfigChangedEvent; |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">import</span> org.apache.dubbo.common.config.configcenter.ConfigurationListener; |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">import</span> org.apache.dubbo.common.logger.ErrorTypeAwareLogger; |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">import</span> org.apache.dubbo.common.logger.LoggerFactory; |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">import</span> org.apache.dubbo.common.utils.CollectionUtils; |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">import</span> org.apache.dubbo.common.utils.Holder; |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">import</span> org.apache.dubbo.rpc.Invocation; |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">import</span> org.apache.dubbo.rpc.Invoker; |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">import</span> org.apache.dubbo.rpc.RpcException; |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">import</span> org.apache.dubbo.rpc.cluster.router.RouterSnapshotNode; |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">import</span> org.apache.dubbo.rpc.cluster.router.state.AbstractStateRouter; |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">import</span> org.apache.dubbo.rpc.cluster.router.state.BitList; |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span><span style="color:#268bd2">public</span> <span style="color:#268bd2">class</span> <span style="color:#268bd2">StickFirstStateRouter</span><span style="color:#719e07">&lt;</span>T<span style="color:#719e07">&gt;</span> <span style="color:#268bd2">extends</span> AbstractStateRouter<span style="color:#719e07">&lt;</span>T<span style="color:#719e07">&gt;</span> <span style="color:#268bd2">implements</span> ConfigurationListener { |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">public</span> <span style="color:#268bd2">StickFirstStateRouter</span>(URL url) { |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">super</span>(url); |
| </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">public</span> <span style="color:#268bd2">static</span> <span style="color:#268bd2">final</span> String NAME <span style="color:#719e07">=</span> <span style="color:#2aa198">&#34;STICK_FIRST_ROUTER&#34;</span>; |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">private</span> <span style="color:#268bd2">static</span> <span style="color:#268bd2">final</span> ErrorTypeAwareLogger logger <span style="color:#719e07">=</span> LoggerFactory.getErrorTypeAwareLogger(StickFirstStateRouter.class); |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">private</span> <span style="color:#268bd2">volatile</span> BitList<span style="color:#719e07">&lt;</span>Invoker<span style="color:#719e07">&lt;</span>T<span style="color:#719e07">&gt;&gt;</span> firstInvokers; |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">@Override</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">protected</span> BitList<span style="color:#719e07">&lt;</span>Invoker<span style="color:#719e07">&lt;</span>T<span style="color:#719e07">&gt;&gt;</span> <span style="color:#268bd2">doRoute</span>(BitList<span style="color:#719e07">&lt;</span>Invoker<span style="color:#719e07">&lt;</span>T<span style="color:#719e07">&gt;&gt;</span> invokers, URL url, Invocation invocation, <span style="color:#dc322f">boolean</span> needToPrintMessage, Holder<span style="color:#719e07">&lt;</span>RouterSnapshotNode<span style="color:#719e07">&lt;</span>T<span style="color:#719e07">&gt;&gt;</span> routerSnapshotNodeHolder, Holder<span style="color:#719e07">&lt;</span>String<span style="color:#719e07">&gt;</span> messageHolder) <span style="color:#268bd2">throws</span> RpcException { |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">if</span> (CollectionUtils.isEmpty(invokers)) { |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">if</span> (needToPrintMessage) { |
| </span></span><span style="display:flex;"><span> messageHolder.set(<span style="color:#2aa198">&#34;Directly Return. Reason: Invokers from previous router is empty.&#34;</span>); |
| </span></span><span style="display:flex;"><span> } |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">return</span> invokers; |
| </span></span><span style="display:flex;"><span> } |
| </span></span><span style="display:flex;"><span> BitList<span style="color:#719e07">&lt;</span>Invoker<span style="color:#719e07">&lt;</span>T<span style="color:#719e07">&gt;&gt;</span> copy <span style="color:#719e07">=</span> invokers.clone(); |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">if</span> (CollectionUtils.isEmpty(copy)) { |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">this</span>.firstInvokers <span style="color:#719e07">=</span> <span style="color:#719e07">new</span> BitList<span style="color:#719e07">&lt;&gt;</span>(BitList.emptyList()); |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">this</span>.firstInvokers.add(copy.get(0)); |
| </span></span><span style="display:flex;"><span> } <span style="color:#719e07">else</span> { |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">this</span>.firstInvokers <span style="color:#719e07">=</span> copy.and(invokers); |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">if</span>(CollectionUtils.isEmpty(<span style="color:#719e07">this</span>.firstInvokers)){ |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">this</span>.firstInvokers.add(copy.get(0)); |
| </span></span><span style="display:flex;"><span> } |
| </span></span><span style="display:flex;"><span> } |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">return</span> <span style="color:#719e07">this</span>.firstInvokers; |
| </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">@Override</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">public</span> <span style="color:#dc322f">void</span> <span style="color:#268bd2">process</span>(ConfigChangedEvent event) { |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">if</span> (logger.isDebugEnabled()) { |
| </span></span><span style="display:flex;"><span> logger.debug(<span style="color:#2aa198">&#34;Notification of tag rule, change type is: &#34;</span> <span style="color:#719e07">+</span> event.getChangeType() <span style="color:#719e07">+</span> <span style="color:#2aa198">&#34;, raw rule is:\n &#34;</span> <span style="color:#719e07">+</span> |
| </span></span><span style="display:flex;"><span> event.getContent()); |
| </span></span><span style="display:flex;"><span> } |
| </span></span><span style="display:flex;"><span> <span style="color:#586e75">// Reset</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">if</span> (event.getChangeType().equals(ConfigChangeType.DELETED)) { |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">this</span>.firstInvokers <span style="color:#719e07">=</span> <span style="color:#cb4b16">null</span>; |
| </span></span><span style="display:flex;"><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">@Override</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">public</span> <span style="color:#dc322f">void</span> <span style="color:#268bd2">stop</span>() { |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">super</span>.stop(); |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">this</span>.firstInvokers <span style="color:#719e07">=</span> <span style="color:#cb4b16">null</span>; |
| </span></span><span style="display:flex;"><span> } |
| </span></span><span style="display:flex;"><span>} |
| </span></span></code></pre></div><ul> |
| <li>StickFirstStateRouterFactory</li> |
| </ul> |
| <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-java" data-lang="java"><span style="display:flex;"><span><span style="color:#719e07">package</span> org.apache.dubbo.samples.extensibility.router.consumer.router; |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">import</span> org.apache.dubbo.common.URL; |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">import</span> org.apache.dubbo.rpc.cluster.router.state.StateRouter; |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">import</span> org.apache.dubbo.rpc.cluster.router.state.StateRouterFactory; |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span><span style="color:#268bd2">public</span> <span style="color:#268bd2">class</span> <span style="color:#268bd2">StickFirstStateRouterFactory</span> <span style="color:#268bd2">implements</span> StateRouterFactory { |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">@Override</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">public</span> <span style="color:#719e07">&lt;</span>T<span style="color:#719e07">&gt;</span> StateRouter<span style="color:#719e07">&lt;</span>T<span style="color:#719e07">&gt;</span> <span style="color:#268bd2">getRouter</span>(Class<span style="color:#719e07">&lt;</span>T<span style="color:#719e07">&gt;</span> interfaceClass, URL url) { |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">return</span> <span style="color:#719e07">new</span> StickFirstStateRouter<span style="color:#719e07">&lt;&gt;</span>(url); |
| </span></span><span style="display:flex;"><span> } |
| </span></span><span style="display:flex;"><span>} |
| </span></span></code></pre></div><h4 id="spi配置">SPI配置</h4> |
| <p>在<code>resources/META-INF/dubbo/org.apache.dubbo.rpc.cluster.router.state.StateRouterFactory</code>文件中添加如下配置:</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-properties" data-lang="properties"><span style="display:flex;"><span>stickfirst<span style="color:#719e07">=</span><span style="color:#2aa198">org.apache.dubbo.samples.extensibility.router.consumer.router.StickFirstStateRouterFactory</span> |
| </span></span></code></pre></div><h4 id="配置文件">配置文件</h4> |
| <p>在<code>resources/application.properties</code>文件中添加如下配置:</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-properties" data-lang="properties"><span style="display:flex;"><span><span style="color:#586e75"># 配置自定义路由</span> |
| </span></span><span style="display:flex;"><span>dubbo.consumer.router<span style="color:#719e07">=</span><span style="color:#2aa198">stickfirst</span> |
| </span></span></code></pre></div><h2 id="运行结果">运行结果</h2> |
| <p>以<strong>使用本地IDE</strong>的方式来运行任务,结果如下:</p> |
| <p><img src="https://dubbo.apache.org/imgs/v3/tasks/extensibility/dubbo-samples-extensibility-router-output.png" alt="dubbo-samples-extensibility-router-output.png"></p></description></item></channel></rss> |