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

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

commit 57ace46955ac506c82098ee0405125be8ccb0c08
Author: Huxing Zhang <[email protected]>
AuthorDate: Wed Dec 12 13:16:40 2018 +0800

    Publish website.
---
 build/blog.js                                      |   6 +-
 build/blogDetail.js                                |   6 +-
 build/community.js                                 |   6 +-
 build/documentation.js                             |   6 +-
 build/home.js                                      |   6 +-
 md_json/blog.json                                  |  43 ++++
 zh-cn/blog/apachecon-na-2018.html                  |  34 +++
 zh-cn/blog/apachecon-na-2018.json                  |   6 +
 zh-cn/blog/dubbo-cluster-error-handling.html       | 232 +++++++++++++++++++++
 zh-cn/blog/dubbo-cluster-error-handling.json       |  10 +
 zh-cn/blog/dubbo-meetup-beijing-may-12th-2018.html |  41 ++++
 zh-cn/blog/dubbo-meetup-beijing-may-12th-2018.json |  10 +
 zh-cn/blog/first-dubbo-filter.html                 | 183 ++++++++++++++++
 zh-cn/blog/first-dubbo-filter.json                 |   6 +
 zh-cn/blog/index.html                              |   2 +-
 zh-cn/blog/qcon-beijing-2018.html                  |  34 +++
 zh-cn/blog/qcon-beijing-2018.json                  |   6 +
 zh-cn/blog/service-and-version.html                | 213 +++++++++++++++++++
 zh-cn/blog/service-and-version.json                |   6 +
 zh-cn/blog/test-verification.html                  | 111 ++++++++++
 zh-cn/blog/test-verification.json                  |   6 +
 zh-cn/docs/admin/install/admin-console.html        |  20 +-
 zh-cn/docs/admin/install/admin-console.json        |   2 +-
 23 files changed, 977 insertions(+), 18 deletions(-)

diff --git a/build/blog.js b/build/blog.js
index d4f01a5..98a7e59 100644
--- a/build/blog.js
+++ b/build/blog.js
@@ -1,6 +1,6 @@
-!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=78) [...]
-  Copyright (c) 2017 Jed Watson.
+!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=80) [...]
+  Copyright (c) 2016 Jed Watson.
   Licensed under the MIT License (MIT), see
   http://jedwatson.github.io/classnames
 */
