| <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/core-features/traffic/</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/core-features/traffic/index.xml" rel="self" type="application/rss+xml"/><item><title>Overview: 条件路由规则</title><link>https://dubbo.apache.org/zh-cn/overview/core-features/traffic/condition-rule/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://dubbo.apache.org/zh-cn/overview/core-features/traffic/condition-rule/</guid><description> |
| <p>条件路由规则将符合特定条件的请求转发到特定的地址实例子集上。规则首先对发起流量的请求参数进行匹配,符合匹配条件的请求将被转发到包含特定实例地址列表的子集。</p> |
| <p>以下是一个条件路由规则示例。</p> |
| <p>基于以下示例规则,所有 <code>org.apache.dubbo.samples.CommentService</code> 服务 <code>getComment</code> 方法的调用都将被转发到有 <code>region=Hangzhou</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-yaml" data-lang="yaml"><span style="display:flex;"><span><span style="color:#268bd2">configVersion</span>: v3.0 |
| </span></span><span style="display:flex;"><span><span style="color:#268bd2">scope</span>: service |
| </span></span><span style="display:flex;"><span><span style="color:#268bd2">force</span>: <span style="color:#cb4b16">true</span> |
| </span></span><span style="display:flex;"><span><span style="color:#268bd2">runtime</span>: <span style="color:#cb4b16">true</span> |
| </span></span><span style="display:flex;"><span><span style="color:#268bd2">enabled</span>: <span style="color:#cb4b16">true</span> |
| </span></span><span style="display:flex;"><span><span style="color:#268bd2">key</span>: org.apache.dubbo.samples.CommentService |
| </span></span><span style="display:flex;"><span><span style="color:#268bd2">conditions</span>: |
| </span></span><span style="display:flex;"><span> - method=getComment =&gt; region=Hangzhou |
| </span></span></code></pre></div><h2 id="conditionrule">ConditionRule</h2> |
| <p>条件路由规则主体。定义路由规则生效的目标服务或应用、流量过滤条件以及一些特定场景下的行为。</p> |
| <table> |
| <thead> |
| <tr> |
| <th>Field</th> |
| <th>Type</th> |
| <th>Description</th> |
| <th>Required</th> |
| </tr> |
| </thead> |
| <tbody> |
| <tr> |
| <td>configVersion</td> |
| <td>string</td> |
| <td>The version of the condition rule definition, currently available version is <code>v3.0</code></td> |
| <td>Yes</td> |
| </tr> |
| <tr> |
| <td>scope</td> |
| <td>string</td> |
| <td>Supports <code>service</code> and <code>application</code> scope rules.</td> |
| <td>Yes</td> |
| </tr> |
| <tr> |
| <td>key</td> |
| <td>string</td> |
| <td>The identifier of the target service or application that this rule is about to apply to. <br/><br/>- If <code>scope:service</code>is set, then <code>key</code>should be specified as the Dubbo service key that this rule targets to control.<br/> - If <code>scope:application</code> is set, then <code>key</code>should be specified as the name of the application that this rule targets to control, application should always be a Dubbo Consumer.</td> |
| <td>Yes</td> |
| </tr> |
| <tr> |
| <td>enabled</td> |
| <td>bool</td> |
| <td>Whether enable this rule or not, set <code>enabled:false</code> to disable this rule.</td> |
| <td>Yes</td> |
| </tr> |
| <tr> |
| <td>conditions</td> |
| <td>string[]</td> |
| <td>The condition routing rule definition of this configuration. Check <a href="./#condition">Condition</a> for details</td> |
| <td>Yes</td> |
| </tr> |
| <tr> |
| <td>force</td> |
| <td>bool</td> |
| <td>The behaviour when the instance subset is empty after after routing. <code>true</code> means return no provider exception while <code>false</code> means ignore this rule.</td> |
| <td>No</td> |
| </tr> |
| <tr> |
| <td>runtime</td> |
| <td>bool</td> |
| <td>Whether run routing rule for every rpc invocation or use routing cache if available.</td> |
| <td>No</td> |
| </tr> |
| </tbody> |
| </table> |
| <h2 id="condition">Condition</h2> |
| <p><code>Condition</code> 为条件路由规则的主体,类型为一个复合结构的 string 字符串,如 <code>method=getComment =&gt; region=Hangzhou</code>。其中,</p> |
| <ul> |
| <li>=&gt; 之前的为请求参数匹配条件,指定的 <code>匹配条件指定的参数</code> 将与 <code>消费者的请求上下文 (URL)、甚至方法参数</code> 进行对比,当消费者满足匹配条件时,对该消费者执行后面的地址子集过滤规则。</li> |
| <li>=&gt; 之后的为地址子集过滤条件,指定的 <code>过滤条件指定的参数</code> 将与 <code>提供者实例地址 (URL)</code> 进行对比,消费者最终只能拿到符合过滤条件的实例列表,从而确保流量只会发送到符合条件的地址子集。 |
| <ul> |
| <li>如果匹配条件为空,表示对所有请求生效,如:<code>=&gt; status != staging</code></li> |
| <li>如果过滤条件为空,表示禁止来自相应请求的访问,如:<code>application = product =&gt;</code></li> |
| </ul> |
| </li> |
| </ul> |
| <h3 id="匹配过滤条件">匹配/过滤条件</h3> |
| <p><strong>参数支持</strong></p> |
| <ul> |
| <li>服务调用上下文,如:interface, method, group, version 等</li> |
| <li>请求上下文,如 attachments[key] = value</li> |
| <li>方法参数,如 arguments[0] = tom</li> |
| <li>URL 本身的字段,如:protocol, host, port 等</li> |
| <li>URL 上任务扩展参数,如:application, organization 等</li> |
| <li>支持开发者自定义扩展</li> |
| </ul> |
| <p><strong>条件支持</strong></p> |
| <ul> |
| <li>等号 = 表示 &ldquo;匹配&rdquo;,如:method = getComment</li> |
| <li>不等号 != 表示 &ldquo;不匹配&rdquo;,如:method != getComment</li> |
| </ul> |
| <p><strong>值支持</strong></p> |
| <ul> |
| <li>以逗号 , 分隔多个值,如:host != 10.20.153.10,10.20.153.11</li> |
| <li>以星号 * 结尾,表示通配,如:host != 10.20.*</li> |
| <li>以美元符 $ 开头,表示引用消费者参数,如:region = $region</li> |
| <li>整数值范围,如:userId = 1~100、userId = 101~</li> |
| <li>支持开发者自定义扩展</li> |
| </ul></description></item><item><title>Overview: 标签路由规则</title><link>https://dubbo.apache.org/zh-cn/overview/core-features/traffic/tag-rule/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://dubbo.apache.org/zh-cn/overview/core-features/traffic/tag-rule/</guid><description> |
| <p>标签路由通过将某一个服务的实例划分到不同的分组,约束具有特定标签的流量只能在指定分组中流转,不同分组为不同的流量场景服务,从而达到实现流量隔离的目的,可以作为蓝绿发布、灰度发布等场景能力的基础。目前有两种方式可以对实例打标,分别是<code>动态规则打标</code>和<code>静态规则打标</code>。<code>动态规则打标</code> 可以在运行时动态的圈住一组机器实例,而 <code>静态规则打标</code> 则需要实例重启后才能生效,其中,动态规则相较于静态规则优先级更高,而当两种规则同时存在且出现冲突时,将以动态规则为准。</p> |
| <p>本文要讲的就是标签路由规则就是 <code>动态规则打标</code>。</p> |
| <p>标签路由是一套严格隔离的流量体系,对于同一个应用而言,一旦打了标签则这部分地址子集就被隔离出来,只有带有对应标签的请求流量可以访问这个地址子集,这部分地址不再接收没有标签或者具有不同标签的流量。</p> |
| <p>举个例子,如果我们将一个应用进行打标,打标后划分为 tag-a、tag-b、无 tag 三个地址子集,则访问这个应用的流量,要么路由到 tag-a (当请求上下文 dubbo.tag=tag-a),要么路由到 tag-b (dubbo.tag=tag-b),或者路由到无 tag 的地址子集 (dubbo.tag 未设置),不会出现混调的情况。</p> |
| <p>标签路由的作用域是提供者应用,消费者应用无需配置标签路由规则。一个提供者应用内的所有服务只能有一条分组规则,不会有服务 A 使用一条路由规则、服务 B 使用另一条路由规则的情况出现。以下条件路由示例,在 <code>shop-detail</code> 应用中圈出了一个隔离环境 <code>gray</code>,<code>gray</code> 环境包含所有带有 <code>env=gray</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-yaml" data-lang="yaml"><span style="display:flex;"><span><span style="color:#268bd2">configVersion</span>: v3.0 |
| </span></span><span style="display:flex;"><span><span style="color:#268bd2">force</span>: <span style="color:#cb4b16">true</span> |
| </span></span><span style="display:flex;"><span><span style="color:#268bd2">enabled</span>: <span style="color:#cb4b16">true</span> |
| </span></span><span style="display:flex;"><span><span style="color:#268bd2">key</span>: shop-detail |
| </span></span><span style="display:flex;"><span><span style="color:#268bd2">tags</span>: |
| </span></span><span style="display:flex;"><span> - <span style="color:#268bd2">name</span>: gray |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">match</span>: |
| </span></span><span style="display:flex;"><span> - <span style="color:#268bd2">key</span>: env |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">value</span>: |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">exact</span>: gray |
| </span></span></code></pre></div><h2 id="tagrule">TagRule</h2> |
| <p>标签路由规则主体。定义路由规则生效的目标应用、标签分类规则以及一些特定场景下的行为。</p> |
| <table> |
| <thead> |
| <tr> |
| <th>Field</th> |
| <th>Type</th> |
| <th>Description</th> |
| <th>Required</th> |
| </tr> |
| </thead> |
| <tbody> |
| <tr> |
| <td>configVersion</td> |
| <td>string</td> |
| <td>The version of the tag rule definition, currently available version is <code>v3.0</code></td> |
| <td>Yes</td> |
| </tr> |
| <tr> |
| <td>key</td> |
| <td>string</td> |
| <td>The identifier of the target application that this rule is about to control</td> |
| <td>Yes</td> |
| </tr> |
| <tr> |
| <td>enabled</td> |
| <td>bool</td> |
| <td>Whether enable this rule or not, set <code>enabled:false</code> to disable this rule.</td> |
| <td>Yes</td> |
| </tr> |
| <tr> |
| <td>tags</td> |
| <td>Tag[]</td> |
| <td>The tag definition of this rule.</td> |
| <td>Yes</td> |
| </tr> |
| <tr> |
| <td>force</td> |
| <td>bool</td> |
| <td>The behaviour when the instance subset is empty after routing. <code>true</code> means return no provider exception while <code>false</code> means fallback to subset without any tags.</td> |
| <td>No</td> |
| </tr> |
| <tr> |
| <td>runtime</td> |
| <td>bool</td> |
| <td>Whether run routing rule for every rpc invocation or use routing cache if available.</td> |
| <td>No</td> |
| </tr> |
| </tbody> |
| </table> |
| <h2 id="tag">Tag</h2> |
| <p>标签定义,根据 <code>match</code> 条件筛选出一部分地址子集。</p> |
| <table> |
| <thead> |
| <tr> |
| <th>Field</th> |
| <th>Type</th> |
| <th>Description</th> |
| <th>Required</th> |
| </tr> |
| </thead> |
| <tbody> |
| <tr> |
| <td>name</td> |
| <td>string</td> |
| <td>The name of the tag used to match the <code>dubbo.tag</code> value in the request context.</td> |
| <td>Yes</td> |
| </tr> |
| <tr> |
| <td>match</td> |
| <td>MatchCondition</td> |
| <td>A set of criterion to be met for instances to be classified as member of this tag.</td> |
| <td>No</td> |
| </tr> |
| </tbody> |
| </table> |
| <h2 id="matchcondition">MatchCondition</h2> |
| <p>定义实例过滤条件,根据 Dubbo URL 地址中的特定参数进行过滤。</p> |
| <table> |
| <thead> |
| <tr> |
| <th>Field</th> |
| <th>Type</th> |
| <th>Description</th> |
| <th>Required</th> |
| </tr> |
| </thead> |
| <tbody> |
| <tr> |
| <td>key</td> |
| <td>string</td> |
| <td>The name of the key in the Dubbo url address.</td> |
| <td>Yes</td> |
| </tr> |
| <tr> |
| <td>value</td> |
| <td>StringMatch (oneof)</td> |
| <td>The matching condition for the value in the Dubbo url address.</td> |
| <td>Yes</td> |
| </tr> |
| </tbody> |
| </table></description></item><item><title>Overview: 脚本路由规则</title><link>https://dubbo.apache.org/zh-cn/overview/core-features/traffic/script-rule/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://dubbo.apache.org/zh-cn/overview/core-features/traffic/script-rule/</guid><description> |
| <p>脚本路由为流量管理提供了最大的灵活性,所有流量在执行负载均衡选址之前,都会动态的执行一遍规则脚本,根据脚本执行的结果确定可用的地址子集。</p> |
| <p>脚本路由只对消费者生效且只支持应用粒度管理,因此, <code>key</code> 必须设置为消费者应用名;脚本语法支持多种,以 Dubbo Java SDK 为例,脚本语法支持 Javascript、Groovy、Kotlin 等,具体可参见每个语言实现的限制。</p> |
| <blockquote> |
| <p>脚本路由由于可以动态加载远端代码执行,因此存在潜在的安全隐患,在启用脚本路由前,一定要确保脚本规则在安全沙箱内运行。</p> |
| </blockquote> |
| <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">configVersion</span>: v3.0 |
| </span></span><span style="display:flex;"><span><span style="color:#268bd2">key</span>: demo-provider |
| </span></span><span style="display:flex;"><span><span style="color:#268bd2">type</span>: javascript |
| </span></span><span style="display:flex;"><span><span style="color:#268bd2">enabled</span>: <span style="color:#cb4b16">true</span> |
| </span></span><span style="display:flex;"><span><span style="color:#268bd2">script</span>: |<span style="color:#2aa198"> |
| </span></span></span><span style="display:flex;"><span><span style="color:#2aa198"> (function route(invokers,invocation,context) { |
| </span></span></span><span style="display:flex;"><span><span style="color:#2aa198"> var result = new java.util.ArrayList(invokers.size()); |
| </span></span></span><span style="display:flex;"><span><span style="color:#2aa198"> for (i = 0; i &lt; invokers.size(); i ++) { |
| </span></span></span><span style="display:flex;"><span><span style="color:#2aa198"> if (&#34;10.20.3.3&#34;.equals(invokers.get(i).getUrl().getHost())) { |
| </span></span></span><span style="display:flex;"><span><span style="color:#2aa198"> result.add(invokers.get(i)); |
| </span></span></span><span style="display:flex;"><span><span style="color:#2aa198"> } |
| </span></span></span><span style="display:flex;"><span><span style="color:#2aa198"> } |
| </span></span></span><span style="display:flex;"><span><span style="color:#2aa198"> return result; |
| </span></span></span><span style="display:flex;"><span><span style="color:#2aa198"> } (invokers, invocation, context)); // 表示立即执行方法</span> |
| </span></span></code></pre></div><h2 id="scriptrule">ScriptRule</h2> |
| <p>脚本路由规则主体。定义脚本规则生效的目标消费者应用、流量过滤脚本以及一些特定场景下的行为。</p> |
| <table> |
| <thead> |
| <tr> |
| <th>Field</th> |
| <th>Type</th> |
| <th>Description</th> |
| <th>Required</th> |
| </tr> |
| </thead> |
| <tbody> |
| <tr> |
| <td>configVersion</td> |
| <td>string</td> |
| <td>The version of the script rule definition, currently available version is <code>v3.0</code></td> |
| <td>Yes</td> |
| </tr> |
| <tr> |
| <td>key</td> |
| <td>string</td> |
| <td>The identifier of the target application that this rule is about to apply to.</td> |
| <td>Yes</td> |
| </tr> |
| <tr> |
| <td>type</td> |
| <td>string</td> |
| <td>The script language used to define <code>script</code>.</td> |
| <td>Yes</td> |
| </tr> |
| <tr> |
| <td>enabled</td> |
| <td>bool</td> |
| <td>Whether enable this rule or not, set <code>enabled:false</code> to disable this rule.</td> |
| <td>Yes</td> |
| </tr> |
| <tr> |
| <td>script</td> |
| <td>string</td> |
| <td>The script definition used to filter dubbo provider instances.</td> |
| <td>Yes</td> |
| </tr> |
| <tr> |
| <td>force</td> |
| <td>bool</td> |
| <td>The behaviour when the instance subset is empty after after routing. <code>true</code> means return no provider exception while <code>false</code> means ignore this rule.</td> |
| <td>No</td> |
| </tr> |
| </tbody> |
| </table> |
| <h2 id="script">Script</h2> |
| <p><code>script</code> 为脚本路由规则的主体,类型为一个具有符合结构的 string 字符串,具体取决于 <code>type</code> 指定的脚本语言。</p> |
| <p>以下是 <code>type: javascript</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-javascript" data-lang="javascript"><span style="display:flex;"><span>(<span style="color:#268bd2">function</span> route(invokers,invocation,context) { |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">var</span> result <span style="color:#719e07">=</span> <span style="color:#719e07">new</span> java.util.ArrayList(invokers.size()); |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">for</span> (i <span style="color:#719e07">=</span> <span style="color:#2aa198">0</span>; i <span style="color:#719e07">&lt;</span> invokers.size(); i <span style="color:#719e07">++</span>) { |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">if</span> (<span style="color:#2aa198">&#34;10.20.3.3&#34;</span>.equals(invokers.get(i).getUrl().getHost())) { |
| </span></span><span style="display:flex;"><span> result.add(invokers.get(i)); |
| </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> result; |
| </span></span><span style="display:flex;"><span> } (invokers, invocation, context)); <span style="color:#586e75">// 表示立即执行方法 |
| </span></span></span></code></pre></div></description></item><item><title>Overview: 动态配置规则</title><link>https://dubbo.apache.org/zh-cn/overview/core-features/traffic/configuration-rule/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://dubbo.apache.org/zh-cn/overview/core-features/traffic/configuration-rule/</guid><description> |
| <p>动态配置规则 (ConfigurationRule) 是 Dubbo 设计的在无需重启应用的情况下,动态调整 RPC 调用行为的一种能力,也称为动态覆盖规则,因为它是通过在运行态覆盖 Dubbo 实例或者 Dubbo 实例中 URL 地址的各种参数值,实现改变 RPC 调用行为的能力。</p> |
| <p>使用动态配置规则,有以下几条关键信息值得注意:</p> |
| <ul> |
| <li><strong>设置规则生效过滤条件。</strong> 配置规则支持一系列的过滤条件,用来限定规则只对符合特定条件的服务、应用或实例才生效。</li> |
| <li><strong>设置规则生效范围。</strong> 一个 rpc 服务有服务发起方(消费者)和服务处理方(提供者)两个角色,对某一个服务定义的规则,可以具体到限制是对消费者还是提供者生效。</li> |
| <li><strong>选择规则管理粒度。</strong> Dubbo 支持从服务和应用两个粒度来管理和下发规则。</li> |
| </ul> |
| <p>以下一个应用级别的配置示例,配置生效后,<code>shop-detail</code> 应用下提供的所有服务都将启用 accesslog,对 <code>shop-detail</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-yaml" data-lang="yaml"><span style="display:flex;"><span><span style="color:#268bd2">configVersion</span>: v3.0 |
| </span></span><span style="display:flex;"><span><span style="color:#268bd2">scope</span>: application |
| </span></span><span style="display:flex;"><span><span style="color:#268bd2">key</span>: shop-detail |
| </span></span><span style="display:flex;"><span><span style="color:#268bd2">configs</span>: |
| </span></span><span style="display:flex;"><span> - <span style="color:#268bd2">side</span>: provider |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">parameters</span>: |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">accesslog</span>: <span style="color:#2aa198">&#39;true&#39;</span> |
| </span></span></code></pre></div><p>以下是一个服务级别的配置示例,<code>key: org.apache.dubbo.samples.UserService</code> 和 <code>side: consumer</code> 说明这条配置对所有正在消费 UserService 的 Dubbo 实例生效,在调用失败后都执行 4 次重试。<code>match</code> 条件进一步限制了消费端的范围,限定为只对应用名为 <code>shop-frontend</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-yaml" data-lang="yaml"><span style="display:flex;"><span><span style="color:#268bd2">configVersion</span>: v3.0 |
| </span></span><span style="display:flex;"><span><span style="color:#268bd2">scope</span>: service |
| </span></span><span style="display:flex;"><span><span style="color:#268bd2">key</span>: org.apache.dubbo.samples.UserService |
| </span></span><span style="display:flex;"><span><span style="color:#268bd2">configs</span>: |
| </span></span><span style="display:flex;"><span> - <span style="color:#268bd2">match</span>: |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">application</span>: |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">oneof</span>: |
| </span></span><span style="display:flex;"><span> - <span style="color:#268bd2">exact</span>: shop-frontend |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">side</span>: consumer |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">parameters</span>: |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">retries</span>: <span style="color:#2aa198">&#39;4&#39;</span> |
| </span></span></code></pre></div><h2 id="configurationrule">ConfigurationRule</h2> |
| <p>配置规则主体,定义要设置的目标服务或应用、具体的规则配置。具体配置规则 (configs) 可以设置多条。</p> |
| <table> |
| <thead> |
| <tr> |
| <th>Field</th> |
| <th>Type</th> |
| <th>Description</th> |
| <th>Required</th> |
| </tr> |
| </thead> |
| <tbody> |
| <tr> |
| <td>configVersion</td> |
| <td>string</td> |
| <td>The version of the configuration rule definition, currently available version is <code>v3.0</code></td> |
| <td>Yes</td> |
| </tr> |
| <tr> |
| <td>scope</td> |
| <td>string</td> |
| <td>Supports <code>service</code> and <code>application</code> scope configurations.</td> |
| <td>Yes</td> |
| </tr> |
| <tr> |
| <td>key</td> |
| <td>string</td> |
| <td>The identifier of the target service or application that this rule is about to apply to. <br/><br/>- If <code>scope:service</code>is set, then <code>key</code>should be specified as the Dubbo service key that this rule targets to control.<br/> - If <code>scope:application</code> is set, then <code>key</code>should be specified as the name of the application that this rule targets to control.</td> |
| <td>Yes</td> |
| </tr> |
| <tr> |
| <td>enabled</td> |
| <td>bool</td> |
| <td>Whether enable this rule or not, set <code>enabled:false</code> to disable this rule.</td> |
| <td>Yes</td> |
| </tr> |
| <tr> |
| <td>configs</td> |
| <td>Config[]</td> |
| <td>The <code>match condition</code> and <code>configuration</code> of this rule.</td> |
| <td>Yes</td> |
| </tr> |
| </tbody> |
| </table> |
| <h2 id="config">Config</h2> |
| <p>具体的规则配置定义,包含生效端 (consumer 或 provider) 和过滤条件。</p> |
| <table> |
| <thead> |
| <tr> |
| <th>Field</th> |
| <th>Type</th> |
| <th>Description</th> |
| <th>Required</th> |
| </tr> |
| </thead> |
| <tbody> |
| <tr> |
| <td>side</td> |
| <td>string</td> |
| <td>Especially useful when <code>scope:service</code>is set.<br/><br/>- <code>side: provider</code>means this Config will only take effect on the provider instances of the service key.<br/>- <code>side:consumer</code>means this Config will only take effect on the consumer instances of the service key</td> |
| <td>Yes</td> |
| </tr> |
| <tr> |
| <td>parameters</td> |
| <td>map&lt;string, string&gt;</td> |
| <td>The keys and values this rule aims to change.</td> |
| <td>Yes</td> |
| </tr> |
| <tr> |
| <td>match</td> |
| <td>MatchCondition</td> |
| <td>A set of criterion to be met in order for the rule/config to be applied to the Dubbo instance.</td> |
| <td>No</td> |
| </tr> |
| <tr> |
| <td>enabled</td> |
| <td>bool</td> |
| <td>Whether enable this Config or not, will use the value in ConfigurationRule if not set</td> |
| <td>No</td> |
| </tr> |
| <tr> |
| <td><del>addresses</del></td> |
| <td><del>string[]</del></td> |
| <td><del>replaced with address in MatchCondition</del></td> |
| <td><del>No</del></td> |
| </tr> |
| <tr> |
| <td><del>providerAddresses</del></td> |
| <td><del>string[]</del></td> |
| <td><del>not supported anymore</del></td> |
| <td><del>No</del></td> |
| </tr> |
| <tr> |
| <td><del>services</del></td> |
| <td><del>string[]</del></td> |
| <td><del>replaced with service in MatchCondition</del></td> |
| <td><del>No</del></td> |
| </tr> |
| <tr> |
| <td><del>applications</del></td> |
| <td><del>string[]</del></td> |
| <td><del>replaced with application in MatchCondition</del></td> |
| <td><del>No</del></td> |
| </tr> |
| </tbody> |
| </table> |
| <h2 id="matchcondition">MatchCondition</h2> |
| <p>过滤条件,用来设置规则对哪个服务 (service)、应用 (application)、实例 (address),或者包含哪些参数 (param) 的实例生效。</p> |
| <table> |
| <thead> |
| <tr> |
| <th>Field</th> |
| <th>Type</th> |
| <th>Description</th> |
| <th>Required</th> |
| </tr> |
| </thead> |
| <tbody> |
| <tr> |
| <td>address</td> |
| <td>StringMatch</td> |
| <td>The instance address matching condition for this config rule to take effect.<br/><br/>- xact: &ldquo;value&rdquo; for exact string match<br/>- prefix: &ldquo;value&rdquo; for prefix-based match<br/>- regex: &ldquo;value&rdquo; for RE2 style regex-based match (<a href="https://github.com/google/re2/wiki/Syntax">https://github.com/google/re2/wiki/Syntax)</a>).</td> |
| <td>No</td> |
| </tr> |
| <tr> |
| <td>service</td> |
| <td>StringMatch (oneof)</td> |
| <td>The service matching condition for this config rule to take effect. Effective when <code>scope: application</code> is set.<br/><br/>- exact: &ldquo;value&rdquo; for exact string match<br/>- prefix: &ldquo;value&rdquo; for prefix-based match<br/>- regex: &ldquo;value&rdquo; for RE2 style regex-based match (<a href="https://github.com/google/re2/wiki/Syntax">https://github.com/google/re2/wiki/Syntax)</a>).</td> |
| <td>No</td> |
| </tr> |
| <tr> |
| <td>application</td> |
| <td>StringMatch (oneof)</td> |
| <td>The application matching condition for this config rule to take effect. Effective when <code>scope: service</code> is set.<br/><br/>- exact: &ldquo;value&rdquo; for exact string match<br/>- prefix: &ldquo;value&rdquo; for prefix-based match<br/>- regex: &ldquo;value&rdquo; for RE2 style regex-based match (<a href="https://github.com/google/re2/wiki/Syntax">https://github.com/google/re2/wiki/Syntax)</a>).</td> |
| <td>No</td> |
| </tr> |
| <tr> |
| <td>param</td> |
| <td>ParamCondition[]</td> |
| <td>The Dubbo url keys and values matching condition for this config rule to take effect.</td> |
| <td>No</td> |
| </tr> |
| </tbody> |
| </table> |
| <h2 id="paramcondition">ParamCondition</h2> |
| <p>定义实例参数 (param) 过滤条件,对应到 Dubbo URL 地址参数。</p> |
| <table> |
| <thead> |
| <tr> |
| <th>Field</th> |
| <th>Type</th> |
| <th>Description</th> |
| <th>Required</th> |
| </tr> |
| </thead> |
| <tbody> |
| <tr> |
| <td>key</td> |
| <td>string</td> |
| <td>The name of the key in the Dubbo url address.</td> |
| <td>Yes</td> |
| </tr> |
| <tr> |
| <td>value</td> |
| <td>StringMatch (oneof)</td> |
| <td>The matching condition for the value in the Dubbo url address.</td> |
| <td>Yes</td> |
| </tr> |
| </tbody> |
| </table> |
| <h2 id="stringmatch">StringMatch</h2> |
| <table> |
| <thead> |
| <tr> |
| <th>Field</th> |
| <th>Type</th> |
| <th>Description</th> |
| <th>Required</th> |
| </tr> |
| </thead> |
| <tbody> |
| <tr> |
| <td>exact</td> |
| <td>string (oneof)</td> |
| <td>exact string match</td> |
| <td>No</td> |
| </tr> |
| <tr> |
| <td>prefix</td> |
| <td>string (oneof)</td> |
| <td>prefix-based match</td> |
| <td>No</td> |
| </tr> |
| <tr> |
| <td>regex</td> |
| <td>string (oneof)</td> |
| <td>RE2 style regex-based match (<a href="https://github.com/google/re2/wiki/Syntax">https://github.com/google/re2/wiki/Syntax)</a>).</td> |
| <td>No</td> |
| </tr> |
| </tbody> |
| </table></description></item><item><title>Overview: 限流 & 熔断</title><link>https://dubbo.apache.org/zh-cn/overview/core-features/traffic/circuit-breaking/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://dubbo.apache.org/zh-cn/overview/core-features/traffic/circuit-breaking/</guid><description> |
| <p>由于微服务分布式的特点,如何构建稳定的微服务集群是一个很大的挑战,其中有两项非常关键的点值得关注</p> |
| <ul> |
| <li>流量控制 (Rate Limiting)</li> |
| <li>熔断降级 (Circuit Breaking)</li> |
| </ul> |
| <h2 id="流量控制">流量控制</h2> |
| <p><strong>流量控制更多的是站在 Dubbo 服务提供者视角来保证服务稳定性</strong>,通过明确的为 Dubbo 服务设置请求上限阈值,确保服务所处理的请求数始终在一个合理范围之内,从而确保系统整体的稳定性。</p> |
| <p><img src="https://dubbo.apache.org/imgs/v3/feature/circuit-breaking/provider-rate-limit.png" alt="provider-rate-limit"></p> |
| <p>根据服务的具体部署情况,服务所能处理的流量上限是一定的,当对服务的请求数量保持在合理的范围时,系统运行正常;而当请求数量严重超过服务处理能力时,如大促期间的流量洪峰等场景,就可能造成服务提供者端的资源过度消耗、负载过高,进而出现响应延迟、请求无应答、系统假死等情况。</p> |
| <p>流量控制解决的问题和工作方式比较容易理解,而其使用的难点就是如何确定服务所能处理的流量最大值?</p> |
| <ul> |
| <li>一种模式是由用户预先设定一个固定的限流值,如 Dubbo 通过集成 Sentinel 等产品实现的限流能力即是这种模式 |
| <ul> |
| <li><a href="../../../tasks/rate-limit/sentinel/">Dubbo Sentinel 流量控制</a></li> |
| </ul> |
| </li> |
| <li>另一种方式是 Dubbo 框架自动根据系统或集群负载情况执行限流,相比用户预先设置限流值更加灵活方便,Dubbo 目前内置了自适应限流模式,具体可参见: |
| <ul> |
| <li><a href="../../../mannual/java-sdk/advanced-features-and-usage/performance/adaptive-concurrency-control/">Java 自适应限流使用方式</a></li> |
| <li><a href="../../../reference/proposals/heuristic-flow-control/">Go 自适应限流使用方式</a></li> |
| <li><a href="../../../reference/proposals/heuristic-flow-control/">自适应限流设计原理</a></li> |
| </ul> |
| </li> |
| </ul> |
| <h2 id="熔断降级">熔断降级</h2> |
| <p><strong>熔断降级则是更多的从 Dubbo 服务消费者视角来保障系统稳定性的重要手段</strong>。一个服务往往需要调用更多的下游 Dubbo 服务来完成业务逻辑,这时下游服务的稳定性就会影响当前服务甚至整个系统的稳定性,熔断(Circuit Breaking)即是面向不稳定服务场景设计的,它能最大限度避免下游服务不稳定对上游服务带来的影响。</p> |
| <p>而相比于熔断后直接返回调用失败信息,配合服务降级能力,我们可以继续调用预先设置好的服务降级逻辑,以降级逻辑的结果作为最终调用结果,以更优雅的返回给服务调用方。</p> |
| <p><img src="https://dubbo.apache.org/imgs/v3/feature/circuit-breaking/consumer-circuit-breaking.png" alt="consumer-circuit-breaking"></p> |
| <p>如上图所示,Dubbo Consumer 依赖的下游的三个 Dubbo 服务,当 Service 3 出现不稳定的情况时(如响应时间变长、错误率增加等),从而 Consumer 调用 Service 3 的线程等资源就会产生堆积,如果此时我们不在 Consumer 侧做任何限制,则 Service 1 与 Service 2 的调用都会受到稳定性影响。通过熔断 Service 3 我们就能保证整个 Dubbo Consumer 服务的稳定性,不拖垮整个 Consumer 服务,熔断 Service 3 的方式可以有很多种实现,包括线程数、信号量、错误率等。</p> |
| <p>Dubbo 通过集成业界主流的框架实现了服务熔断降级能力</p> |
| <ul> |
| <li><a href="../../../tasks/rate-limit/sentinel/">Sentinel</a></li> |
| <li><a href="../../../tasks/rate-limit/hystrix/">Hystrix</a></li> |
| <li><a href="../../../tasks/rate-limit/resilience4j/">Resilience4J</a></li> |
| </ul></description></item></channel></rss> |