This is an automated email from the ASF dual-hosted git repository.

github-bot pushed a commit to branch asf-site
in repository https://gitbox.apache.org/repos/asf/dubbo-website.git


The following commit(s) were added to refs/heads/asf-site by this push:
     new 6905928  Automated deployment: Sat Mar  7 16:23:13 UTC 2020 
1c41196ff38c31a49f925910510849921386112a
6905928 is described below

commit 6905928fccfcd7d0d62f96010d027e09e9cb8618
Author: lovepoem <lovep...@users.noreply.github.com>
AuthorDate: Sat Mar 7 16:23:13 2020 +0000

    Automated deployment: Sat Mar  7 16:23:13 UTC 2020 
1c41196ff38c31a49f925910510849921386112a
---
 build/blog.js                                      |   2 +-
 .../consistent-hash-balance-model.jpg              | Bin 0 -> 29205 bytes
 .../consistent-hash-delete-node-model.jpg          | Bin 0 -> 32314 bytes
 .../consistenthash/consistent-hash-init-model.jpg  | Bin 0 -> 29515 bytes
 .../consistent-hash-new-node-model.jpg             | Bin 0 -> 35015 bytes
 .../consistent-hash-request-model.jpg              | Bin 0 -> 34165 bytes
 .../consistent-hash-virtual-node-model.jpg         | Bin 0 -> 33019 bytes
 md_json/blog.json                                  |   9 ++
 .../blog/dubbo-consistent-hash-implementation.html |  96 +++++++++++++++++++++
 .../blog/dubbo-consistent-hash-implementation.json |  10 +++
 zh-cn/blog/index.html                              |   2 +-
 11 files changed, 117 insertions(+), 2 deletions(-)