-!function(){"use strict";function n(){for(var 
e=[],t=0;t<arguments.length;t++){var r=arguments[t];if(r){var o=typeof 
r;if("string"===o||"number"===o)e.push(r);else 
if(Array.isArray(r)&&r.length){var a=n.apply(null,r);a&&e.push(a)}else 
if("object"===o)for(var u in r)i.call(r,u)&&r[u]&&e.push(u)}}return e.join(" 
")}var i={}.hasOwnProperty;void 
0!==e&&e.exports?(n.default=n,e.exports=n):(r=[],void 0!==(o=function(){return 
n}.apply(t,r))&&(e.exports=o))}()},function(e,t,n){"use strict";funct [...]
\ No newline at end of file
+!function(){"use strict";function n(){for(var 
e=[],t=0;t<arguments.length;t++){var r=arguments[t];if(r){var o=typeof 
r;if("string"===o||"number"===o)e.push(r);else 
if(Array.isArray(r))e.push(n.apply(null,r));else if("object"===o)for(var a in 
r)i.call(r,a)&&r[a]&&e.push(a)}}return e.join(" ")}var i={}.hasOwnProperty;void 
0!==e&&e.exports?e.exports=n:(r=[],void 0!==(o=function(){return 
n}.apply(t,r))&&(e.exports=o))}()},function(e,t,n){"use strict";function 
r(e,t,r){var o=r.configurable,u= [...]
\ No newline at end of file
diff --git a/build/blogDetail.js b/build/blogDetail.js
index ec5b66b..d737c9f 100644
--- a/build/blogDetail.js
+++ b/build/blogDetail.js
@@ -1,6 +1,6 @@
-!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=79) [...]
-  Copyright (c) 2017 Jed Watson.
+!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=81) [...]
+  Copyright (c) 2016 Jed Watson.
   Licensed under the MIT License (MIT), see
   http://jedwatson.github.io/classnames
 */
-!function(){"use strict";function n(){for(var 
e=[],t=0;t<arguments.length;t++){var r=arguments[t];if(r){var o=typeof 
r;if("string"===o||"number"===o)e.push(r);else 
if(Array.isArray(r)&&r.length){var a=n.apply(null,r);a&&e.push(a)}else 
if("object"===o)for(var u in r)i.call(r,u)&&r[u]&&e.push(u)}}return e.join(" 
")}var i={}.hasOwnProperty;void 
0!==e&&e.exports?(n.default=n,e.exports=n):(r=[],void 0!==(o=function(){return 
n}.apply(t,r))&&(e.exports=o))}()},function(e,t,n){"use strict";funct [...]
\ No newline at end of file
+!function(){"use strict";function n(){for(var 
e=[],t=0;t<arguments.length;t++){var r=arguments[t];if(r){var o=typeof 
r;if("string"===o||"number"===o)e.push(r);else 
if(Array.isArray(r))e.push(n.apply(null,r));else if("object"===o)for(var a in 
r)i.call(r,a)&&r[a]&&e.push(a)}}return e.join(" ")}var i={}.hasOwnProperty;void 
0!==e&&e.exports?e.exports=n:(r=[],void 0!==(o=function(){return 
n}.apply(t,r))&&(e.exports=o))}()},function(e,t,n){"use strict";function 
r(e,t,r){var o=r.configurable,u= [...]
\ No newline at end of file
diff --git a/build/community.js b/build/community.js
index 4704938..9b45e1b 100644
--- a/build/community.js
+++ b/build/community.js
@@ -1,6 +1,6 @@
-!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=80) [...]
-  Copyright (c) 2017 Jed Watson.
+!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=82) [...]
+  Copyright (c) 2016 Jed Watson.
   Licensed under the MIT License (MIT), see
   http://jedwatson.github.io/classnames
 */
-!function(){"use strict";function n(){for(var 
e=[],t=0;t<arguments.length;t++){var r=arguments[t];if(r){var o=typeof 
r;if("string"===o||"number"===o)e.push(r);else 
if(Array.isArray(r)&&r.length){var a=n.apply(null,r);a&&e.push(a)}else 
if("object"===o)for(var l in r)i.call(r,l)&&r[l]&&e.push(l)}}return e.join(" 
")}var i={}.hasOwnProperty;void 
0!==e&&e.exports?(n.default=n,e.exports=n):(r=[],void 0!==(o=function(){return 
n}.apply(t,r))&&(e.exports=o))}()},function(e,t,n){"use strict";funct [...]
\ No newline at end of file
+!function(){"use strict";function n(){for(var 
e=[],t=0;t<arguments.length;t++){var r=arguments[t];if(r){var o=typeof 
r;if("string"===o||"number"===o)e.push(r);else 
if(Array.isArray(r))e.push(n.apply(null,r));else if("object"===o)for(var a in 
r)i.call(r,a)&&r[a]&&e.push(a)}}return e.join(" ")}var i={}.hasOwnProperty;void 
0!==e&&e.exports?e.exports=n:(r=[],void 0!==(o=function(){return 
n}.apply(t,r))&&(e.exports=o))}()},function(e,t,n){"use strict";function 
r(e,t,r){var o=r.configurable,l= [...]
\ No newline at end of file
diff --git a/build/documentation.js b/build/documentation.js
index b1330c7..6637d67 100644
--- a/build/documentation.js
+++ b/build/documentation.js
@@ -1,6 +1,6 @@
-!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=81) [...]
-  Copyright (c) 2017 Jed Watson.
+!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=83) [...]
+  Copyright (c) 2016 Jed Watson.
   Licensed under the MIT License (MIT), see
   http://jedwatson.github.io/classnames
 */
-!function(){"use strict";function n(){for(var 
e=[],t=0;t<arguments.length;t++){var r=arguments[t];if(r){var o=typeof 
r;if("string"===o||"number"===o)e.push(r);else 
if(Array.isArray(r)&&r.length){var l=n.apply(null,r);l&&e.push(l)}else 
if("object"===o)for(var a in r)i.call(r,a)&&r[a]&&e.push(a)}}return e.join(" 
")}var i={}.hasOwnProperty;void 
0!==e&&e.exports?(n.default=n,e.exports=n):(r=[],void 0!==(o=function(){return 
n}.apply(t,r))&&(e.exports=o))}()},function(e,t,n){"use strict";funct [...]
\ No newline at end of file
+!function(){"use strict";function n(){for(var 
e=[],t=0;t<arguments.length;t++){var r=arguments[t];if(r){var o=typeof 
r;if("string"===o||"number"===o)e.push(r);else 
if(Array.isArray(r))e.push(n.apply(null,r));else if("object"===o)for(var l in 
r)i.call(r,l)&&r[l]&&e.push(l)}}return e.join(" ")}var i={}.hasOwnProperty;void 
0!==e&&e.exports?e.exports=n:(r=[],void 0!==(o=function(){return 
n}.apply(t,r))&&(e.exports=o))}()},function(e,t,n){"use strict";function 
r(e,t,r){var o=r.configurable,a= [...]
\ No newline at end of file
diff --git a/build/home.js b/build/home.js
index d580bc6..cbb9bf5 100644
--- a/build/home.js
+++ b/build/home.js
@@ -1,6 +1,6 @@
-!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=82) [...]
-  Copyright (c) 2017 Jed Watson.
+!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=84) [...]
+  Copyright (c) 2016 Jed Watson.
   Licensed under the MIT License (MIT), see
   http://jedwatson.github.io/classnames
 */
-!function(){"use strict";function n(){for(var 
e=[],t=0;t<arguments.length;t++){var r=arguments[t];if(r){var o=typeof 
r;if("string"===o||"number"===o)e.push(r);else 
if(Array.isArray(r)&&r.length){var i=n.apply(null,r);i&&e.push(i)}else 
if("object"===o)for(var u in r)a.call(r,u)&&r[u]&&e.push(u)}}return e.join(" 
")}var a={}.hasOwnProperty;void 
0!==e&&e.exports?(n.default=n,e.exports=n):(r=[],void 0!==(o=function(){return 
n}.apply(t,r))&&(e.exports=o))}()},function(e,t,n){"use strict";funct [...]
\ No newline at end of file
+!function(){"use strict";function n(){for(var 
e=[],t=0;t<arguments.length;t++){var r=arguments[t];if(r){var o=typeof 
r;if("string"===o||"number"===o)e.push(r);else 
if(Array.isArray(r))e.push(n.apply(null,r));else if("object"===o)for(var i in 
r)a.call(r,i)&&r[i]&&e.push(i)}}return e.join(" ")}var a={}.hasOwnProperty;void 
0!==e&&e.exports?e.exports=n:(r=[],void 0!==(o=function(){return 
n}.apply(t,r))&&(e.exports=o))}()},function(e,t,n){"use strict";function 
r(e,t,r){var o=r.configurable,u= [...]
\ No newline at end of file
diff --git a/md_json/blog.json b/md_json/blog.json
index 12d642c..cd02a27 100644
--- a/md_json/blog.json
+++ b/md_json/blog.json
@@ -202,6 +202,11 @@
   ],
   "zh-cn": [
     {
+      "filename": "apachecon-na-2018.md",
+      "link": "/zh-cn/blog/apachecon-na-2018.html",
+      "meta": {}
+    },
+    {
       "filename": "download.md",
       "link": "/zh-cn/blog/download.html",
       "meta": {}
@@ -234,6 +239,15 @@
       }
     },
     {
+      "filename": "dubbo-cluster-error-handling.md",
+      "link": "/zh-cn/blog/dubbo-cluster-error-handling.html",
+      "meta": {
+        "title": "Dubbo集群容错",
+        "keywords": "Dubbo, RPC, cluster, Error-handling",
+        "description": 
"在分布式系统中,集群某个某些节点出现问题是大概率事件,因此在设计分布式RPC框架的过程中,必须要把失败作为设计的一等公民来对待。一次调用失败之后,应该如何选择对失败的选择策略,这是一个见仁见智的问题,每种策略可能都有自己独特的应用场景。因此,作为框架来说,应当针对不同场景提供多种策略,供用户进行选择。本文介绍了Dubbo框架提供的多种错误处理策略,并通过实例说明如何进行配置。"
+      }
+    },
+    {
       "filename": "dubbo-compatible.md",
       "link": "/zh-cn/blog/dubbo-compatible.html",
       "meta": {
@@ -297,6 +311,15 @@
       }
     },
     {
+      "filename": "dubbo-meetup-beijing-may-12th-2018.md",
+      "link": "/zh-cn/blog/dubbo-meetup-beijing-may-12th-2018.html",
+      "meta": {
+        "title": "首届Dubbo开发者沙龙在北京成功举办",
+        "keywords": "Dubbo, Beijing, meetup",
+        "description": "首届Dubbo开发者沙龙在北京成功举办"
+      }
+    },
+    {
       "filename": "dubbo-meetup-chengdu.md",
       "link": "/zh-cn/blog/dubbo-meetup-chengdu.html",
       "meta": {
@@ -369,6 +392,11 @@
       }
     },
     {
+      "filename": "first-dubbo-filter.md",
+      "link": "/zh-cn/blog/first-dubbo-filter.html",
+      "meta": {}
+    },
+    {
       "filename": "how-to-involve-dubbo-community.md",
       "link": "/zh-cn/blog/how-to-involve-dubbo-community.html",
       "meta": {
@@ -438,6 +466,11 @@
       }
     },
     {
+      "filename": "qcon-beijing-2018.md",
+      "link": "/zh-cn/blog/qcon-beijing-2018.html",
+      "meta": {}
+    },
+    {
       "filename": "sentinel-introduction-for-dubbo.md",
       "link": "/zh-cn/blog/sentinel-introduction-for-dubbo.html",
       "meta": {
@@ -447,6 +480,11 @@
       }
     },
     {
+      "filename": "service-and-version.md",
+      "link": "/zh-cn/blog/service-and-version.html",
+      "meta": {}
+    },
+    {
       "filename": "spring-boot-dubbo-start-stop-analysis.md",
       "link": "/zh-cn/blog/spring-boot-dubbo-start-stop-analysis.html",
       "meta": {
@@ -456,6 +494,11 @@
       }
     },
     {
+      "filename": "test-verification.md",
+      "link": "/zh-cn/blog/test-verification.html",
+      "meta": {}
+    },
+    {
       "filename": "tracing-with-skywalking.md",
       "link": "/zh-cn/blog/tracing-with-skywalking.html",
       "meta": {
diff --git a/zh-cn/blog/apachecon-na-2018.html 
b/zh-cn/blog/apachecon-na-2018.html
new file mode 100644
index 0000000..6104fa9
--- /dev/null
+++ b/zh-cn/blog/apachecon-na-2018.html
@@ -0,0 +1,34 @@
+<!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="apachecon-na-2018" />
+       <meta name="description" content="apachecon-na-2018" />
+       <!-- 网页标签标题 -->
+       <title>apachecon-na-2018</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 [...]
+<p>罗毅/刘军将在蒙特利尔举办的 ApacheCon 大会上进行题为&quot;Introducing Apache Dubbo(Incubating): 
What is Dubbo and How it Works&quot;的演讲。请点击<a 
href="https://apachecon.dukecon.org/acna/2018/#/scheduledEvent/b8db9dc580d85853f";>此处</a>查看大会议程,并在<a
 
href="https://www.eventbrite.com/e/apachecon-north-america-2018-registration-43200327342";>此处</a>中进行注册。</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>Disclaimer</h3><p>Apache 
Dubbo is an effort undergoing incubation at The Apache Software Foundation 
(ASF), sponsored by the Incubator. Incubation is required of all newly accepted 
projects until a further review indicates that the infrastructure, 
communications, and decision making proce [...]
+       <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/apachecon-na-2018.json 
b/zh-cn/blog/apachecon-na-2018.json
new file mode 100644
index 0000000..0344e80
--- /dev/null
+++ b/zh-cn/blog/apachecon-na-2018.json
@@ -0,0 +1,6 @@
+{
+  "filename": "apachecon-na-2018.md",
+  "__html": "<h2>ApacheCon大会议程公布</h2>\n<p>罗毅/刘军将在蒙特利尔举办的 ApacheCon 
大会上进行题为&quot;Introducing Apache Dubbo(Incubating): What is Dubbo and How it 
Works&quot;的演讲。请点击<a 
href=\"https://apachecon.dukecon.org/acna/2018/#/scheduledEvent/b8db9dc580d85853f\";>此处</a>查看大会议程,并在<a
 
href=\"https://www.eventbrite.com/e/apachecon-north-america-2018-registration-43200327342\";>此处</a>中进行注册。</p>\n",
+  "link": "/zh-cn/blog/apachecon-na-2018.html",
+  "meta": {}
+}
\ No newline at end of file
diff --git a/zh-cn/blog/dubbo-cluster-error-handling.html 
b/zh-cn/blog/dubbo-cluster-error-handling.html
new file mode 100644
index 0000000..ec48a71
--- /dev/null
+++ b/zh-cn/blog/dubbo-cluster-error-handling.html
@@ -0,0 +1,232 @@
+<!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, RPC, cluster, Error-handling" />
+       <meta name="description" 
content="在分布式系统中,集群某个某些节点出现问题是大概率事件,因此在设计分布式RPC框架的过程中,必须要把失败作为设计的一等公民来对待。一次调用失败之后,应该如何选择对失败的选择策略,这是一个见仁见智的问题,每种策略可能都有自己独特的应用场景。因此,作为框架来说,应当针对不同场景提供多种策略,供用户进行选择。本文介绍了Dubbo框架提供的多种错误处理策略,并通过实例说明如何进行配置。"
 />
+       <!-- 网页标签标题 -->
+       <title>Dubbo集群容错</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 [...]
+<p>在分布式系统中,集群某个某些节点出现问题是大概率事件,因此在设计分布式RPC框架的过程中,必须要把失败作为设计的一等公民来对待。一次调用失败之后,应该如何选择对失败的选择策略,这是一个见仁见智的问题,每种策略可能都有自己独特的应用场景。因此,作为框架来说,应当针对不同场景提供多种策略,供用户进行选择。</p>
+<p>在Dubbo设计中,通过Cluster这个接口的抽象,把一组可供调用的Provider信息组合成为一个统一的<code>Invoker</code>供调用方进行调用。经过路由规则过滤,负载均衡选址后,选中一个具体地址进行调用,如果调用失败,则会按照集群配置的容错策略进行容错处理。</p>
+<p>Dubbo默认内置了若干容错策略,如果不能满足用户需求,则可以通过自定义容错策略进行配置。</p>
+<h3>内置容错策略</h3>
+<p>Dubbo主要内置了如下几种策略:</p>
+<ul>
+<li>Failover(失败自动切换)</li>
+<li>Failsafe(失败安全)</li>
+<li>Failfast(快速失败)</li>
+<li>Failback(失败自动恢复)</li>
+<li>Forking(并行调用)</li>
+<li>Broadcast(广播调用)</li>
+</ul>
+<p>这些名称比较相似,概念也比较容易混淆,下面逐一进行解释。</p>
+<h4>Failover(失败自动切换)</h4>
+<p><code>Failover</code>是高可用系统中的一个常用概念,服务器通常拥有主备两套机器配置,如果主服务器出现故障,则自动切换到备服务器中,从而保证了整体的高可用性。</p>
+<p>Dubbo也借鉴了这个思想,并且把它作为Dubbo<code>默认的容错策略</code>。当调用出现失败的时候,根据配置的重试次数,会自动从其他可用地址中重新选择一个可用的地址进行调用,直到调用成功,或者是达到重试的上限位置。</p>
+<p>Dubbo里默认配置的重试次数是2,也就是说,算上第一次调用,最多会调用3次。</p>
+<p>其配置方法,容错策略既可以在服务提供方配置,也可以服务调用方进行配置。而重试次数的配置则更为灵活,既可以在服务级别进行配置,也可以在方法级别进行配置。具体优先顺序为:</p>
+<pre><code>服务调用方方法级配置 &gt; 服务调用方服务级配置 &gt; 服务提供方方法级配置 &gt; 服务提供方服务级配置
+</code></pre>
+<p>以XML方式为例,具体配置方法如下:</p>
+<p>服务提供方,服务级配置</p>
+<pre><code class="language-xml"><span class="hljs-tag">&lt;<span 
class="hljs-name">dubbo:service</span> <span 
class="hljs-attr">interface</span>=<span 
class="hljs-string">"org.apache.dubbo.demo.DemoService"</span> <span 
class="hljs-attr">ref</span>=<span class="hljs-string">"demoService"</span> 
<span class="hljs-attr">cluster</span>=<span 
class="hljs-string">"failover"</span> <span 
class="hljs-attr">retries</span>=<span class="hljs-string">"2"</span> 
/&gt;</span>
+</code></pre>
+<p>服务提供方,方法级配置</p>
+<pre><code class="language-xml"><span class="hljs-tag">&lt;<span 
class="hljs-name">dubbo:service</span> <span 
class="hljs-attr">interface</span>=<span 
class="hljs-string">"org.apache.dubbo.demo.DemoService"</span> <span 
class="hljs-attr">ref</span>=<span 
class="hljs-string">"demoService"</span><span 
class="hljs-attr">cluster</span>=<span 
class="hljs-string">"failover"</span>&gt;</span>
+     <span class="hljs-tag">&lt;<span class="hljs-name">dubbo:method</span> 
<span class="hljs-attr">name</span>=<span class="hljs-string">"sayHello"</span> 
<span class="hljs-attr">retries</span>=<span class="hljs-string">"2"</span> 
/&gt;</span>
+ <span class="hljs-tag">&lt;/<span 
class="hljs-name">dubbo:reference</span>&gt;</span>
+</code></pre>
+<p>服务调用方,服务级配置</p>
+<pre><code class="language-xml"><span class="hljs-tag">&lt;<span 
class="hljs-name">dubbo:reference</span> <span 
class="hljs-attr">id</span>=<span class="hljs-string">"demoService"</span> 
<span class="hljs-attr">interface</span>=<span 
class="hljs-string">"org.apache.dubbo.demo.DemoService"</span> <span 
class="hljs-attr">cluster</span>=<span class="hljs-string">"failover"</span> 
<span class="hljs-attr">retries</span>=<span 
class="hljs-string">"1"</span>/&gt;</span>
+</code></pre>
+<p>服务调用方,方法级配置:</p>
+<pre><code class="language-xml"> <span class="hljs-tag">&lt;<span 
class="hljs-name">dubbo:reference</span> <span 
class="hljs-attr">id</span>=<span class="hljs-string">"demoService"</span> 
<span class="hljs-attr">interface</span>=<span 
class="hljs-string">"org.apache.dubbo.demo.DemoService"</span> <span 
class="hljs-attr">cluster</span>=<span 
class="hljs-string">"failover"</span>&gt;</span>
+     <span class="hljs-tag">&lt;<span class="hljs-name">dubbo:method</span> 
<span class="hljs-attr">name</span>=<span class="hljs-string">"sayHello"</span> 
<span class="hljs-attr">retries</span>=<span class="hljs-string">"3"</span> 
/&gt;</span>
+ <span class="hljs-tag">&lt;/<span 
class="hljs-name">dubbo:reference</span>&gt;</span>
+</code></pre>
+<p>Failover可以自动对失败进行重试,对调用者屏蔽了失败的细节,但是Failover策略也会带来一些副作用:</p>
+<ul>
+<li>重试会额外增加一下开销,例如增加资源的使用,在高负载系统下,额外的重试可能让系统雪上加霜。</li>
+<li>重试会增加调用的响应时间。</li>
+<li>某些情况下,重试甚至会造成资源的浪费。考虑一个调用场景,A-&gt;B-&gt;C,如果A处设置了超时100ms,再B-&gt;C的第一次调用完成时已经超过了100ms,但很不幸B-&gt;C失败,这时候会进行重试,但其实这时候重试已经没有意义,因此在A看来这次调用已经超时,A可能已经开始执行其他逻辑。</li>
+</ul>
+<h4>Failsafe(失败安全)</h4>
+<p>失败安全策略的核心是即使失败了也不会影响整个调用流程。通常情况下用于旁路系统或流程中,它的失败不影响核心业务的正确性。在实现上,当出现调用失败时,会忽略此错误,并记录一条日志,同时返回一个空结果,在上游看来调用是成功的。</p>
+<p>应用场景,可以用于写入审计日志等操作。</p>
+<p>具体配置方法:</p>
+<p>服务提供方,服务级配置</p>
+<pre><code class="language-xml"><span class="hljs-tag">&lt;<span 
class="hljs-name">dubbo:service</span> <span 
class="hljs-attr">interface</span>=<span 
class="hljs-string">"org.apache.dubbo.demo.DemoService"</span> <span 
class="hljs-attr">ref</span>=<span class="hljs-string">"demoService"</span> 
<span class="hljs-attr">cluster</span>=<span 
class="hljs-string">"failsafe"</span> /&gt;</span>
+</code></pre>
+<p>服务调用方,服务级配置</p>
+<pre><code class="language-xml"><span class="hljs-tag">&lt;<span 
class="hljs-name">dubbo:reference</span> <span 
class="hljs-attr">id</span>=<span class="hljs-string">"demoService"</span> 
<span class="hljs-attr">interface</span>=<span 
class="hljs-string">"org.apache.dubbo.demo.DemoService"</span> <span 
class="hljs-attr">cluster</span>=<span 
class="hljs-string">"failsafe"</span>/&gt;</span>
+</code></pre>
+<p>其中服务调用方配置优先于服务提供方配置。</p>
+<h4>Failfast(快速失败)</h4>
+<p>某些业务场景中,某些操作可能是非幂等的,如果重复发起调用,可能会导致出现脏数据等。例如调用某个服务,其中包含一个数据库的写操作,如果写操作完成,但是在发送结果给调用方的过程中出错了,那么在调用发看来这次调用失败了,但其实数据写入已经完成。这种情况下,重试可能并不是一个好策略,这时候就需要使用到<code>Failfast</code>策略,调用失败立即报错。让调用方来决定下一步的操作并保证业务的幂等性。</p>
+<p>具体配置方法:</p>
+<p>服务提供方,服务级配置</p>
+<pre><code class="language-xml"><span class="hljs-tag">&lt;<span 
class="hljs-name">dubbo:service</span> <span 
class="hljs-attr">interface</span>=<span 
class="hljs-string">"org.apache.dubbo.demo.DemoService"</span> <span 
class="hljs-attr">ref</span>=<span class="hljs-string">"demoService"</span> 
<span class="hljs-attr">cluster</span>=<span 
class="hljs-string">"failfast"</span> /&gt;</span>
+</code></pre>
+<p>服务调用方,服务级配置</p>
+<pre><code class="language-xml"><span class="hljs-tag">&lt;<span 
class="hljs-name">dubbo:reference</span> <span 
class="hljs-attr">id</span>=<span class="hljs-string">"demoService"</span> 
<span class="hljs-attr">interface</span>=<span 
class="hljs-string">"org.apache.dubbo.demo.DemoService"</span> <span 
class="hljs-attr">cluster</span>=<span 
class="hljs-string">"failfast"</span>/&gt;</span>
+</code></pre>
+<p>其中服务调用方配置优先于服务提供方配置。</p>
+<h4>Failback(失败自动恢复)</h4>
+<p><code>Failback</code>通常和<code>Failover</code>两个概念联系在一起。在高可用系统中,当主机发生故障,通过<code>Failover</code>进行主备切换后,待故障恢复后,系统应该具备自动恢复原始配置的能力。</p>
+<p>Dubbo中的<code>Failback</code>策略中,如果调用失败,则此次失败相当于<code>Failsafe</code>,将返回一个空结果。而与<code>Failsafe</code>不同的是,Failback策略会将这次调用加入内存中的失败列表中,对于这个列表中的失败调用,会在另一个线程中进行异步重试,重试如果再发生失败,则会忽略,即使重试调用成功,原来的调用方也感知不到了。因此它通常适合于,对于实时性要求不高,且不需要返回值的一些异步操作。</p>
+<p>具体配置方法:</p>
+<p>服务提供方,服务级配置</p>
+<pre><code class="language-xml"><span class="hljs-tag">&lt;<span 
class="hljs-name">dubbo:service</span> <span 
class="hljs-attr">interface</span>=<span 
class="hljs-string">"org.apache.dubbo.demo.DemoService"</span> <span 
class="hljs-attr">ref</span>=<span class="hljs-string">"demoService"</span> 
<span class="hljs-attr">cluster</span>=<span 
class="hljs-string">"failsafe"</span> /&gt;</span>
+</code></pre>
+<p>服务调用方,服务级配置</p>
+<pre><code class="language-xml"><span class="hljs-tag">&lt;<span 
class="hljs-name">dubbo:reference</span> <span 
class="hljs-attr">id</span>=<span class="hljs-string">"demoService"</span> 
<span class="hljs-attr">interface</span>=<span 
class="hljs-string">"org.apache.dubbo.demo.DemoService"</span> <span 
class="hljs-attr">cluster</span>=<span 
class="hljs-string">"failsafe"</span>/&gt;</span>
+</code></pre>
+<p>其中服务调用方配置优先于服务提供方配置。</p>
+<p>按照目前的实现,Failback策略还有一些局限,例如内存中的失败调用列表没有上限,可能导致堆积,异步重试的执行间隔无法调整,默认是5秒。</p>
+<h4>Forking(并行调用)</h4>
+<p>上述几种策略中,主要都是针对调用失败发生后如何进行弥补的角度去考虑的,而<code>Forking</code>策略则跟上述几种策略不同,是一种典型的用成本换时间的思路。即第一次调用的时候就同时发起多个调用,只要其中一个调用成功,就认为成功。在资源充足,且对于失败的容忍度较低的场景下,可以采用此策略。</p>
+<p>具体配置方法:</p>
+<p>服务提供方,服务级配置</p>
+<pre><code class="language-xml"><span class="hljs-tag">&lt;<span 
class="hljs-name">dubbo:service</span> <span 
class="hljs-attr">interface</span>=<span 
class="hljs-string">"org.apache.dubbo.demo.DemoService"</span> <span 
class="hljs-attr">ref</span>=<span class="hljs-string">"demoService"</span> 
<span class="hljs-attr">cluster</span>=<span 
class="hljs-string">"forking"</span> /&gt;</span>
+</code></pre>
+<p>服务调用方,服务级配置</p>
+<pre><code class="language-xml"><span class="hljs-tag">&lt;<span 
class="hljs-name">dubbo:reference</span> <span 
class="hljs-attr">id</span>=<span class="hljs-string">"demoService"</span> 
<span class="hljs-attr">interface</span>=<span 
class="hljs-string">"org.apache.dubbo.demo.DemoService"</span> <span 
class="hljs-attr">cluster</span>=<span 
class="hljs-string">"forking"</span>/&gt;</span>
+</code></pre>
+<p>其中服务调用方配置优先于服务提供方配置。</p>
+<h4>Broadcast(广播调用)</h4>
+<p>在某些场景下,可能需要对服务的所有提供者进行操作,此时可以使用广播调用策略。此策略会逐个调用所有提供者,只要任意有一个提供者出错,则认为此次调用出错。通常用于通知所有提供者更新缓存或日志等本地资源信息。</p>
+<p>具体配置方法:</p>
+<p>服务提供方,服务级配置</p>
+<pre><code class="language-xml"><span class="hljs-tag">&lt;<span 
class="hljs-name">dubbo:service</span> <span 
class="hljs-attr">interface</span>=<span 
class="hljs-string">"org.apache.dubbo.demo.DemoService"</span> <span 
class="hljs-attr">ref</span>=<span class="hljs-string">"demoService"</span> 
<span class="hljs-attr">cluster</span>=<span 
class="hljs-string">"broadcast"</span> /&gt;</span>
+</code></pre>
+<p>服务调用方,服务级配置</p>
+<pre><code class="language-xml"><span class="hljs-tag">&lt;<span 
class="hljs-name">dubbo:reference</span> <span 
class="hljs-attr">id</span>=<span class="hljs-string">"demoService"</span> 
<span class="hljs-attr">interface</span>=<span 
class="hljs-string">"org.apache.dubbo.demo.DemoService"</span> <span 
class="hljs-attr">cluster</span>=<span 
class="hljs-string">"broadcast"</span>/&gt;</span>
+</code></pre>
+<p>其中服务调用方配置优先于服务提供方配置。</p>
+<h4>各种策略对比</h4>
+<p>下表对各种策略做一个简单对比,</p>
+<table>
+<thead>
+<tr>
+<th>策略名称</th>
+<th>优点</th>
+<th>缺点</th>
+<th>主要应用场景</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+<td>Failover</td>
+<td>对调用者屏蔽调用失败的信息</td>
+<td>增加RT,额外资源开销,资源浪费</td>
+<td>对调用rt不敏感的场景</td>
+</tr>
+<tr>
+<td>Failfast</td>
+<td>业务快速感知失败状态进行自主决策</td>
+<td>产生较多报错的信息</td>
+<td>非幂等性操作,需要快速感知失败的场景</td>
+</tr>
+<tr>
+<td>Failsafe</td>
+<td>即使失败了也不会影响核心流程</td>
+<td>对于失败的信息不敏感,需要额外的监控</td>
+<td>旁路系统,失败不影响核心流程正确性的场景</td>
+</tr>
+<tr>
+<td>Failback</td>
+<td>失败自动异步重试</td>
+<td>重试任务可能堆积</td>
+<td>对于实时性要求不高,且不需要返回值的一些异步操作</td>
+</tr>
+<tr>
+<td>Forking</td>
+<td>并行发起多个调用,降低失败概率</td>
+<td>消耗额外的机器资源,需要确保操作幂等性</td>
+<td>资源充足,且对于失败的容忍度较低,实时性要求高的场景</td>
+</tr>
+<tr>
+<td>Broadcast</td>
+<td>支持对所有的服务提供者进行操作</td>
+<td>资源消耗很大</td>
+<td>通知所有提供者更新缓存或日志等本地资源信息</td>
+</tr>
+</tbody>
+</table>
+<h3>自定义容错策略</h3>
+<p>如果上述内置的容错策略无法满足你的需求,还可以通过扩展的方式来实现自定义容错策略。</p>
+<h4>扩展接口</h4>
+<p><code>com.alibaba.dubbo.rpc.cluster.Cluster</code></p>
+<h4>扩展配置</h4>
+<pre><code class="language-xml"><span class="hljs-tag">&lt;<span 
class="hljs-name">dubbo:service</span> <span 
class="hljs-attr">cluster</span>=<span class="hljs-string">"xxx"</span> 
/&gt;</span>
+</code></pre>
+<h4>扩展示例</h4>
+<p>下面通过一个例子来展示如何使用自定义的容错策略。
+Maven 项目结构:</p>
+<pre><code>src
+ |-main
+    |-java
+        |-com
+            |-xxx
+                |-XxxCluster.java (实现Cluster接口)
+    |-resources
+        |-META-INF
+            |-dubbo
+                |-org.apache.dubbo.rpc.cluster.Cluster 
(纯文本文件,内容为:xxx=com.xxx.XxxCluster)
+</code></pre>
+<p>XxxCluster.java:</p>
+<pre><code class="language-java"><span class="hljs-keyword">package</span> 
com.xxx;
+ 
+<span class="hljs-keyword">import</span> org.apache.dubbo.rpc.cluster.Cluster;
+<span class="hljs-keyword">import</span> 
org.apache.dubbo.rpc.cluster.support.AbstractClusterInvoker;
+<span class="hljs-keyword">import</span> 
org.apache.dubbo.rpc.cluster.Directory;
+<span class="hljs-keyword">import</span> 
org.apache.dubbo.rpc.cluster.LoadBalance;
+<span class="hljs-keyword">import</span> org.apache.dubbo.rpc.Invoker;
+<span class="hljs-keyword">import</span> org.apache.dubbo.rpc.Invocation;
+<span class="hljs-keyword">import</span> org.apache.dubbo.rpc.Result;
+<span class="hljs-keyword">import</span> org.apache.dubbo.rpc.RpcException;
+
+<span class="hljs-keyword">import</span> java.util.List;
+
+<span class="hljs-keyword">public</span> <span class="hljs-class"><span 
class="hljs-keyword">class</span> <span class="hljs-title">XxxCluster</span> 
<span class="hljs-keyword">implements</span> <span 
class="hljs-title">Cluster</span> </span>{
+
+    <span class="hljs-meta">@Override</span>
+    <span class="hljs-keyword">public</span> &lt;T&gt; <span 
class="hljs-function">Invoker&lt;T&gt; <span 
class="hljs-title">join</span><span class="hljs-params">(Directory&lt;T&gt; 
directory)</span> <span class="hljs-keyword">throws</span> RpcException </span>{
+        <span class="hljs-keyword">return</span> <span 
class="hljs-keyword">new</span> AbstractClusterInvoker&lt;T&gt;() {
+            <span class="hljs-meta">@Override</span>
+            <span class="hljs-function"><span 
class="hljs-keyword">protected</span> Result <span 
class="hljs-title">doInvoke</span><span class="hljs-params">(Invocation 
invocation, List&lt;Invoker&lt;T&gt;&gt; invokers, LoadBalance 
loadbalance)</span> <span class="hljs-keyword">throws</span> RpcException 
</span>{
+                <span class="hljs-comment">// your custimzed fault tolarence 
strategy goes here</span>
+            }
+        };
+    }
+
+}
+</code></pre>
+<p><code>META-INF/dubbo/com.alibaba.dubbo.rpc.cluster.Cluster</code>文件的内容为</p>
+<pre><code>xxx=com.xxx.XxxCluster
+</code></pre>
+</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>Disclaimer</h3><p>Apache 
Dubbo is an effort undergoing incubation at The Apache Software Foundation 
(ASF), sponsored by the Incubator. Incubation is required of all newly accepted 
projects until a further review indicates that the infrastructure, 
communications, and decision making proce [...]
+       <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-cluster-error-handling.json 
b/zh-cn/blog/dubbo-cluster-error-handling.json
new file mode 100644
index 0000000..b158a33
--- /dev/null
+++ b/zh-cn/blog/dubbo-cluster-error-handling.json
@@ -0,0 +1,10 @@
+{
+  "filename": "dubbo-cluster-error-handling.md",
+  "__html": "<h3>Design For 
failure</h3>\n<p>在分布式系统中,集群某个某些节点出现问题是大概率事件,因此在设计分布式RPC框架的过程中,必须要把失败作为设计的一等公民来对待。一次调用失败之后,应该如何选择对失败的选择策略,这是一个见仁见智的问题,每种策略可能都有自己独特的应用场景。因此,作为框架来说,应当针对不同场景提供多种策略,供用户进行选择。</p>\n<p>在Dubbo设计中,通过Cluster这个接口的抽象,把一组可供调用的Provider信息组合成为一个统一的<code>Invoker</code>供调用方进行调用。经过路由规则过滤,负载均衡选址后,选中一个具体地址进行调用,如果调用失败,则会按照集群配置的容错策略进行容错处理。</p>\n<p>Dubbo默认内置了若干容错策略,如果不能满足用户需求,则可以通过自定义容错策略进行配置。</p>\n<h3>内置容错
 
策略</h3>\n<p>Dubbo主要内置了如下几种策略:</p>\n<ul>\n<li>Failover(失败自动切换)</li>\n<li>Failsaf 
[...]
+  "link": "/zh-cn/blog/dubbo-cluster-error-handling.html",
+  "meta": {
+    "title": "Dubbo集群容错",
+    "keywords": "Dubbo, RPC, cluster, Error-handling",
+    "description": 
"在分布式系统中,集群某个某些节点出现问题是大概率事件,因此在设计分布式RPC框架的过程中,必须要把失败作为设计的一等公民来对待。一次调用失败之后,应该如何选择对失败的选择策略,这是一个见仁见智的问题,每种策略可能都有自己独特的应用场景。因此,作为框架来说,应当针对不同场景提供多种策略,供用户进行选择。本文介绍了Dubbo框架提供的多种错误处理策略,并通过实例说明如何进行配置。"
+  }
+}
\ No newline at end of file
diff --git a/zh-cn/blog/dubbo-meetup-beijing-may-12th-2018.html 
b/zh-cn/blog/dubbo-meetup-beijing-may-12th-2018.html
new file mode 100644
index 0000000..52bb9f4
--- /dev/null
+++ b/zh-cn/blog/dubbo-meetup-beijing-may-12th-2018.html
@@ -0,0 +1,41 @@
+<!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, Beijing, meetup" />
+       <meta name="description" content="首届Dubbo开发者沙龙在北京成功举办" />
+       <!-- 网页标签标题 -->
+       <title>首届Dubbo开发者沙龙在北京成功举办</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 [...]
+<p>首届Dubbo开发者沙龙在北京成功举办, 超过400位开发者参加。这是一个很好的开始!</p>
+<p>分享嘉宾及主体如下:</p>
+<ul>
+<li>罗军: Dubbo 的现状现状与未来规划 <a 
href="https://github.com/dubbo/awesome-dubbo/raw/master/slides/meetup/201805%40Beijing/dubbo-present-and-future.pdf";>PDF</a></li>
+<li>刘军: 第四届阿里中间件性能挑战赛 <a 
href="https://github.com/dubbo/awesome-dubbo/raw/master/slides/meetup/201805%40Beijing/introduction-to-4th-aliware-performance-challenge.pdf";>PDF</a></li>
+<li>陈志轩: 通过 Dubbo 和 Spring-boot 快速构建微服务 <a 
href="https://github.com/dubbo/awesome-dubbo/raw/master/slides/meetup/201805%40Beijing/quickly-building-microservice-with-dubbo-and-springboot.pdf";>PDF</a></li>
+<li>王欣: Dubbo 和微店的服务化实践历程分享 <a 
href="https://github.com/dubbo/awesome-dubbo/raw/master/slides/meetup/201805%40Beijing/dubbo-and-weidian's-practice-on-microservice-architecture.pdf">PDF</a></li>
+</ul>
+</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>Disclaimer</h3><p>Apache 
Dubbo is an effort undergoing incubation at The Apache Software Foundation 
(ASF), sponsored by the Incubator. Incubation is required of all newly accepted 
projects until a further review indicates that the infrastructure, 
communications, and decision making proce [...]
+       <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-meetup-beijing-may-12th-2018.json 
b/zh-cn/blog/dubbo-meetup-beijing-may-12th-2018.json
new file mode 100644
index 0000000..2dcc43f
--- /dev/null
+++ b/zh-cn/blog/dubbo-meetup-beijing-may-12th-2018.json
@@ -0,0 +1,10 @@
+{
+  "filename": "dubbo-meetup-beijing-may-12th-2018.md",
+  "__html": "<h2>首届Dubbo开发者沙龙在北京成功举办</h2>\n<p>首届Dubbo开发者沙龙在北京成功举办, 
超过400位开发者参加。这是一个很好的开始!</p>\n<p>分享嘉宾及主体如下:</p>\n<ul>\n<li>罗军: Dubbo 的现状现状与未来规划 
<a 
href=\"https://github.com/dubbo/awesome-dubbo/raw/master/slides/meetup/201805%40Beijing/dubbo-present-and-future.pdf\";>PDF</a></li>\n<li>刘军:
 第四届阿里中间件性能挑战赛 <a 
href=\"https://github.com/dubbo/awesome-dubbo/raw/master/slides/meetup/201805%40Beijing/introduction-to-4th-aliware-performance-challenge.pdf\";>PDF</a></li>\n<li>陈志轩:
 通过 Dubbo 和 Spring-b [...]
+  "link": "/zh-cn/blog/dubbo-meetup-beijing-may-12th-2018.html",
+  "meta": {
+    "title": "首届Dubbo开发者沙龙在北京成功举办",
+    "keywords": "Dubbo, Beijing, meetup",
+    "description": "首届Dubbo开发者沙龙在北京成功举办"
+  }
+}
\ No newline at end of file
diff --git a/zh-cn/blog/first-dubbo-filter.html 
b/zh-cn/blog/first-dubbo-filter.html
new file mode 100644
index 0000000..f140f64
--- /dev/null
+++ b/zh-cn/blog/first-dubbo-filter.html
@@ -0,0 +1,183 @@
+<!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="first-dubbo-filter" />
+       <meta name="description" content="first-dubbo-filter" />
+       <!-- 网页标签标题 -->
+       <title>first-dubbo-filter</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>概述</h3>
+<p>在Dubbo的整体设计中,Filter是一个很重要的概念,包括Dubbo本身的大多数功能,都是基于此扩展点实现的,在每次的调用过程中,Filter的拦截都会被执行。</p>
+<h4>Dubbo Filter的加载机制</h4>
+<p>Dubbo中已经实现的Filter大概有二十几个,它们的入口都是ProtocolFilterWrapper,ProtocolFilterWrapper对Protocol做了Wrapper,会在加载扩展的时候被加载进来,下面我们来看下然后我们看一下这个Filter链是如何构造的。</p>
+<pre><code class="language-java"><span 
class="hljs-comment">//ProtocolFilterWrapper.java</span>
+<span class="hljs-keyword">public</span> &lt;T&gt; <span 
class="hljs-function">Invoker&lt;T&gt; <span 
class="hljs-title">refer</span><span class="hljs-params">(Class&lt;T&gt; type, 
URL url)</span> <span class="hljs-keyword">throws</span> RpcException </span>{
+        <span class="hljs-keyword">if</span> 
(Constants.REGISTRY_PROTOCOL.equals(url.getProtocol())) {
+            <span class="hljs-keyword">return</span> protocol.refer(type, url);
+        }
+        <span class="hljs-keyword">return</span> 
buildInvokerChain(protocol.refer(type, url), Constants.REFERENCE_FILTER_KEY, 
Constants.CONSUMER);
+    }
+    
+    <span class="hljs-keyword">private</span> <span 
class="hljs-keyword">static</span> &lt;T&gt; <span 
class="hljs-function">Invoker&lt;T&gt; <span 
class="hljs-title">buildInvokerChain</span><span class="hljs-params">(<span 
class="hljs-keyword">final</span> Invoker&lt;T&gt; invoker, String key, String 
group)</span> </span>{
+        Invoker&lt;T&gt; last = invoker;
+        List&lt;Filter&gt; filters = 
ExtensionLoader.getExtensionLoader(Filter.class).getActivateExtension(invoker.getUrl(),
 key, group);
+        <span class="hljs-keyword">if</span> (filters.size() &gt; <span 
class="hljs-number">0</span>) {
+            <span class="hljs-keyword">for</span> (<span 
class="hljs-keyword">int</span> i = filters.size() - <span 
class="hljs-number">1</span>; i &gt;= <span class="hljs-number">0</span>; i --) 
{
+                <span class="hljs-keyword">final</span> Filter filter = 
filters.get(i);
+                <span class="hljs-keyword">final</span> Invoker&lt;T&gt; next 
= last;
+                last = <span class="hljs-keyword">new</span> 
Invoker&lt;T&gt;() {
+
+                    <span class="hljs-function"><span 
class="hljs-keyword">public</span> Class&lt;T&gt; <span 
class="hljs-title">getInterface</span><span class="hljs-params">()</span> 
</span>{
+                        <span class="hljs-keyword">return</span> 
invoker.getInterface();
+                    }
+
+                    <span class="hljs-function"><span 
class="hljs-keyword">public</span> URL <span 
class="hljs-title">getUrl</span><span class="hljs-params">()</span> </span>{
+                        <span class="hljs-keyword">return</span> 
invoker.getUrl();
+                    }
+
+                    <span class="hljs-function"><span 
class="hljs-keyword">public</span> <span class="hljs-keyword">boolean</span> 
<span class="hljs-title">isAvailable</span><span class="hljs-params">()</span> 
</span>{
+                        <span class="hljs-keyword">return</span> 
invoker.isAvailable();
+                    }
+
+                    <span class="hljs-function"><span 
class="hljs-keyword">public</span> Result <span 
class="hljs-title">invoke</span><span class="hljs-params">(Invocation 
invocation)</span> <span class="hljs-keyword">throws</span> RpcException 
</span>{
+                        <span class="hljs-keyword">return</span> 
filter.invoke(next, invocation);
+                    }
+
+                    <span class="hljs-function"><span 
class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span 
class="hljs-title">destroy</span><span class="hljs-params">()</span> </span>{
+                        invoker.destroy();
+                    }
+
+                    <span class="hljs-meta">@Override</span>
+                    <span class="hljs-function"><span 
class="hljs-keyword">public</span> String <span 
class="hljs-title">toString</span><span class="hljs-params">()</span> </span>{
+                        <span class="hljs-keyword">return</span> 
invoker.toString();
+                    }
+                };
+            }
+        }
+        <span class="hljs-keyword">return</span> last;
+    }
+
+</code></pre>
+<h4>Dubbo Filter的激活机制</h4>
+<p>通过上述代码我们可以看到,在<code>buildInvokerChain</code>中,先获取所有已经激活的调用链,这里的调用链是已经排好序的。再通过Invoker来构造出一个Filter的调用链,最后构建出的调用链大致可以表示为:Filter1-&gt;Filter2-&gt;Filter3-&gt;......-&gt;Invoker,下面我们来看一下,第一步中获取已经激活的调用链的详细流程:</p>
+<pre><code class="language-java">    <span class="hljs-function"><span 
class="hljs-keyword">public</span> List&lt;T&gt; <span 
class="hljs-title">getActivateExtension</span><span class="hljs-params">(URL 
url, String key, String group)</span> </span>{
+        String value = url.getParameter(key);
+        <span class="hljs-keyword">return</span> getActivateExtension(url, 
value == <span class="hljs-keyword">null</span> || value.length() == <span 
class="hljs-number">0</span> ? <span class="hljs-keyword">null</span> : 
Constants.COMMA_SPLIT_PATTERN.split(value), group);
+    }
+    
+    <span class="hljs-function"><span class="hljs-keyword">public</span> 
List&lt;T&gt; <span class="hljs-title">getActivateExtension</span><span 
class="hljs-params">(URL url, String[] values, String group)</span> </span>{
+        List&lt;T&gt; exts = <span class="hljs-keyword">new</span> 
ArrayList&lt;T&gt;();
+        
+        List&lt;String&gt; names = values == <span 
class="hljs-keyword">null</span> ? <span class="hljs-keyword">new</span> 
ArrayList&lt;String&gt;(<span class="hljs-number">0</span>) : 
Arrays.asList(values);
+
+        <span class="hljs-keyword">if</span> (! 
names.contains(Constants.REMOVE_VALUE_PREFIX + Constants.DEFAULT_KEY)) {
+            getExtensionClasses();
+            <span class="hljs-keyword">for</span> (Map.Entry&lt;String, 
Activate&gt; entry : cachedActivates.entrySet()) {
+                String name = entry.getKey();
+                Activate activate = entry.getValue();
+                <span class="hljs-keyword">if</span> (isMatchGroup(group, 
activate.group())) {
+                    T ext = getExtension(name);
+                    <span class="hljs-keyword">if</span> (! 
names.contains(name) &amp;&amp; ! names.contains(Constants.REMOVE_VALUE_PREFIX 
+ name) 
+                            &amp;&amp; isActive(activate, url)) {
+                        exts.add(ext);
+                    }
+                }
+            }
+            Collections.sort(exts, ActivateComparator.COMPARATOR);
+        }
+        List&lt;T&gt; usrs = <span class="hljs-keyword">new</span> 
ArrayList&lt;T&gt;();
+        <span class="hljs-keyword">for</span> (<span 
class="hljs-keyword">int</span> i = <span class="hljs-number">0</span>; i &lt; 
names.size(); i ++) {
+            String name = names.get(i);
+            <span class="hljs-keyword">if</span> (! 
name.startsWith(Constants.REMOVE_VALUE_PREFIX)
+                    &amp;&amp; ! names.contains(Constants.REMOVE_VALUE_PREFIX 
+ name)) {
+                           <span class="hljs-keyword">if</span> 
(Constants.DEFAULT_KEY.equals(name)) {
+                    <span class="hljs-keyword">if</span> (usrs.size() &gt; 
<span class="hljs-number">0</span>) {
+                        exts.addAll(<span class="hljs-number">0</span>, usrs);
+                        usrs.clear();
+                    }
+                } <span class="hljs-keyword">else</span> {
+                    T ext = getExtension(name);
+                    usrs.add(ext);
+                }
+            }
+        }
+        <span class="hljs-keyword">if</span> (usrs.size() &gt; <span 
class="hljs-number">0</span>) {
+            exts.addAll(usrs);
+        }
+        <span class="hljs-keyword">return</span> exts;
+    }
+</code></pre>
+<p>通过以上代码可以看到,用户自己配置的Filter中,有些是默认激活,有些是需要通过配置文件来激活。而所有Filter的加载顺序,也是先处理Dubbo的默认Filter,再来处理用户自己定义并且配置的Filter。通过&quot;-&quot;配置,可以替换掉Dubbo的原生Filter,通过这样的设计,可以灵活地替换或者修改Filter的加载顺序。</p>
+<h4>Dubbo原生的Filter</h4>
+<p>Dubbo原生的Filter很多,RpcContext,accesslog等功能都可以通过Dubbo来实现,下面我们来介绍一下Consumer端用于上下文传递的ConsumerContextFilter:</p>
+<pre><code class="language-java"><span class="hljs-function"><span 
class="hljs-keyword">public</span> Result <span 
class="hljs-title">invoke</span><span class="hljs-params">(Invoker&lt;?&gt; 
invoker, Invocation invocation)</span> <span class="hljs-keyword">throws</span> 
RpcException </span>{
+        RpcContext.getContext()
+                .setInvoker(invoker)
+                .setInvocation(invocation)
+                .setLocalAddress(NetUtils.getLocalHost(), <span 
class="hljs-number">0</span>)
+                .setRemoteAddress(invoker.getUrl().getHost(), 
+                                  invoker.getUrl().getPort());
+        <span class="hljs-keyword">if</span> (invocation <span 
class="hljs-keyword">instanceof</span> RpcInvocation) {
+            ((RpcInvocation)invocation).setInvoker(invoker);
+        }
+        <span class="hljs-keyword">try</span> {
+            <span class="hljs-keyword">return</span> 
invoker.invoke(invocation);
+        } <span class="hljs-keyword">finally</span> {
+            RpcContext.getContext().clearAttachments();
+        }
+    }
+</code></pre>
+<p>此Filter记录了调用过程中的状态信息,并且通过invocation对象将客户端设置的attachments参数传递到服务端。并且在调用完成后清除这些参数,这就是为什么请求状态信息可以按次记录并且进行传递。</p>
+<h4>实现一个Dubbo Filter</h4>
+<p>得益于Dubbo灵活的设计和良好的可扩展性,我们可以通过实现自己的Dubbo 
Filter来完成调用链路中的逻辑嵌入,比如,耗时统计,monitor信息统计等,下面我们来实现一个简单的Filter:</p>
+<p>Maven 项目结构:</p>
+<pre><code>src
+ |-main
+    |-java
+        |-com
+            |-xxx
+                |-XxxFilter.java (实现Filter接口)
+    |-resources
+        |-META-INF
+            |-dubbo
+                |-com.alibaba.dubbo.rpc.Filter 
(纯文本文件,内容为:xxx=com.xxx.XxxFilter)
+</code></pre>
+<p>XxxFilter.java:</p>
+<pre><code>public class XxxFilter implements Filter {
+    public Result invoke(Invoker&lt;?&gt; invoker, Invocation invocation) 
throws RpcException {
+        // before filter ...
+        Result result = invoker.invoke(invocation);
+        // after filter ...
+        return result;
+    }
+}
+</code></pre>
+<p>META-INF/dubbo/com.alibaba.dubbo.rpc.Filter:</p>
+<pre><code>xxx=com.xxx.XxxFilter
+</code></pre>
+<p>在before和after中,可以实现自己的业务逻辑来赋予改filter一定的功能。编写和配置完成后,该filter就会被Dubbo框架激活并且在调用链中执行。</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>Disclaimer</h3><p>Apache 
Dubbo is an effort undergoing incubation at The Apache Software Foundation 
(ASF), sponsored by the Incubator. Incubation is required of all newly accepted 
projects until a further review indicates that the infrastructure, 
communications, and decision making proce [...]
+       <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/first-dubbo-filter.json 
b/zh-cn/blog/first-dubbo-filter.json
new file mode 100644
index 0000000..8cce968
--- /dev/null
+++ b/zh-cn/blog/first-dubbo-filter.json
@@ -0,0 +1,6 @@
+{
+  "filename": "first-dubbo-filter.md",
+  "__html": "<h1>第一个Dubbo 
Filter</h1>\n<h3>概述</h3>\n<p>在Dubbo的整体设计中,Filter是一个很重要的概念,包括Dubbo本身的大多数功能,都是基于此扩展点实现的,在每次的调用过程中,Filter的拦截都会被执行。</p>\n<h4>Dubbo
 
Filter的加载机制</h4>\n<p>Dubbo中已经实现的Filter大概有二十几个,它们的入口都是ProtocolFilterWrapper,ProtocolFilterWrapper对Protocol做了Wrapper,会在加载扩展的时候被加载进来,下面我们来看下然后我们看一下这个Filter链是如何构造的。</p>\n<pre><code
 class=\"language-java\"><span 
class=\"hljs-comment\">//ProtocolFilterWrapper.java</span>\n<span 
class=\"hljs-keyword\">public</span> &lt;T&gt; <span class=\"hljs- [...]
+  "link": "/zh-cn/blog/first-dubbo-filter.html",
+  "meta": {}
+}
\ No newline at end of file
diff --git a/zh-cn/blog/index.html b/zh-cn/blog/index.html
index 491155d..da17259 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>
diff --git a/zh-cn/blog/qcon-beijing-2018.html 
b/zh-cn/blog/qcon-beijing-2018.html
new file mode 100644
index 0000000..e8b88a9
--- /dev/null
+++ b/zh-cn/blog/qcon-beijing-2018.html
@@ -0,0 +1,34 @@
+<!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="qcon-beijing-2018" />
+       <meta name="description" content="qcon-beijing-2018" />
+       <!-- 网页标签标题 -->
+       <title>qcon-beijing-2018</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 [...]
+<p>罗毅在Qcon Beijing 2018上进行了Dubbo开源现状及未来规划的主题演讲。详细内容请查看<a 
href="https://github.com/dubbo/awesome-dubbo/raw/master/slides/qcon2018/dubbo-present-and-future.pdf";>幻灯片</a>。</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>Disclaimer</h3><p>Apache 
Dubbo is an effort undergoing incubation at The Apache Software Foundation 
(ASF), sponsored by the Incubator. Incubation is required of all newly accepted 
projects until a further review indicates that the infrastructure, 
communications, and decision making proce [...]
+       <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/qcon-beijing-2018.json 
b/zh-cn/blog/qcon-beijing-2018.json
new file mode 100644
index 0000000..000d43a
--- /dev/null
+++ b/zh-cn/blog/qcon-beijing-2018.json
@@ -0,0 +1,6 @@
+{
+  "filename": "qcon-beijing-2018.md",
+  "__html": "<h2>Dubbo路线图在QCon Beijing 2018上公布</h2>\n<p>罗毅在Qcon Beijing 
2018上进行了Dubbo开源现状及未来规划的主题演讲。详细内容请查看<a 
href=\"https://github.com/dubbo/awesome-dubbo/raw/master/slides/qcon2018/dubbo-present-and-future.pdf\";>幻灯片</a>。</p>\n",
+  "link": "/zh-cn/blog/qcon-beijing-2018.html",
+  "meta": {}
+}
\ No newline at end of file
diff --git a/zh-cn/blog/service-and-version.html 
b/zh-cn/blog/service-and-version.html
new file mode 100644
index 0000000..bcff661
--- /dev/null
+++ b/zh-cn/blog/service-and-version.html
@@ -0,0 +1,213 @@
+<!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="service-and-version" />
+       <meta name="description" content="service-and-version" />
+       <!-- 网页标签标题 -->
+       <title>service-and-version</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 [...]
+<p>我们在调用Dubbo服务的时候,一般只需要将Consumer端的<code>dubbo:reference</code>指定成服务端中<code>dubbo:service</code>暴露的服务,就可以找到服务端,完成调用,也就是说,Dubbo只需要服务接口信息就可以找到服务提供者。
+其实除了服务提供者以外,Dubbo也有服务分组和版本的概念,在客户端去寻找“匹配”的服务端的时候,需要服务接口,版本号,组别这三个信息都匹配,才算是一个有效的服务端:</p>
+<pre><code class="language-java">   <span class="hljs-function"><span 
class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> 
<span class="hljs-keyword">boolean</span> <span 
class="hljs-title">isMatch</span><span class="hljs-params">(URL consumerUrl, 
URL providerUrl)</span> </span>{
+        String consumerInterface = consumerUrl.getServiceInterface();
+        String providerInterface = providerUrl.getServiceInterface();
+        <span class="hljs-keyword">if</span> 
(!(Constants.ANY_VALUE.equals(consumerInterface) || 
StringUtils.isEquals(consumerInterface, providerInterface)))
+            <span class="hljs-keyword">return</span> <span 
class="hljs-keyword">false</span>;
+
+        <span class="hljs-keyword">if</span> 
(!isMatchCategory(providerUrl.getParameter(Constants.CATEGORY_KEY, 
Constants.DEFAULT_CATEGORY),
+                consumerUrl.getParameter(Constants.CATEGORY_KEY, 
Constants.DEFAULT_CATEGORY))) {
+            <span class="hljs-keyword">return</span> <span 
class="hljs-keyword">false</span>;
+        }
+        <span class="hljs-keyword">if</span> 
(!providerUrl.getParameter(Constants.ENABLED_KEY, <span 
class="hljs-keyword">true</span>)
+                &amp;&amp; 
!Constants.ANY_VALUE.equals(consumerUrl.getParameter(Constants.ENABLED_KEY))) {
+            <span class="hljs-keyword">return</span> <span 
class="hljs-keyword">false</span>;
+        }
+
+        String consumerGroup = consumerUrl.getParameter(Constants.GROUP_KEY);
+        String consumerVersion = 
consumerUrl.getParameter(Constants.VERSION_KEY);
+        String consumerClassifier = 
consumerUrl.getParameter(Constants.CLASSIFIER_KEY, Constants.ANY_VALUE);
+
+        String providerGroup = providerUrl.getParameter(Constants.GROUP_KEY);
+        String providerVersion = 
providerUrl.getParameter(Constants.VERSION_KEY);
+        String providerClassifier = 
providerUrl.getParameter(Constants.CLASSIFIER_KEY, Constants.ANY_VALUE);
+        <span class="hljs-keyword">return</span> 
(Constants.ANY_VALUE.equals(consumerGroup) || 
StringUtils.isEquals(consumerGroup, providerGroup) || 
StringUtils.isContains(consumerGroup, providerGroup))
+                &amp;&amp; (Constants.ANY_VALUE.equals(consumerVersion) || 
StringUtils.isEquals(consumerVersion, providerVersion))
+                &amp;&amp; (consumerClassifier == <span 
class="hljs-keyword">null</span> || 
Constants.ANY_VALUE.equals(consumerClassifier) || 
StringUtils.isEquals(consumerClassifier, providerClassifier));
+    }
+</code></pre>
+<p>如果没有配置组别和版本号,默认值为空。服务端和消费端都没有配,只有服务接口,其他两个信息都为空,也是可以“找到”对方的,那服务名和版本号可以如何使用呢?下面我们来看一下具体的场景:</p>
+<h3>服务分组</h3>
+<p>当一个接口有多种实现时,可以用 group 区分。</p>
+<p>服务</p>
+<pre><code>&lt;dubbo:service group=&quot;feedback&quot; 
interface=&quot;com.xxx.IndexService&quot; /&gt;
+&lt;dubbo:service group=&quot;member&quot; 
interface=&quot;com.xxx.IndexService&quot; /&gt;
+</code></pre>
+<p>引用</p>
+<pre><code>&lt;dubbo:reference id=&quot;feedbackIndexService&quot; 
group=&quot;feedback&quot; interface=&quot;com.xxx.IndexService&quot; /&gt;
+&lt;dubbo:reference id=&quot;memberIndexService&quot; group=&quot;member&quot; 
interface=&quot;com.xxx.IndexService&quot; /&gt;
+</code></pre>
+<p>任意组</p>
+<pre><code>&lt;dubbo:reference id=&quot;barService&quot; 
interface=&quot;com.foo.BarService&quot; group=&quot;*&quot; /&gt;
+</code></pre>
+<h3>多版本</h3>
+<p>当一个接口实现,出现不兼容升级时,可以用版本号过渡,版本号不同的服务相互间不引用。</p>
+<p>可以按照以下的步骤进行版本迁移:</p>
+<ol>
+<li>在低压力时间段,先升级一半提供者为新版本</li>
+<li>再将所有消费者升级为新版本</li>
+<li>然后将剩下的一半提供者升级为新版本</li>
+</ol>
+<p>老版本服务提供者配置:</p>
+<pre><code>&lt;dubbo:service interface=&quot;com.foo.BarService&quot; 
version=&quot;1.0.0&quot; /&gt;  
+</code></pre>
+<p>新版本服务提供者配置:</p>
+<pre><code>&lt;dubbo:service interface=&quot;com.foo.BarService&quot; 
version=&quot;2.0.0&quot; /&gt;
+</code></pre>
+<p>老版本服务消费者配置:</p>
+<pre><code>&lt;dubbo:reference id=&quot;barService&quot; 
interface=&quot;com.foo.BarService&quot; version=&quot;1.0.0&quot; /&gt;
+</code></pre>
+<p>新版本服务消费者配置:</p>
+<pre><code>&lt;dubbo:reference id=&quot;barService&quot; 
interface=&quot;com.foo.BarService&quot; version=&quot;2.0.0&quot; /&gt;
+</code></pre>
+<p>如果不需要区分版本,可以按照以下的方式配置:</p>
+<pre><code>&lt;dubbo:reference id=&quot;barService&quot; 
interface=&quot;com.foo.BarService&quot; version=&quot;*&quot; /&gt; 
+</code></pre>
+<h3>分组聚合</h3>
+<p>按组合并返回结果,比如菜单服务,接口一样,但有多种实现,用group区分,现在消费方需从每种group中调用一次返回结果,合并结果返回,这样就可以实现聚合菜单项。</p>
+<h4>配置</h4>
+<p>搜索所有分组</p>
+<pre><code>&lt;dubbo:reference interface=&quot;com.xxx.MenuService&quot; 
group=&quot;*&quot; merger=&quot;true&quot; /&gt;
+</code></pre>
+<p>合并指定分组</p>
+<pre><code>&lt;dubbo:reference interface=&quot;com.xxx.MenuService&quot; 
group=&quot;aaa,bbb&quot; merger=&quot;true&quot; /&gt;
+</code></pre>
+<p>指定方法合并结果,其它未指定的方法,将只调用一个 Group</p>
+<pre><code>&lt;dubbo:reference interface=&quot;com.xxx.MenuService&quot; 
group=&quot;*&quot;&gt;
+&lt;dubbo:method name=&quot;getMenuItems&quot; merger=&quot;true&quot; /&gt;
+&lt;/dubbo:service&gt;
+</code></pre>
+<p>某个方法不合并结果,其它都合并结果</p>
+<pre><code>&lt;dubbo:reference interface=&quot;com.xxx.MenuService&quot; 
group=&quot;*&quot; merger=&quot;true&quot;&gt;
+&lt;dubbo:method name=&quot;getMenuItems&quot; merger=&quot;false&quot; /&gt;
+&lt;/dubbo:service&gt;
+</code></pre>
+<p>指定合并策略,缺省根据返回值类型自动匹配,如果同一类型有两个合并器时,需指定合并器的名称</p>
+<pre><code>&lt;dubbo:reference interface=&quot;com.xxx.MenuService&quot; 
group=&quot;*&quot;&gt;
+&lt;dubbo:method name=&quot;getMenuItems&quot; merger=&quot;mymerge&quot; /&gt;
+&lt;/dubbo:service&gt;
+</code></pre>
+<p>指定合并方法,将调用返回结果的指定方法进行合并,合并方法的参数类型必须是返回结果类型本身</p>
+<pre><code>&lt;dubbo:reference interface=&quot;com.xxx.MenuService&quot; 
group=&quot;*&quot;&gt;
+&lt;dubbo:method name=&quot;getMenuItems&quot; merger=&quot;.addAll&quot; /&gt;
+&lt;/dubbo:service&gt;  
+</code></pre>
+<h4>实现原理</h4>
+<p>如果配置了merge,Dubbo会分别调用多个组别的服务提供者,然后把结果聚合,返回给消费端,具体的实现在<code>MergeableClusterInvoker.java</code>里:</p>
+<pre><code class="language-java"> <span class="hljs-function"><span 
class="hljs-keyword">public</span> Result <span 
class="hljs-title">invoke</span><span class="hljs-params">(<span 
class="hljs-keyword">final</span> Invocation invocation)</span> <span 
class="hljs-keyword">throws</span> RpcException </span>{
+        List&lt;Invoker&lt;T&gt;&gt; invokers = directory.list(invocation);
+
+        String merger = 
getUrl().getMethodParameter(invocation.getMethodName(), Constants.MERGER_KEY);
+        <span class="hljs-keyword">if</span> (ConfigUtils.isEmpty(merger)) { 
<span class="hljs-comment">// If a method doesn't have a merger, only invoke 
one Group</span>
+            <span class="hljs-keyword">for</span> (<span 
class="hljs-keyword">final</span> Invoker&lt;T&gt; invoker : invokers) {
+                <span class="hljs-keyword">if</span> (invoker.isAvailable()) {
+                    <span class="hljs-keyword">return</span> 
invoker.invoke(invocation);
+                }
+            }
+            <span class="hljs-keyword">return</span> 
invokers.iterator().next().invoke(invocation);
+        }
+
+        Class&lt;?&gt; returnType;
+        <span class="hljs-keyword">try</span> {
+            returnType = getInterface().getMethod(
+                    invocation.getMethodName(), 
invocation.getParameterTypes()).getReturnType();
+        } <span class="hljs-keyword">catch</span> (NoSuchMethodException e) {
+            returnType = <span class="hljs-keyword">null</span>;
+        }
+
+        Map&lt;String, Future&lt;Result&gt;&gt; results = <span 
class="hljs-keyword">new</span> HashMap&lt;String, Future&lt;Result&gt;&gt;();
+        <span class="hljs-keyword">for</span> (<span 
class="hljs-keyword">final</span> Invoker&lt;T&gt; invoker : invokers) {
+            Future&lt;Result&gt; future = executor.submit(<span 
class="hljs-keyword">new</span> Callable&lt;Result&gt;() {
+                <span class="hljs-meta">@Override</span>
+                <span class="hljs-function"><span 
class="hljs-keyword">public</span> Result <span 
class="hljs-title">call</span><span class="hljs-params">()</span> <span 
class="hljs-keyword">throws</span> Exception </span>{
+                    <span class="hljs-keyword">return</span> 
invoker.invoke(<span class="hljs-keyword">new</span> RpcInvocation(invocation, 
invoker));
+                }
+            });
+            results.put(invoker.getUrl().getServiceKey(), future);
+        }
+
+        Object result = <span class="hljs-keyword">null</span>;
+
+        List&lt;Result&gt; resultList = <span class="hljs-keyword">new</span> 
ArrayList&lt;Result&gt;(results.size());
+
+        <span class="hljs-keyword">int</span> timeout = 
getUrl().getMethodParameter(invocation.getMethodName(), Constants.TIMEOUT_KEY, 
Constants.DEFAULT_TIMEOUT);
+        <span class="hljs-keyword">for</span> (Map.Entry&lt;String, 
Future&lt;Result&gt;&gt; entry : results.entrySet()) {
+            Future&lt;Result&gt; future = entry.getValue();
+            <span class="hljs-keyword">try</span> {
+                Result r = future.get(timeout, TimeUnit.MILLISECONDS);
+                <span class="hljs-keyword">if</span> (r.hasException()) {
+                    log.error(<span class="hljs-string">"Invoke "</span> + 
getGroupDescFromServiceKey(entry.getKey()) + 
+                                    <span class="hljs-string">" failed: 
"</span> + r.getException().getMessage(), 
+                            r.getException());
+                } <span class="hljs-keyword">else</span> {
+                    resultList.add(r);
+                }
+            } <span class="hljs-keyword">catch</span> (Exception e) {
+                <span class="hljs-keyword">throw</span> <span 
class="hljs-keyword">new</span> RpcException(<span class="hljs-string">"Failed 
to invoke service "</span> + entry.getKey() + <span class="hljs-string">": 
"</span> + e.getMessage(), e);
+            }
+        }
+
+        <span class="hljs-keyword">if</span> (resultList.isEmpty()) {
+            <span class="hljs-keyword">return</span> <span 
class="hljs-keyword">new</span> RpcResult((Object) <span 
class="hljs-keyword">null</span>);
+        } <span class="hljs-keyword">else</span> <span 
class="hljs-keyword">if</span> (resultList.size() == <span 
class="hljs-number">1</span>) {
+            <span class="hljs-keyword">return</span> 
resultList.iterator().next();
+        }
+
+        <span class="hljs-keyword">if</span> (returnType == <span 
class="hljs-keyword">void</span>.class) {
+            <span class="hljs-keyword">return</span> <span 
class="hljs-keyword">new</span> RpcResult((Object) <span 
class="hljs-keyword">null</span>);
+        }
+</code></pre>
+<p>如果配置了merger,会依次调用,结果都放在results里面,其中value都是future类型,等调用完成之后,再遍历results,通过future.get拿到真正的结果,到此为止,所有调用的结果都放在resultList里面了,接下来要做的是把结果进行聚合:</p>
+<pre><code class="language-java">  Merger resultMerger;
+  <span class="hljs-keyword">if</span> (ConfigUtils.isDefault(merger)) {
+      resultMerger = MergerFactory.getMerger(returnType);
+  } <span class="hljs-keyword">else</span> {
+      resultMerger = 
ExtensionLoader.getExtensionLoader(Merger.class).getExtension(merger);
+  }
+  <span class="hljs-keyword">if</span> (resultMerger != <span 
class="hljs-keyword">null</span>) {
+      List&lt;Object&gt; rets = <span class="hljs-keyword">new</span> 
ArrayList&lt;Object&gt;(resultList.size());
+      <span class="hljs-keyword">for</span> (Result r : resultList) {
+          rets.add(r.getValue());
+      }
+      result = resultMerger.merge(
+                        rets.toArray((Object[]) Array.newInstance(returnType, 
<span class="hljs-number">0</span>)));
+  } <span class="hljs-keyword">else</span> {
+      <span class="hljs-keyword">throw</span> <span 
class="hljs-keyword">new</span> RpcException(<span class="hljs-string">"There 
is no merger to merge result."</span>)
+  }
+  <span class="hljs-keyword">return</span> <span 
class="hljs-keyword">new</span> RpcResult(result);
+</code></pre>
+<p>这里会根据返回值的类型,获取到对应的resultMerger,除了Dubbo默认实现的类型外,也可以自己指定merger类型并且添加相应的扩展,通过实现<code>merge</code>方法类进行结果聚合。</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>Disclaimer</h3><p>Apache 
Dubbo is an effort undergoing incubation at The Apache Software Foundation 
(ASF), sponsored by the Incubator. Incubation is required of all newly accepted 
projects until a further review indicates that the infrastructure, 
communications, and decision making proce [...]
+       <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/service-and-version.json 
b/zh-cn/blog/service-and-version.json
new file mode 100644
index 0000000..aa6638c
--- /dev/null
+++ b/zh-cn/blog/service-and-version.json
@@ -0,0 +1,6 @@
+{
+  "filename": "service-and-version.md",
+  "__html": 
"<h1>Dubbo服务分组和版本聚合</h1>\n<p>我们在调用Dubbo服务的时候,一般只需要将Consumer端的<code>dubbo:reference</code>指定成服务端中<code>dubbo:service</code>暴露的服务,就可以找到服务端,完成调用,也就是说,Dubbo只需要服务接口信息就可以找到服务提供者。\n其实除了服务提供者以外,Dubbo也有服务分组和版本的概念,在客户端去寻找“匹配”的服务端的时候,需要服务接口,版本号,组别这三个信息都匹配,才算是一个有效的服务端:</p>\n<pre><code
 class=\"language-java\">   <span class=\"hljs-function\"><span 
class=\"hljs-keyword\">public</span> <span class=\"hljs-keyword\">static</span> 
<span class=\"hljs-keyword\">boolean</span> <span class=\"hljs- [...]
+  "link": "/zh-cn/blog/service-and-version.html",
+  "meta": {}
+}
\ No newline at end of file
diff --git a/zh-cn/blog/test-verification.html 
b/zh-cn/blog/test-verification.html
new file mode 100644
index 0000000..cd53812
--- /dev/null
+++ b/zh-cn/blog/test-verification.html
@@ -0,0 +1,111 @@
+<!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="test-verification" />
+       <meta name="description" content="test-verification" />
+       <!-- 网页标签标题 -->
+       <title>test-verification</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 [...]
+<p>除了线上常规的使用场景以外,我们在日常使用中还需要一些特定的使用方式,比如对正在开发的功能进行验证测试,比如单独调用某台机器的服务,这篇文章就来介绍一下这些场景下的使用方式。</p>
+<h3>只订阅</h3>
+<p>为方便开发测试,经常会在线下共用一个所有服务可用的注册中心,这时,如果一个正在开发中的服务提供者注册,可能会影响消费者不能正常运行。</p>
+<p>可以让服务提供者开发方,只订阅服务(开发的服务可能依赖其它服务),而不注册正在开发的服务,通过直连测试正在开发的服务。<br>
+<img 
src="https://cdn.nlark.com/lark/0/2018/jpeg/6752/1535447102196-eabbff47-287d-4f85-8fea-05b4f4921d75.jpeg";
 alt="subscribe-only.jpg">
+禁用注册配置</p>
+<pre><code>&lt;dubbo:registry address=&quot;10.20.153.10:9090&quot; 
register=&quot;false&quot; /&gt;
+</code></pre>
+<p>或者</p>
+<pre><code>&lt;dubbo:registry 
address=&quot;10.20.153.10:9090?register=false&quot; /&gt;
+</code></pre>
+<h3>指定IP调用</h3>
+<p>在开发及测试环境下,经常需要绕过注册中心,只测试指定服务提供者,这时候可能需要点对点直连,点对点直联方式,将以服务接口为单位,忽略注册中心的提供者列表,A
 接口配置点对点,不影响 B 接口从注册中心获取列表<br>
+<img 
src="https://cdn.nlark.com/lark/0/2018/jpeg/6752/1535447028864-8b952768-6fce-4c3c-b7a4-2003f3291d8e.jpeg";
 alt="dubbo-directly.jpg"></p>
+<p>可以通过以下几种配置来指定IP调用</p>
+<ul>
+<li>XML 配置: 如果是线上需求需要点对点,可在 <a href="dubbo:reference">dubbo:reference</a> 中配置 
url 指向提供者,将绕过注册中心,多个地址用分号隔开,配置如下:
+<code>&lt;dubbo:reference id=&quot;xxxService&quot; 
interface=&quot;com.alibaba.xxx.XxxService&quot; 
url=&quot;dubbo://localhost:20890&quot; /&gt;</code></li>
+<li>通过-D参数指定: 在 JVM 启动参数中加入-D参数映射服务地址,如:<code>java 
-Dcom.alibaba.xxx.XxxService=dubbo://localhost:20890</code></li>
+<li>通过文件映射: 如果服务比较多,也可以用文件映射,用 -Ddubbo.resolve.file 指定映射文件路径,此配置优先级高于 <a 
href="dubbo:reference">dubbo:reference</a> 中的配置,如:
+<code>java -Ddubbo.resolve.file=xxx.properties</code><br>
+然后在映射文件 xxx.properties 中加入配置,其中 key 为服务名,value 为服务提供者 
URL:<code>com.alibaba.xxx.XxxService=dubbo://localhost:20890</code></li>
+</ul>
+<h3>回声测试</h3>
+<h4>使用方式</h4>
+<p>回声测试用于检测服务是否可用,回声测试按照正常请求流程执行,能够测试整个调用是否通畅,可用于监控。</p>
+<p>所有服务自动实现 EchoService 接口,只需将任意服务引用强制转型为 EchoService,即可使用。</p>
+<p>Spring 配置:</p>
+<pre><code>&lt;dubbo:reference id=&quot;memberService&quot; 
interface=&quot;com.xxx.MemberService&quot; /&gt;
+</code></pre>
+<p>代码:</p>
+<pre><code>// 远程服务引用
+MemberService memberService = ctx.getBean(&quot;memberService&quot;); 
+ 
+EchoService echoService = (EchoService) memberService; // 强制转型为EchoService
+
+// 回声测试可用性
+String status = echoService.$echo(&quot;OK&quot;); 
+ 
+assert(status.equals(&quot;OK&quot;));
+</code></pre>
+<h4>实现原理</h4>
+<p>我们在实现,注册服务的时候,并没有配置EchoService这个接口,为什么可以直接使用呢?原来是Dubbo在生成proxy的时候,已经实现了<code>EchoService这个接口</code></p>
+<pre><code class="language-java">  <span class="hljs-meta">@Override</span>
+    <span class="hljs-keyword">public</span> &lt;T&gt; <span 
class="hljs-function">T <span class="hljs-title">getProxy</span><span 
class="hljs-params">(Invoker&lt;T&gt; invoker)</span> <span 
class="hljs-keyword">throws</span> RpcException </span>{
+        Class&lt;?&gt;[] interfaces = <span class="hljs-keyword">null</span>;
+        String config = invoker.getUrl().getParameter(<span 
class="hljs-string">"interfaces"</span>);
+        <span class="hljs-keyword">if</span> (config != <span 
class="hljs-keyword">null</span> &amp;&amp; config.length() &gt; <span 
class="hljs-number">0</span>) {
+            String[] types = Constants.COMMA_SPLIT_PATTERN.split(config);
+            <span class="hljs-keyword">if</span> (types != <span 
class="hljs-keyword">null</span> &amp;&amp; types.length &gt; <span 
class="hljs-number">0</span>) {
+                interfaces = <span class="hljs-keyword">new</span> 
Class&lt;?&gt;[types.length + <span class="hljs-number">2</span>];
+                interfaces[<span class="hljs-number">0</span>] = 
invoker.getInterface();
+                interfaces[<span class="hljs-number">1</span>] = 
EchoService.class;
+                <span class="hljs-keyword">for</span> (<span 
class="hljs-keyword">int</span> i = <span class="hljs-number">0</span>; i &lt; 
types.length; i++) {
+                    interfaces[i + <span class="hljs-number">1</span>] = 
ReflectUtils.forName(types[i]);
+                }
+            }
+        }
+        <span class="hljs-keyword">if</span> (interfaces == <span 
class="hljs-keyword">null</span>) {
+            interfaces = <span class="hljs-keyword">new</span> 
Class&lt;?&gt;[]{invoker.getInterface(), EchoService.class};
+        }
+        <span class="hljs-keyword">return</span> getProxy(invoker, interfaces);
+    }
+</code></pre>
+<p>通过这种方式,任何bean都可以被转换成EchoService的实例,但是并没有实现<code>$echo</code>这个方法,这里,Dubbo使用filter机制做了处理:</p>
+<pre><code class="language-java"><span class="hljs-keyword">public</span> 
<span class="hljs-class"><span class="hljs-keyword">class</span> <span 
class="hljs-title">EchoFilter</span> <span 
class="hljs-keyword">implements</span> <span class="hljs-title">Filter</span> 
</span>{
+
+    <span class="hljs-meta">@Override</span>
+    <span class="hljs-function"><span class="hljs-keyword">public</span> 
Result <span class="hljs-title">invoke</span><span 
class="hljs-params">(Invoker&lt;?&gt; invoker, Invocation inv)</span> <span 
class="hljs-keyword">throws</span> RpcException </span>{
+        <span class="hljs-keyword">if</span> 
(inv.getMethodName().equals(Constants.$ECHO) &amp;&amp; inv.getArguments() != 
<span class="hljs-keyword">null</span> &amp;&amp; inv.getArguments().length == 
<span class="hljs-number">1</span>)
+            <span class="hljs-keyword">return</span> <span 
class="hljs-keyword">new</span> RpcResult(inv.getArguments()[<span 
class="hljs-number">0</span>]);
+        <span class="hljs-keyword">return</span> invoker.invoke(inv);
+    }
+
+}
+</code></pre>
+<p>在经过EchoFilter.invoke方法时,如果调用的是<code>$echo</code>,会中断当前的调用过程,直接返回<code>$echo</code>的入参,否则会继续执行Filter链。<br>
+通过动态代理和EchoFilter机制,使得回声测试的整个过程对用户透明,不需要做任何额外的配置,直接调用即可。</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>Disclaimer</h3><p>Apache 
Dubbo is an effort undergoing incubation at The Apache Software Foundation 
(ASF), sponsored by the Incubator. Incubation is required of all newly accepted 
projects until a further review indicates that the infrastructure, 
communications, and decision making proce [...]
+       <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/test-verification.json 
b/zh-cn/blog/test-verification.json
new file mode 100644
index 0000000..225b52f
--- /dev/null
+++ b/zh-cn/blog/test-verification.json
@@ -0,0 +1,6 @@
+{
+  "filename": "test-verification.md",
+  "__html": 
"<h1>Dubbo测试验证</h1>\n<p>除了线上常规的使用场景以外,我们在日常使用中还需要一些特定的使用方式,比如对正在开发的功能进行验证测试,比如单独调用某台机器的服务,这篇文章就来介绍一下这些场景下的使用方式。</p>\n<h3>只订阅</h3>\n<p>为方便开发测试,经常会在线下共用一个所有服务可用的注册中心,这时,如果一个正在开发中的服务提供者注册,可能会影响消费者不能正常运行。</p>\n<p>可以让服务提供者开发方,只订阅服务(开发的服务可能依赖其它服务),而不注册正在开发的服务,通过直连测试正在开发的服务。<br>\n<img
 
src=\"https://cdn.nlark.com/lark/0/2018/jpeg/6752/1535447102196-eabbff47-287d-4f85-8fea-05b4f4921d75.jpeg\";
 alt=\"subscribe-only.jpg\">\n禁用注册配置</p>\n<pre><code>&lt;dubbo:registry 
address=&quot;10.20.15 [...]
+  "link": "/zh-cn/blog/test-verification.html",
+  "meta": {}
+}
\ No newline at end of file
diff --git a/zh-cn/docs/admin/install/admin-console.html 
b/zh-cn/docs/admin/install/admin-console.html
index 11e0b75..dd79362 100644
--- a/zh-cn/docs/admin/install/admin-console.html
+++ b/zh-cn/docs/admin/install/admin-console.html
@@ -12,7 +12,25 @@
        <link rel="stylesheet" href="/build/documentation.css" />
 </head>
 <body>
-       <div id="root"><div class="documentation-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 [...]
+       <div id="root"><div class="documentation-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 [...]
+<h3>管理控制台安装</h3>
+<p>=======
+###管理控制台安装</p>
+<blockquote>
+<blockquote>
+<blockquote>
+<blockquote>
+<blockquote>
+<blockquote>
+<blockquote>
+<p>a71d0fc87489096a2e99133c47769ffa750bafa6</p>
+</blockquote>
+</blockquote>
+</blockquote>
+</blockquote>
+</blockquote>
+</blockquote>
+</blockquote>
 <p>目前版本的管理控制台正在开发中,已经完成了服务查询和服务治理的功能,采用前后端分离的模式,具体的安装和使用步骤如下:</p>
 <p>安装:</p>
 <pre><code class="language-sh">git <span class="hljs-built_in">clone</span> 
https://github.com/apache/incubator-dubbo-ops.git /var/tmp/dubbo-ops
diff --git a/zh-cn/docs/admin/install/admin-console.json 
b/zh-cn/docs/admin/install/admin-console.json
index a4246cb..f1351ac 100644
--- a/zh-cn/docs/admin/install/admin-console.json
+++ b/zh-cn/docs/admin/install/admin-console.json
@@ -1,6 +1,6 @@
 {
   "filename": "admin-console.md",
-  "__html": 
"<h3>管理控制台安装</h3>\n<p>目前版本的管理控制台正在开发中,已经完成了服务查询和服务治理的功能,采用前后端分离的模式,具体的安装和使用步骤如下:</p>\n<p>安装:</p>\n<pre><code
 class=\"language-sh\">git <span class=\"hljs-built_in\">clone</span> 
https://github.com/apache/incubator-dubbo-ops.git /var/tmp/dubbo-ops\n<span 
class=\"hljs-built_in\">cd</span> /var/tmp/dubbo-ops\nmvn clean 
package\n</code></pre>\n<p>配置 <sup class=\"footnote-ref\"><a href=\"#fn1\" 
id=\"fnref1\">[1]</a></sup>:</p>\n<pre><code 
class=\"language-sh\">配置文件为:\ndubbo-admin- [...]
+  "__html": "<p>&lt;&lt;&lt;&lt;&lt;&lt;&lt; 
HEAD</p>\n<h3>管理控制台安装</h3>\n<p>=======\n###管理控制台安装</p>\n<blockquote>\n<blockquote>\n<blockquote>\n<blockquote>\n<blockquote>\n<blockquote>\n<blockquote>\n<p>a71d0fc87489096a2e99133c47769ffa750bafa6</p>\n</blockquote>\n</blockquote>\n</blockquote>\n</blockquote>\n</blockquote>\n</blockquote>\n</blockquote>\n<p>目前版本的管理控制台正在开发中,已经完成了服务查询和服务治理的功能,采用前后端分离的模式,具体的安装和使用步骤如下:</p>\n<p>安装:</p>\n<pre><code
 class=\"language-sh\">git <span class=\"hljs-buil [...]
   "link": "/zh-cn/docs/admin/install/admin-console.html",
   "meta": {}
 }
\ No newline at end of file

Reply via email to