diff --git a/build/blog.js b/build/blog.js
index dad8a76..c4d80e8 100644
--- a/build/blog.js
+++ b/build/blog.js
@@ -1,4 +1,4 @@
-!function(e){function t(r){if(n[r])return n[r].exports;var 
o=n[r]={i:r,l:!1,exports:{}};return 
e[r].call(o.exports,o,o.exports,t),o.l=!0,o.exports}var 
n={};t.m=e,t.c=n,t.i=function(e){return 
e},t.d=function(e,n,r){t.o(e,n)||Object.defineProperty(e,n,{configurable:!1,enumerable:!0,get:r})},t.n=function(e){var
 n=e&&e.__esModule?function(){return e.default}:function(){return e};return 
t.d(n,"a",n),n},t.o=function(e,t){return 
Object.prototype.hasOwnProperty.call(e,t)},t.p="/build/",t(t.s=317 [...]
+!function(e){function t(r){if(n[r])return n[r].exports;var 
o=n[r]={i:r,l:!1,exports:{}};return 
e[r].call(o.exports,o,o.exports,t),o.l=!0,o.exports}var 
n={};t.m=e,t.c=n,t.i=function(e){return 
e},t.d=function(e,n,r){t.o(e,n)||Object.defineProperty(e,n,{configurable:!1,enumerable:!0,get:r})},t.n=function(e){var
 n=e&&e.__esModule?function(){return e.default}:function(){return e};return 
t.d(n,"a",n),n},t.o=function(e,t){return 
Object.prototype.hasOwnProperty.call(e,t)},t.p="/build/",t(t.s=317 [...]
   Copyright (c) 2017 Jed Watson.
   Licensed under the MIT License (MIT), see
   http://jedwatson.github.io/classnames
diff --git a/img/blog/consistenthash/consistent-hash-balance-model.jpg 
b/img/blog/consistenthash/consistent-hash-balance-model.jpg
new file mode 100644
index 0000000..9bcee0c
Binary files /dev/null and 
b/img/blog/consistenthash/consistent-hash-balance-model.jpg differ
diff --git a/img/blog/consistenthash/consistent-hash-delete-node-model.jpg 
b/img/blog/consistenthash/consistent-hash-delete-node-model.jpg
new file mode 100644
index 0000000..a07e294
Binary files /dev/null and 
b/img/blog/consistenthash/consistent-hash-delete-node-model.jpg differ
diff --git a/img/blog/consistenthash/consistent-hash-init-model.jpg 
b/img/blog/consistenthash/consistent-hash-init-model.jpg
new file mode 100644
index 0000000..bcbbc00
Binary files /dev/null and 
b/img/blog/consistenthash/consistent-hash-init-model.jpg differ
diff --git a/img/blog/consistenthash/consistent-hash-new-node-model.jpg 
b/img/blog/consistenthash/consistent-hash-new-node-model.jpg
new file mode 100644
index 0000000..1af435b
Binary files /dev/null and 
b/img/blog/consistenthash/consistent-hash-new-node-model.jpg differ
diff --git a/img/blog/consistenthash/consistent-hash-request-model.jpg 
b/img/blog/consistenthash/consistent-hash-request-model.jpg
new file mode 100644
index 0000000..fb5f3d4
Binary files /dev/null and 
b/img/blog/consistenthash/consistent-hash-request-model.jpg differ
diff --git a/img/blog/consistenthash/consistent-hash-virtual-node-model.jpg 
b/img/blog/consistenthash/consistent-hash-virtual-node-model.jpg
new file mode 100644
index 0000000..b9de63d
Binary files /dev/null and 
b/img/blog/consistenthash/consistent-hash-virtual-node-model.jpg differ
diff --git a/md_json/blog.json b/md_json/blog.json
index 861d294..8e75d14 100644
--- a/md_json/blog.json
+++ b/md_json/blog.json
@@ -407,6 +407,15 @@
       }
     },
     {
+      "filename": "dubbo-consistent-hash-implementation.md",
+      "link": "/zh-cn/blog/dubbo-consistent-hash-implementation.html",
+      "meta": {
+        "title": "Dubbo一致性Hash负载均衡实现剖析",
+        "keywords": "Dubbo, Consistent Hash,一致性Hash,一致性哈希",
+        "description": "本文以一般的一致性Hash实现作为引子,详细剖析了Dubbo一致性Hash负载均衡算法的实现"
+      }
+    },
+    {
       "filename": "dubbo-context-information.md",
       "link": "/zh-cn/blog/dubbo-context-information.html",
       "meta": {
diff --git a/zh-cn/blog/dubbo-consistent-hash-implementation.html 
b/zh-cn/blog/dubbo-consistent-hash-implementation.html
new file mode 100644
index 0000000..be85f06
--- /dev/null
+++ b/zh-cn/blog/dubbo-consistent-hash-implementation.html
@@ -0,0 +1,96 @@
+<!DOCTYPE html>
+<html lang="en">
+
+<head>
+       <meta charset="UTF-8">
+       <meta name="viewport" content="width=device-width, initial-scale=1.0, 
maximum-scale=1.0, user-scalable=no">
+       <meta name="keywords" content="Dubbo, Consistent Hash,一致性Hash,一致性哈希" />
+       <meta name="description" 
content="本文以一般的一致性Hash实现作为引子,详细剖析了Dubbo一致性Hash负载均衡算法的实现" />
+       <!-- 网页标签标题 -->
+       <title>Dubbo一致性Hash负载均衡实现剖析</title>
+       <link rel="shortcut icon" href="/img/dubbo.ico"/>
+       <link rel="stylesheet" href="/build/blogDetail.css" />
+</head>
+<body>
+       <div id="root"><div class="blog-detail-page" data-reactroot=""><header 
class="header-container header-container-normal"><div class="header-body"><a 
href="/zh-cn/index.html"><img class="logo" 
src="/img/dubbo_colorful.png"/></a><div class="search search-normal"><span 
class="icon-search"></span></div><span class="language-switch 
language-switch-normal">En</span><div class="header-menu"><img 
class="header-menu-toggle" src="/img/menu_gray.png"/><ul><li class="menu-item 
menu-item-normal"><a h [...]
+<h3>一、环形队列Hash映射模型</h3>
+<p>这种方案,其基础还是基于取模运算。对2^32取模,那么,Hash值的区间为[0, 2^32-1]。接下来要做的,就包括两部分:</p>
+<h4><strong>a、映射服务</strong></h4>
+<p>将服务地址(ip+端口)按照一定规则构造出特定的识别码(如md5码),再用识别码对2^32取模,确定服务在Hash值区间对应的位置。假设有Node1、Node2、Node3三个服务,其映射关系如下:</p>
+<p><img src="../../img/blog/consistenthash/consistent-hash-init-model.jpg" 
alt="Init"></p>
+<h4><strong>b、映射请求、定位服务</strong></h4>
+<p>在发起请求时,我们往往会带上参数,而这些参数,就可以被我们用来确定具体调用哪一个服务。假设有请求R1、R2、R3,对它们的参数也经过计算特定识别码、取余的一系列运算之后,有如下映射关系:</p>
+<p><img src="../../img/blog/consistenthash/consistent-hash-request-model.jpg" 
alt="Request"></p>
+<p>从图中,我们可以看到,R1请求映射在0-Node1中间,R2请求映射在Node1-Node2中间,R3请求映射在Node2-Node3中间。我们取<strong>服务Hash值大于请求Hash值</strong>的<strong>第一个服务</strong>作为实际的调用服务。也就是说,R1请求将调用Node1服务,R2请求将调用Node2服务,R3请求将调用Node3服务。</p>
+<h4><strong>c、新增服务节点</strong></h4>
+<p>假设新增服务Node4,映射在Node3之前,恰巧破坏了原来的一个映射关系:</p>
+<p><img src="../../img/blog/consistenthash/consistent-hash-new-node-model.jpg" 
alt="New Node"></p>
+<p>这样,请求R3将会实际调用服务Node4,但请求R1、R2不受影响。</p>
+<h4><strong>d、删除服务节点</strong></h4>
+<p>假设服务Node2宕机,那么R2请求将会映射到Node3:</p>
+<p><img 
src="../../img/blog/consistenthash/consistent-hash-delete-node-model.jpg" 
alt="Delete Node"></p>
+<p>原本的R1、R3请求不受影响。</p>
+<blockquote>
+<p>可以看出,当新增、删除服务时,受影响的请求是有限的。不至于像简单取模映射一般,服务发生变化时,需要调整全局的映射关系。</p>
+</blockquote>
+<h4><strong>e、平衡性与虚拟节点</strong></h4>
+<p>在我们上面的假设中,我们假设Node1、Node2、Node3三个服务在经过Hash映射后所分布的位置恰巧把环切成了均等的三分,请求的分布也基本是平衡的。但是实际上计算服务Hash值的时候,是很难这么巧的。也许一不小心就映射成了这个样子:</p>
+<p><img src="../../img/blog/consistenthash/consistent-hash-balance-model.jpg" 
alt="Balance"></p>
+<p>这样,就会导致大部分请求都会被映射到Node1上。因此,引出了虚拟节点。</p>
+<p>所谓虚拟节点,就是除了对服务本身地址进行Hash映射外,还通过在它地址上做些处理(比如Dubbo中,在ip+port的字符串后加上计数符1、2、3......,分别代表虚拟节点1、2、3),以达到同一服务映射多个节点的目的。通过引入虚拟节点,我们可以把上图中映射给Node1的请求进一步拆分:</p>
+<p><img 
src="../../img/blog/consistenthash/consistent-hash-virtual-node-model.jpg" 
alt="Virtual Node"></p>
+<p>如上图所示,若有请求落在Node3-Node1'区间,该请求应该是调用Node1'服务,但是因为Node1'是Node1的虚拟节点,所以实际调用的是Node1服务。通过引入虚拟节点,请求的分布就会比较平衡了。</p>
+<h3><strong>二、Dubbo一致性Hash的使用与负载均衡策略的引入阶段</strong></h3>
+<h4><strong>a、如何使用一致性Hash作为Dubbo的负载均衡策略?</strong></h4>
+<p>dubbo:service、dubbo:reference、dubbo:provider、dubbo:consumer、dubbo:method这几个配置项都可以配置Dubbo的负载均衡策略,其中一致性Hash的属性值是:<strong>consistenthash</strong>。</p>
+<p>以dubbo:reference为例:</p>
+<p><strong>XML配置:</strong></p>
+<blockquote>
+<p>&lt;dubbo:reference loadbalance=&quot;consistenthash&quot; /&gt;</p>
+</blockquote>
+<p><strong>Properties配置:</strong></p>
+<blockquote>
+<p>dubbo.reference.loadbalance=consistenthash</p>
+</blockquote>
+<p><strong>注解:</strong></p>
+<blockquote>
+<p>@Reference(loadbalance = &quot;consistenthash&quot;)</p>
+</blockquote>
+<h4><strong>b、Dubbo负载均衡策略的引入阶段</strong></h4>
+<p>Dubbo实现的是客户端负载均衡。关于服务接口代理类的实现,这里不做详细描述,可以参考官网:</p>
+<blockquote>
+<p>服务引入:<a 
href="http://dubbo.apache.org/zh-cn/docs/source_code_guide/refer-service.html%E3%80%82";>http://dubbo.apache.org/zh-cn/docs/source_code_guide/refer-service.html。</a></p>
+</blockquote>
+<p>在接口代理类生成、并且装配好后,服务的调用基本是这样一个流程:proxy -&gt; MockClusterInvoker -&gt; 
集群策略(如:FailoverClusterInvoker) -&gt; 根据选定的负载均衡策略确定选定的远程调用对象Invoker。</p>
+<p><strong>负载均衡策略的初始化</strong>是在AbstractClusterInvoker中的initLoadBalance方法中初始化的:</p>
+<pre><code class="language-java"><span class="hljs-function"><span 
class="hljs-keyword">protected</span> LoadBalance <span 
class="hljs-title">initLoadBalance</span><span 
class="hljs-params">(List&lt;Invoker&lt;T&gt;&gt; invokers, Invocation 
invocation)</span> </span>{
+    <span class="hljs-keyword">if</span> 
(CollectionUtils.isNotEmpty(invokers)) {
+        <span class="hljs-keyword">return</span> 
ExtensionLoader.getExtensionLoader(LoadBalance<span class="hljs-class">.<span 
class="hljs-keyword">class</span>).<span 
class="hljs-title">getExtension</span>(<span 
class="hljs-title">invokers</span>.<span class="hljs-title">get</span>(0).<span 
class="hljs-title">getUrl</span>()
+                .<span class="hljs-title">getMethodParameter</span>(<span 
class="hljs-title">RpcUtils</span>.<span 
class="hljs-title">getMethodName</span>(<span 
class="hljs-title">invocation</span>), <span 
class="hljs-title">LOADBALANCE_KEY</span>, <span 
class="hljs-title">DEFAULT_LOADBALANCE</span>))</span>;
+    } <span class="hljs-keyword">else</span> {
+        <span class="hljs-keyword">return</span> 
ExtensionLoader.getExtensionLoader(LoadBalance<span class="hljs-class">.<span 
class="hljs-keyword">class</span>).<span 
class="hljs-title">getExtension</span>(<span 
class="hljs-title">DEFAULT_LOADBALANCE</span>)</span>;
+    }
+}
+</code></pre>
+<p>这部分代码逻辑分为两部分:</p>
+<p>1、获取调用方法所配置的LOADBALANCE_KEY属性的值,LOADBALANCE_KEY这个常量的实际值为:loadbalance,即为我们的所配置的属性;</p>
+<p>2、利用SPI机制来初始化并加载该值所代表的负载均衡策略。</p>
+<p>所有的负载均衡策略都会继承LoadBalance接口。在各种集群策略中,最终都会调用AbstractClusterInvoker的select方法,而AbstractClusterInvoker会在doSelect中,<strong>调用LoadBalance的select方法,这里即开始了负载均衡策略的执行。</strong></p>
+</section><footer class="footer-container"><div class="footer-body"><img 
src="/img/dubbo_gray.png"/><img class="apache" src="/img/apache_logo.png"/><div 
class="cols-container"><div class="col col-12"><h3></h3><p></p></div><div 
class="col col-4"><dl><dt>ASF</dt><dd><a href="http://www.apache.org"; 
target="_self">基金会</a></dd><dd><a href="http://www.apache.org/licenses/"; 
target="_self">证书</a></dd><dd><a 
href="http://www.apache.org/events/current-event"; 
target="_self">事件</a></dd><dd><a href=" [...]
+       <script 
src="https://f.alicdn.com/react/15.4.1/react-with-addons.min.js";></script>
+       <script 
src="https://f.alicdn.com/react/15.4.1/react-dom.min.js";></script>
+       <script>
+               window.rootPath = '';
+  </script>
+  <script src="/build/blogDetail.js"></script>
+  <!-- Global site tag (gtag.js) - Google Analytics -->
+       <script async 
src="https://www.googletagmanager.com/gtag/js?id=UA-112489517-1";></script>
+       <script>
+               window.dataLayer = window.dataLayer || [];
+               function gtag(){dataLayer.push(arguments);}
+               gtag('js', new Date());
+
+               gtag('config', 'UA-112489517-1');
+       </script>
+</body>
+</html>
\ No newline at end of file
diff --git a/zh-cn/blog/dubbo-consistent-hash-implementation.json 
b/zh-cn/blog/dubbo-consistent-hash-implementation.json
new file mode 100644
index 0000000..4b99bfc
--- /dev/null
+++ b/zh-cn/blog/dubbo-consistent-hash-implementation.json
@@ -0,0 +1,10 @@
+{
+  "filename": "dubbo-consistent-hash-implementation.md",
+  "__html": 
"<p>需要强调的是,Dubbo的Hash映射模型与大部分网上资料描述的<strong>环形队列Hash映射模型</strong>是存在一些区别的。于我而言,环形队列Hash映射模型,不足以让我对一致性Hash有足够彻底的了解。直到看懂了Dubbo的一致性Hash的实现,才觉得豁然开朗。</p>\n<h3>一、环形队列Hash映射模型</h3>\n<p>这种方案,其基础还是基于取模运算。对2^32取模,那么,Hash值的区间为[0,
 
2^32-1]。接下来要做的,就包括两部分:</p>\n<h4><strong>a、映射服务</strong></h4>\n<p>将服务地址(ip+端口)按照一定规则构造出特定的识别码(如md5码),再用识别码对2^32取模,确定服务在Hash值区间对应的位置。假设有Node1、Node2、Node3三个服务,其映射关系如下:</p>\n<p><img
 src=\"../../img/blog/consistenthash/consistent-hash-init-model.jpg\" 
alt=\"Init\">< [...]
+  "link": "/zh-cn/blog/dubbo-consistent-hash-implementation.html",
+  "meta": {
+    "title": "Dubbo一致性Hash负载均衡实现剖析",
+    "keywords": "Dubbo, Consistent Hash,一致性Hash,一致性哈希",
+    "description": "本文以一般的一致性Hash实现作为引子,详细剖析了Dubbo一致性Hash负载均衡算法的实现"
+  }
+}
\ No newline at end of file
diff --git a/zh-cn/blog/index.html b/zh-cn/blog/index.html
index 0f2e582..ea6de38 100644
--- a/zh-cn/blog/index.html
+++ b/zh-cn/blog/index.html
@@ -12,7 +12,7 @@
        <link rel="stylesheet" href="/build/blog.css" />
 </head>
 <body>
-       <div id="root"><div class="blog-list-page" data-reactroot=""><header 
class="header-container header-container-normal"><div class="header-body"><a 
href="/zh-cn/index.html"><img class="logo" 
src="/img/dubbo_colorful.png"/></a><div class="search search-normal"><span 
class="icon-search"></span></div><span class="language-switch 
language-switch-normal">En</span><div class="header-menu"><img 
class="header-menu-toggle" src="/img/menu_gray.png"/><ul><li class="menu-item 
menu-item-normal"><a hre [...]
+       <div id="root"><div class="blog-list-page" data-reactroot=""><header 
class="header-container header-container-normal"><div class="header-body"><a 
href="/zh-cn/index.html"><img class="logo" 
src="/img/dubbo_colorful.png"/></a><div class="search search-normal"><span 
class="icon-search"></span></div><span class="language-switch 
language-switch-normal">En</span><div class="header-menu"><img 
class="header-menu-toggle" src="/img/menu_gray.png"/><ul><li class="menu-item 
menu-item-normal"><a hre [...]
        <script 
src="https://f.alicdn.com/react/15.4.1/react-with-addons.min.js";></script>
        <script 
src="https://f.alicdn.com/react/15.4.1/react-dom.min.js";></script>
        <script>

Reply via email to