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

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


The following commit(s) were added to refs/heads/asf-site by this push:
     new 7c99ee0  build
7c99ee0 is described below

commit 7c99ee0f529655affe0bb82b8312563d4e977eb9
Author: zhuyong <yong.z...@alibaba-inc.com>
AuthorDate: Tue Sep 4 09:19:09 2018 +0800

    build
---
 en-us/blog/dubbo-generic-invoke.html               | 18 +++++-----
 en-us/blog/dubbo-generic-invoke.json               |  2 +-
 en-us/blog/introduction-to-dubbo-spi-2.html        | 14 ++++----
 en-us/blog/introduction-to-dubbo-spi-2.json        |  2 +-
 .../spring-boot-dubbo-start-stop-analysis.html     | 14 ++++----
 .../spring-boot-dubbo-start-stop-analysis.json     |  2 +-
 ...o-basic-usage-dubbo-provider-configuration.html | 15 ++++----
 ...o-basic-usage-dubbo-provider-configuration.json |  2 +-
 zh-cn/blog/dubbo-contribue-to-opensource.html      | 41 +++++++++++-----------
 zh-cn/blog/dubbo-contribue-to-opensource.json      |  2 +-
 zh-cn/blog/dubbo-generic-invoke.html               | 16 ++++-----
 zh-cn/blog/dubbo-generic-invoke.json               |  2 +-
 zh-cn/blog/dubbo-invoke.html                       | 22 ++++++------
 zh-cn/blog/dubbo-invoke.json                       |  2 +-
 zh-cn/blog/introduction-to-dubbo-qos.html          | 20 +++++------
 zh-cn/blog/introduction-to-dubbo-qos.json          |  2 +-
 zh-cn/blog/introduction-to-dubbo-spi-2.html        | 12 +++----
 zh-cn/blog/introduction-to-dubbo-spi-2.json        |  2 +-
 zh-cn/blog/introduction-to-dubbo-spi.html          | 19 +++++-----
 zh-cn/blog/introduction-to-dubbo-spi.json          |  2 +-
 .../spring-boot-dubbo-start-stop-analysis.html     | 14 ++++----
 .../spring-boot-dubbo-start-stop-analysis.json     |  2 +-
 zh-cn/docs/user/demos/group-merger.html            |  6 ++--
 zh-cn/docs/user/demos/group-merger.json            |  2 +-
 24 files changed, 119 insertions(+), 116 deletions(-)

diff --git a/en-us/blog/dubbo-generic-invoke.html 
b/en-us/blog/dubbo-generic-invoke.html
index 327ed19..d4819e3 100644
--- a/en-us/blog/dubbo-generic-invoke.html
+++ b/en-us/blog/dubbo-generic-invoke.html
@@ -12,7 +12,7 @@
        <link rel="stylesheet" href="/build/blogDetail.css" />
 </head>
 <body>
-       <div id="root"><div class="blog-detail-page" data-reactroot="" 
data-reactid="1" data-react-checksum="-1076442714"><header 
class="header-container header-container-normal" data-reactid="2"><div 
class="header-body" data-reactid="3"><a href="/en-us/index.html" 
data-reactid="4"><img class="logo" src="/img/dubbo_colorful.png" 
data-reactid="5"/></a><span class="language-switch language-switch-normal" 
data-reactid="6">中</span><div class="header-menu" data-reactid="7"><img 
class="header-menu-to [...]
+       <div id="root"><div class="blog-detail-page" data-reactroot="" 
data-reactid="1" data-react-checksum="143640982"><header 
class="header-container header-container-normal" data-reactid="2"><div 
class="header-body" data-reactid="3"><a href="/en-us/index.html" 
data-reactid="4"><img class="logo" src="/img/dubbo_colorful.png" 
data-reactid="5"/></a><span class="language-switch language-switch-normal" 
data-reactid="6">中</span><div class="header-menu" data-reactid="7"><img 
class="header-menu-togg [...]
 <p>The generic invoke could be considered to be used in the following 
cases:</p>
 <ul>
 <li>Service test platform</li>
@@ -22,7 +22,7 @@
 instead of depending the interface jar package, the service call is initiated 
directly through the GenericService interface, and all POJOs in the parameters 
and return values are represented by a <code>Map</code>.
 Generic invoke does not require attention on the server and can be exposed as 
normal services.</p>
 <p>Next, let's take a look at how the consumer uses generic invoke for service 
call.</p>
-<h3>Generic invoke through Spring XML configuration</h3>
+<h2>Generic invoke through Spring XML configuration</h2>
 <p>Declare <code>generic=&quot;true&quot;</code> in Spring configuration, such 
as</p>
 <pre><code class="language-xml">"userService" 
interface="com.alibaba.dubbo.samples.generic.api.IUserService" 
generic="true"/&gt;
 </code></pre>
@@ -44,7 +44,7 @@ System.out.println(name);
 <p>iii.        If it is a POJO, use the full class name directly, such as 
<code>com.alibaba.dubbo.samples.generic.api.Params</code>.</p>
 </li>
 </ol>
-<h3>Generic invoke through API programming</h3>
+<h2>Generic invoke through API programming</h2>
 <pre><code class="language-java">ApplicationConfig application = <span 
class="hljs-keyword">new</span> ApplicationConfig()ApplicationConfig 
application = <span class="hljs-keyword">new</span> ApplicationConfig();
 application.setName(<span class="hljs-string">"api-generic-consumer"</span>);
 
@@ -68,7 +68,7 @@ String name = (String) genericService.$invoke(<span 
class="hljs-string">"delete"
 System.out.println(name);
 </code></pre>
 <p>Through the API, you don't need to configure the service in advance like 
XML. You can dynamically construct ReferenceConfig; the API is more common than 
XML.</p>
-<h3>The case where parameters or return values are POJOs</h3>
+<h2>The case where parameters or return values are POJOs</h2>
 <p>For example, the method signature is <code>User get(Params params)</code>, 
where <code>User</code> has two attributes, id and name, and 
<code>Params</code> has one attribute, query.</p>
 <p>The following is the code of the consumer:</p>
 <pre><code class="language-java">String[] parameterTypes = <span 
class="hljs-keyword">new</span> String[]{<span 
class="hljs-string">"com.alibaba.dubbo.samples.generic.api.Params"</span>};
@@ -83,9 +83,9 @@ System.out.println(<span class="hljs-string">"sample one 
result: "</span> + user
 </code></pre>
 <p>Here, the Dubbo framework will automatically convert the return value from 
POJO to Map.
 It can be seen that the return value <code>user</code> is a HashMap, which 
stores three k/vs, name, id, and class.</p>
-<h3>Generic interface implementation</h3>
+<h2>Generic interface implementation</h2>
 <p>The implementation of the generic interface is mainly used when the server 
does not have an API interface. All POJOs in the parameters and return values 
are represented by Map, which is usually used for framework integration. For 
example, to implement a generic remote service Mock framework, all service 
requests can be handled by implementing the interface GenericService.</p>
-<h4>Implementation GenericService on the server</h4>
+<h3>Implementation GenericService on the server</h3>
 <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">GenericServiceImpl</span> <span 
class="hljs-keyword">implements</span> <span 
class="hljs-title">GenericService</span> </span>{
     <span class="hljs-meta">@Override</span>
     <span class="hljs-keyword">public</span> Object $invoke(String method, 
String[] parameterTypes, Object[] args) <span 
class="hljs-keyword">throws</span> GenericException {
@@ -99,7 +99,7 @@ It can be seen that the return value <code>user</code> is a 
HashMap, which store
     }
 }
 </code></pre>
-<h4>Server exposed service</h4>
+<h3>Server exposed service</h3>
 <pre><code class="language-java">ApplicationConfig application = <span 
class="hljs-keyword">new</span> ApplicationConfig();
 application.setName(<span class="hljs-string">"api-generic-provider"</span>);
 
@@ -123,7 +123,7 @@ service2.setRef(genericService);
 service2.export();
 </code></pre>
 <p>Similarly, you can expose the service using XML configuration; in this 
case, the server does not depend on the two interfaces HiService and 
HelloService.</p>
-<h4>Service invoke on the consumer</h4>
+<h3>Service invoke on the consumer</h3>
 <pre><code class="language-java">ApplicationConfig application = <span 
class="hljs-keyword">new</span> ApplicationConfig();
 application.setName(<span class="hljs-string">"api-generic-consumer"</span>);
 
@@ -150,7 +150,7 @@ System.out.println(helloService.hello(<span 
class="hljs-string">"community"</spa
 </code></pre>
 <p>Similarly, the consumer can also reference the service using an XML 
configuration and then make the call. Here you can see that the calling method 
is a normal service call, not a generic call. Of course, it is also possible to 
use generic calls.</p>
 <p>So far, a simple service Mock platform has been successfully launched!</p>
-<h3>Others</h3>
+<h2>Others</h2>
 <ul>
 <li>The generic invoke and generic interface implementations introduced in 
this article are all based on the native Dubbo protocol. Prior to version 
2.6.2, other protocols such as http/hessian don't support generic invoke. 
Version 2.6.3 will support the generic invoke of these two protocols.</li>
 <li>The relevant sample codes mentioned in this article can be found in 
dubbo-samples: <a 
href="https://github.com/dubbo/dubbo-samples/tree/master/dubbo-samples-generic";>https://github.com/dubbo/dubbo-samples/tree/master/dubbo-samples-generic</a></li>
diff --git a/en-us/blog/dubbo-generic-invoke.json 
b/en-us/blog/dubbo-generic-invoke.json
index 9a0a6a0..ee76abd 100644
--- a/en-us/blog/dubbo-generic-invoke.json
+++ b/en-us/blog/dubbo-generic-invoke.json
@@ -1,4 +1,4 @@
 {
   "filename": "dubbo-generic-invoke.md",
-  "__html": "<h1>Generic invoke of Dubbo</h1>\n<p>The generic invoke could be 
considered to be used in the following cases:</p>\n<ul>\n<li>Service test 
platform</li>\n<li>API service gateway</li>\n</ul>\n<p>The generic invoke is 
mainly used when the consumer does not have an API interface;\ninstead of 
depending the interface jar package, the service call is initiated directly 
through the GenericService interface, and all POJOs in the parameters and 
return values are represented by a <cod [...]
+  "__html": "<h1>Generic invoke of Dubbo</h1>\n<p>The generic invoke could be 
considered to be used in the following cases:</p>\n<ul>\n<li>Service test 
platform</li>\n<li>API service gateway</li>\n</ul>\n<p>The generic invoke is 
mainly used when the consumer does not have an API interface;\ninstead of 
depending the interface jar package, the service call is initiated directly 
through the GenericService interface, and all POJOs in the parameters and 
return values are represented by a <cod [...]
 }
\ No newline at end of file
diff --git a/en-us/blog/introduction-to-dubbo-spi-2.html 
b/en-us/blog/introduction-to-dubbo-spi-2.html
index f52e125..42e034e 100644
--- a/en-us/blog/introduction-to-dubbo-spi-2.html
+++ b/en-us/blog/introduction-to-dubbo-spi-2.html
@@ -12,11 +12,11 @@
        <link rel="stylesheet" href="/build/blogDetail.css" />
 </head>
 <body>
-       <div id="root"><div class="blog-detail-page" data-reactroot="" 
data-reactid="1" data-react-checksum="1212085058"><header 
class="header-container header-container-normal" data-reactid="2"><div 
class="header-body" data-reactid="3"><a href="/en-us/index.html" 
data-reactid="4"><img class="logo" src="/img/dubbo_colorful.png" 
data-reactid="5"/></a><span class="language-switch language-switch-normal" 
data-reactid="6">中</span><div class="header-menu" data-reactid="7"><img 
class="header-menu-tog [...]
+       <div id="root"><div class="blog-detail-page" data-reactroot="" 
data-reactid="1" data-react-checksum="1160050139"><header 
class="header-container header-container-normal" data-reactid="2"><div 
class="header-body" data-reactid="3"><a href="/en-us/index.html" 
data-reactid="4"><img class="logo" src="/img/dubbo_colorful.png" 
data-reactid="5"/></a><span class="language-switch language-switch-normal" 
data-reactid="6">中</span><div class="header-menu" data-reactid="7"><img 
class="header-menu-tog [...]
 <hr>
-<p>In the <a href="#/blog/introduction-to-dubbo-spi.md">actual implementation 
of the Dubbo extensibility mechanism</a>, we learned some concepts of the Dubbo 
extension mechanism, explored the implementation of LoadBalance in Dubbo, and 
implemented a LoadBalance on our own. Do you think Dubbo's extension mechanism 
is great? Next, we will go deep into the source code of Dubbo and see what it 
is.</p>
-<h1>ExtensionLoader</h1>
-<p>ExtentionLoader is the core class, which is responsible for the loading and 
lifecycle management of extension points. Let's start with this class. There 
are many methods of Extension, and the common methods include:</p>
+<p>In the <a href="./introduction-to-dubbo-spi.md">actual implementation of 
the Dubbo extensibility mechanism</a>, we learned some concepts of the Dubbo 
extension mechanism, explored the implementation of LoadBalance in Dubbo, and 
implemented a LoadBalance on our own. Do you think Dubbo's extension mechanism 
is great? Next, we will go deep into the source code of Dubbo and see what it 
is.</p>
+<h2>ExtensionLoader</h2>
+<p><code>ExtentionLoader</code> is the core class, which is responsible for 
the loading and lifecycle management of extension points. Let's start with this 
class. There are many methods of Extension, and the common methods include:</p>
 <ul>
 <li><code>public static &lt;T&gt; ExtensionLoader&lt;T&gt; 
getExtensionLoader(Class&lt;T&gt; type)</code></li>
 <li><code>public T getExtension(String name)</code></li>
@@ -161,7 +161,7 @@ This is a static factory method that enters an extensible 
interface and returns
 <li>Extended instance is auto-wrapping. Auto-wrapping is about implementing 
Spring like AOP functionality. Dubbo uses it to implement some common functions 
internally, such as logging, monitoring, and so on. The contents of the 
extended instance auto-wrapper will also be explained separately later.</li>
 </ol>
 <p>After the above 4 steps, Dubbo creates and initializes an extended 
instance. The dependencies of this instance are injected and packaged as 
needed. At this point, this extended instance can be used.</p>
-<h1>Auto-assembly of Dubbo SPI advanced usage</h1>
+<h2>Auto-assembly of Dubbo SPI advanced usage</h2>
 <p>The relevant code for auto-assembly is in the injectExtension method:</p>
 <pre><code class="language-java"><span class="hljs-function"><span 
class="hljs-keyword">private</span> T <span 
class="hljs-title">injectExtension</span><span class="hljs-params">(T 
instance)</span> </span>{
     <span class="hljs-keyword">for</span> (Method method : 
instance.getClass().getMethods()) {
@@ -222,7 +222,7 @@ This is a static factory method that enters an extensible 
interface and returns
 </code></pre>
 <p>The AdaptiveExtensionLoader class has @Adaptive annotations. As mentioned 
earlier, Dubbo creates an adaptive instance for each extension. If the 
extension class has @Adaptive annotations, it will use it as an adaptive class. 
If not, Dubbo will create one for us. So 
<code>ExtensionLoader.getExtensionLoader(ExtensionFactory.class).getAdaptiveExtension())</code>
 will return an AdaptiveExtensionLoader instance as an adaptive extension 
instance.
 The AdaptiveExtentionLoader will iterate through all the ExtensionFactory 
implementations and try to load the extensions. If found, return. If not, 
continue to find it in the next ExtensionFactory. Dubbo has two 
ExtensionFactory built in, which are searched from Dubbo's own extension 
mechanism and Spring container. Since ExtensionFactory itself is also an 
extension point, we can implement our own ExtensionFactory to enable automatic 
assembly of Dubbo to support our custom components. For [...]
-<h1>AoP of Dubbo SPI advanced usage</h1>
+<h2>AoP of Dubbo SPI advanced usage</h2>
 <p>We often use AOP functionality when using Spring. Insert other logic before 
and after the method of the target class. For example, Spring AOP is usually 
used to implement logging, monitoring, and authentication, and so on.
 Does Dubbo's extension mechanism also support similar features? The answer is 
yes. In Dubbo, there is a special class called the Wrapper class. It uses the 
wrapper class to wrap the original extension point instance through the 
decorator pattern, and then inserts additional logic before and after the 
original extension point implementation to implement AOP functionality.</p>
 <h3>What is the Wrapper class</h3>
@@ -268,7 +268,7 @@ The code of ProtocolFilterWrapper is as follows:</p>
     }
 </code></pre>
 <p>ProtocolFilterWrapper has a constructor <code>public 
ProtocolFilterWrapper(Protocol protocol)</code>, and the parameter is the 
extension point Protocol. So it is a Wrapper class in the Dubbo extension 
mechanism. The ExtensionLoader will cache it. When creating Extension instances 
later, the ExtensionLoader use these wrapper classes to wrap the original 
Extension point in turn.</p>
-<h1>Extension point adaptive</h1>
+<h2>Extension point adaptive</h2>
 <p>As mentioned earlier, Dubbo needs to determine which extension to use based 
on method parameters at runtime. So there is an extension point adaptive 
instance. In fact, it is an extension point proxy that delays the selection of 
extensions from starting Dubbo to calling RPC. Each extension point in Dubbo 
has an adaptive class. If it is not explicitly provided, Dubbo will 
automatically create one for us. By default, Javaassist is used.
 Let's first look at the code to create an adaptive extension class:</p>
 <pre><code class="language-java"><span class="hljs-function"><span 
class="hljs-keyword">public</span> T <span 
class="hljs-title">getAdaptiveExtension</span><span 
class="hljs-params">()</span> </span>{
diff --git a/en-us/blog/introduction-to-dubbo-spi-2.json 
b/en-us/blog/introduction-to-dubbo-spi-2.json
index 918b890..732d33f 100644
--- a/en-us/blog/introduction-to-dubbo-spi-2.json
+++ b/en-us/blog/introduction-to-dubbo-spi-2.json
@@ -1,4 +1,4 @@
 {
   "filename": "introduction-to-dubbo-spi-2.md",
-  "__html": "<h1>Dubbo extensible mechanism source code 
analysis</h1>\n<hr>\n<p>In the <a 
href=\"#/blog/introduction-to-dubbo-spi.md\">actual implementation of the Dubbo 
extensibility mechanism</a>, we learned some concepts of the Dubbo extension 
mechanism, explored the implementation of LoadBalance in Dubbo, and implemented 
a LoadBalance on our own. Do you think Dubbo's extension mechanism is great? 
Next, we will go deep into the source code of Dubbo and see what it 
is.</p>\n<h1>Extensi [...]
+  "__html": "<h1>Dubbo extensible mechanism source code 
analysis</h1>\n<hr>\n<p>In the <a 
href=\"./introduction-to-dubbo-spi.md\">actual implementation of the Dubbo 
extensibility mechanism</a>, we learned some concepts of the Dubbo extension 
mechanism, explored the implementation of LoadBalance in Dubbo, and implemented 
a LoadBalance on our own. Do you think Dubbo's extension mechanism is great? 
Next, we will go deep into the source code of Dubbo and see what it 
is.</p>\n<h2>ExtensionLoa [...]
 }
\ No newline at end of file
diff --git a/en-us/blog/spring-boot-dubbo-start-stop-analysis.html 
b/en-us/blog/spring-boot-dubbo-start-stop-analysis.html
index bf3adb0..faf218d 100644
--- a/en-us/blog/spring-boot-dubbo-start-stop-analysis.html
+++ b/en-us/blog/spring-boot-dubbo-start-stop-analysis.html
@@ -12,14 +12,14 @@
        <link rel="stylesheet" href="/build/blogDetail.css" />
 </head>
 <body>
-       <div id="root"><div class="blog-detail-page" data-reactroot="" 
data-reactid="1" data-react-checksum="-194004511"><header 
class="header-container header-container-normal" data-reactid="2"><div 
class="header-body" data-reactid="3"><a href="/en-us/index.html" 
data-reactid="4"><img class="logo" src="/img/dubbo_colorful.png" 
data-reactid="5"/></a><span class="language-switch language-switch-normal" 
data-reactid="6">中</span><div class="header-menu" data-reactid="7"><img 
class="header-menu-tog [...]
-<h3>Introduction</h3>
+       <div id="root"><div class="blog-detail-page" data-reactroot="" 
data-reactid="1" data-react-checksum="827242965"><header 
class="header-container header-container-normal" data-reactid="2"><div 
class="header-body" data-reactid="3"><a href="/en-us/index.html" 
data-reactid="4"><img class="logo" src="/img/dubbo_colorful.png" 
data-reactid="5"/></a><span class="language-switch language-switch-normal" 
data-reactid="6">中</span><div class="header-menu" data-reactid="7"><img 
class="header-menu-togg [...]
+<h2>Introduction</h2>
 <p><a 
href="https://github.com/apache/incubator-dubbo-spring-boot-project";>Dubbo 
Spring Boot</a> project is dedicated to simplifying the development of the 
Dubbo RPC framework in the Spring Boot application. It also integrates the 
feature of Spring Boot:</p>
 <ul>
 <li><a 
href="https://github.com/apache/incubator-dubbo-spring-boot-project/blob/master/dubbo-spring-boot-autoconfigure";>Autoconfigure</a>
 (ex: Annotation driver, Autoconfigure, etc.)</li>
 <li><a 
href="https://github.com/apache/incubator-dubbo-spring-boot-project/blob/master/dubbo-spring-boot-actuator";>Production-Ready</a>
 (ex: Security, Healthy check, Externalize configuration, etc.)</li>
 </ul>
-<h3>The analysis of DubboConsumer startup</h3>
+<h2>The analysis of DubboConsumer startup</h2>
 <p>Have you ever thought about this : since the <code>DubboConsumerDemo</code> 
application in <code>incubator-dubbo-spring-boot-project</code> has only one 
line of code, why not just exit directly when the <code>main</code> method is 
executed?</p>
 <pre><code class="language-java"><span 
class="hljs-meta">@SpringBootApplication</span>(scanBasePackages = <span 
class="hljs-string">"com.alibaba.boot.dubbo.demo.consumer.controller"</span>)
 <span class="hljs-keyword">public</span> <span class="hljs-class"><span 
class="hljs-keyword">class</span> <span 
class="hljs-title">DubboConsumerDemo</span> </span>{
@@ -124,7 +124,7 @@ main:35, DubboConsumerDemo 
(com.alibaba.boot.dubbo.demo.consumer.bootstrap)
 <p>In the await method, the current thread checks the variable 
<code>stopAwait</code> every 10 seconds in a while loop. It is a 
<code>volatile</code> variable that is used to ensure that the current thread 
can see the change immediately after the variable being modified by another 
thread. If there is no change, it will stay in the loop. This is the reason why 
the thread does not exit, which is also the reason that the entire Spring-boot 
application doesn't exit.</p>
 <p>Since Spring-boot application enables port 8080 and 8081(management port) 
at the same time, there are actually two Tomcats. So there are two threads 
named <code>container-0</code> and <code>container-1</code>.</p>
 <p>Next, let's see how this Spring-boot application exits.</p>
-<h3>The analysis of DubboConsumer exit</h3>
+<h2>The analysis of DubboConsumer exit</h2>
 <p>As mentioned in the previous description, there is a thread that checks the 
variable <code>stopAwait</code> continuously. So there must be a thread to 
modify <code>stopAwait</code> at Stop, thus break the while loop. But who is 
modifying this variable?</p>
 <p>By analyzing the source code, we can see that there is only one method that 
modifies <code>stopAwait</code> : 
<code>org.apache.catalina.core.StandardServer#stopAwait</code>. To figure out 
who is calling this method, we add a breakpoint here.</p>
 <blockquote>
@@ -172,14 +172,14 @@ run:<span class="hljs-number">929</span>, 
AbstractApplicationContext$<span class
 <li>Respond to external signals, such as Ctrl+C(actually sent as SIGINT 
signal), or <code>SIGTERM</code> signal (<code>kill $PID</code> will send 
<code>SIGTERM</code> signal by default)</li>
 </ol>
 <p>Therefore, the normal application will execute the above ShutdownHook 
during the stop process (except <code>kill -9 $PID</code>). Its function is not 
only to close the Tomcat, but also to perform other cleanup work. It is 
unnecessary to go into details.</p>
-<h3>Summary</h3>
+<h2>Summary</h2>
 <ol>
 <li>During the startup of <code>DubboConsumer</code>, an independent 
non-daemon thread is launched to query the status of the variable continuously, 
thus the process can't exit.</li>
 <li>To stop the <code>DubboConsumer</code>, one should call ShutdownHook to 
change the variable to let the thread break the loop.</li>
 </ol>
-<h3>Problems</h3>
+<h2>Problems</h2>
 <p>In the example of DubboProvider, we see that Provider doesn't start Tomcat 
to provide HTTP service, then how does the program stays alive without exiting? 
We will answer this question in the next article.</p>
-<h4>Notice</h4>
+<h3>Notice</h3>
 <p>By running the following unit test which create a thread in <code>Intellij 
IDEA</code> , we are surprised to find that the program exits with less than 
1000s. Why?(The thread being created is a non-daemon thread)</p>
 <pre><code class="language-java">    <span class="hljs-meta">@Test</span>
     <span class="hljs-function"><span class="hljs-keyword">public</span> <span 
class="hljs-keyword">void</span> <span class="hljs-title">test</span><span 
class="hljs-params">()</span> </span>{
diff --git a/en-us/blog/spring-boot-dubbo-start-stop-analysis.json 
b/en-us/blog/spring-boot-dubbo-start-stop-analysis.json
index a448956..0f03710 100644
--- a/en-us/blog/spring-boot-dubbo-start-stop-analysis.json
+++ b/en-us/blog/spring-boot-dubbo-start-stop-analysis.json
@@ -1,4 +1,4 @@
 {
   "filename": "spring-boot-dubbo-start-stop-analysis.md",
-  "__html": "<h1>Source code analysis of spring-boot+Dubbo App start and 
stop</h1>\n<h3>Introduction</h3>\n<p><a 
href=\"https://github.com/apache/incubator-dubbo-spring-boot-project\";>Dubbo 
Spring Boot</a> project is dedicated to simplifying the development of the 
Dubbo RPC framework in the Spring Boot application. It also integrates the 
feature of Spring Boot:</p>\n<ul>\n<li><a 
href=\"https://github.com/apache/incubator-dubbo-spring-boot-project/blob/master/dubbo-spring-boot-autoconfigu
 [...]
+  "__html": "<h1>Source code analysis of spring-boot+Dubbo App start and 
stop</h1>\n<h2>Introduction</h2>\n<p><a 
href=\"https://github.com/apache/incubator-dubbo-spring-boot-project\";>Dubbo 
Spring Boot</a> project is dedicated to simplifying the development of the 
Dubbo RPC framework in the Spring Boot application. It also integrates the 
feature of Spring Boot:</p>\n<ul>\n<li><a 
href=\"https://github.com/apache/incubator-dubbo-spring-boot-project/blob/master/dubbo-spring-boot-autoconfigu
 [...]
 }
\ No newline at end of file
diff --git a/zh-cn/blog/dubbo-basic-usage-dubbo-provider-configuration.html 
b/zh-cn/blog/dubbo-basic-usage-dubbo-provider-configuration.html
index 565a526..b66d179 100644
--- a/zh-cn/blog/dubbo-basic-usage-dubbo-provider-configuration.html
+++ b/zh-cn/blog/dubbo-basic-usage-dubbo-provider-configuration.html
@@ -12,14 +12,15 @@
        <link rel="stylesheet" href="/build/blogDetail.css" />
 </head>
 <body>
-       <div id="root"><div class="blog-detail-page" data-reactroot="" 
data-reactid="1" data-react-checksum="1330502866"><header 
class="header-container header-container-normal" data-reactid="2"><div 
class="header-body" data-reactid="3"><a href="/zh-cn/index.html" 
data-reactid="4"><img class="logo" src="/img/dubbo_colorful.png" 
data-reactid="5"/></a><span class="language-switch language-switch-normal" 
data-reactid="6">En</span><div class="header-menu" data-reactid="7"><img 
class="header-menu-to [...]
-<h1>Dubbo基本用法</h1>
+       <div id="root"><div class="blog-detail-page" data-reactroot="" 
data-reactid="1" data-react-checksum="-1994522696"><header 
class="header-container header-container-normal" data-reactid="2"><div 
class="header-body" data-reactid="3"><a href="/zh-cn/index.html" 
data-reactid="4"><img class="logo" src="/img/dubbo_colorful.png" 
data-reactid="5"/></a><span class="language-switch language-switch-normal" 
data-reactid="6">En</span><div class="header-menu" data-reactid="7"><img 
class="header-menu-t [...]
+<hr>
+<h2>Dubbo基本用法</h2>
 <p>本章节主要讲述如何配置dubbo,按照配置方式上分,可以分为:XML配置,properties方式配置,注解方式配置,API调用方式配置。
 按照功能角度进行划分,可以分为Dubbo Provider和Dubbo Consumer。接下来章节中,分别对dubbo provider和Dubbo 
consumer进行讲解。</p>
-<h2>Dubbo Provider配置</h2>
-<h3>Provider 配置详解</h3>
+<h3>Dubbo Provider配置</h3>
+<h4>Provider 配置详解</h4>
 <p>配置Dubbo Provider有4种方式:XML配置,properties方式配置,API调用方式配置,注解方式配置。</p>
-<h4>XML配置</h4>
+<h5>XML配置</h5>
 <h6>最简单的配置的样例:</h6>
 <pre><code>&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
 &lt;beans xmlns=&quot;http://www.springframework.org/schema/beans&quot;
@@ -264,7 +265,7 @@ dubbo.protocol.port=28080
 <li>如果 classpath 根目录下存在多个 dubbo.properties,比如多个 jar 包中有 dubbo.properties,Dubbo 
会任意加载,并打印 Error 日志,后续可能改为抛异常。 ↩</li>
 <li>协议的 id 没配时,缺省使用协议名作为 id</li>
 </ol>
-<h4>annotation</h4>
+<h5>注解配置</h5>
 <h6>Service注解暴露服务</h6>
 <pre><code>import com.alibaba.dubbo.config.annotation.Service;
 
@@ -304,7 +305,7 @@ public class ProviderTestApp {
 <p>或者使用spring bean xml配置方式:</p>
 <pre><code>&lt;dubbo:annotation package=&quot;com.chanshuyi.service.impl&quot; 
/&gt;
 </code></pre>
-<h4>api直接触发</h4>
+<h5>代码配置</h5>
 <pre><code>import com.alibaba.dubbo.rpc.config.ApplicationConfig;
 import com.alibaba.dubbo.rpc.config.RegistryConfig;
 import com.alibaba.dubbo.rpc.config.ProviderConfig;
diff --git a/zh-cn/blog/dubbo-basic-usage-dubbo-provider-configuration.json 
b/zh-cn/blog/dubbo-basic-usage-dubbo-provider-configuration.json
index 6fb50bf..5da54f5 100644
--- a/zh-cn/blog/dubbo-basic-usage-dubbo-provider-configuration.json
+++ b/zh-cn/blog/dubbo-basic-usage-dubbo-provider-configuration.json
@@ -1,4 +1,4 @@
 {
   "filename": "dubbo-basic-usage-dubbo-provider-configuration.md",
-  "__html": "<h2>Dubbo基本用法-Dubbo 
Provider配置</h2>\n<h1>Dubbo基本用法</h1>\n<p>本章节主要讲述如何配置dubbo,按照配置方式上分,可以分为:XML配置,properties方式配置,注解方式配置,API调用方式配置。\n按照功能角度进行划分,可以分为Dubbo
 Provider和Dubbo Consumer。接下来章节中,分别对dubbo provider和Dubbo 
consumer进行讲解。</p>\n<h2>Dubbo Provider配置</h2>\n<h3>Provider 
配置详解</h3>\n<p>配置Dubbo 
Provider有4种方式:XML配置,properties方式配置,API调用方式配置,注解方式配置。</p>\n<h4>XML配置</h4>\n<h6>最简单的配置的样例:</h6>\n<pre><code>&lt;?xml
 version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;\n&lt;beans xmlns=&qu 
[...]
+  "__html": "<h1>Dubbo基本用法-Dubbo 
Provider配置</h1>\n<hr>\n<h2>Dubbo基本用法</h2>\n<p>本章节主要讲述如何配置dubbo,按照配置方式上分,可以分为:XML配置,properties方式配置,注解方式配置,API调用方式配置。\n按照功能角度进行划分,可以分为Dubbo
 Provider和Dubbo Consumer。接下来章节中,分别对dubbo provider和Dubbo 
consumer进行讲解。</p>\n<h3>Dubbo Provider配置</h3>\n<h4>Provider 
配置详解</h4>\n<p>配置Dubbo 
Provider有4种方式:XML配置,properties方式配置,API调用方式配置,注解方式配置。</p>\n<h5>XML配置</h5>\n<h6>最简单的配置的样例:</h6>\n<pre><code>&lt;?xml
 version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;\n&lt;beans xml [...]
 }
\ No newline at end of file
diff --git a/zh-cn/blog/dubbo-contribue-to-opensource.html 
b/zh-cn/blog/dubbo-contribue-to-opensource.html
index bc30704..382a74c 100644
--- a/zh-cn/blog/dubbo-contribue-to-opensource.html
+++ b/zh-cn/blog/dubbo-contribue-to-opensource.html
@@ -12,25 +12,26 @@
        <link rel="stylesheet" href="/build/blogDetail.css" />
 </head>
 <body>
-       <div id="root"><div class="blog-detail-page" data-reactroot="" 
data-reactid="1" data-react-checksum="253774876"><header 
class="header-container header-container-normal" data-reactid="2"><div 
class="header-body" data-reactid="3"><a href="/zh-cn/index.html" 
data-reactid="4"><img class="logo" src="/img/dubbo_colorful.png" 
data-reactid="5"/></a><span class="language-switch language-switch-normal" 
data-reactid="6">En</span><div class="header-menu" data-reactid="7"><img 
class="header-menu-tog [...]
+       <div id="root"><div class="blog-detail-page" data-reactroot="" 
data-reactid="1" data-react-checksum="-1828827822"><header 
class="header-container header-container-normal" data-reactid="2"><div 
class="header-body" data-reactid="3"><a href="/zh-cn/index.html" 
data-reactid="4"><img class="logo" src="/img/dubbo_colorful.png" 
data-reactid="5"/></a><span class="language-switch language-switch-normal" 
data-reactid="6">En</span><div class="header-menu" data-reactid="7"><img 
class="header-menu-t [...]
+<hr>
 <p>Github 上有众多优秀的开源项目,大多数 IT 从业者将其当做了予取予求的工具库,遇到什么需求,先去 Github 
搜一把,但有没有想过有一天自己也可以给开源事业做一些贡献呢?本文将会以 incubator-dubbo 
项目为例,向你阐释,给开源项目做贡献并不是一件难事。</p>
-<h3>1 为何要给开源贡献力量</h3>
+<h2>1 为何要给开源贡献力量</h2>
 <p>为开源项目做贡献得到的收益是多方面的,为了让你有足够的信心加入到开源项目中,我在文章最开始列举出它的诸多好处。</p>
-<h4>1.1 巩固技能</h4>
+<h3>1.1 巩固技能</h3>
 <p>无论你是提交代码,撰写文档,提交 
Issue,组织活动,当你切身参与到一个开源项目中,相关的技能都会得到历练,并且在开源项目中找到自己的位置。一方面,日常工作中我们中的大多数人接触到的是业务场景,并没有太多机会接触到基础架构组件,开源项目为我们提供了一个平台,在这里,你可以尽情挑选自己熟悉的项目为它添砖加瓦(以
 Dubbo 为例,并不是所有 IT 
公司都有能力自研服务治理框架);另一方面,你所提交的代码,会有管理员协助审核,他们会给出专业的建议,更好的代码规范以及更优的编程思路最终都会变成你的经验。</p>
-<h4>1.2 结交朋友</h4>
+<h3>1.2 结交朋友</h3>
 <p>开源社区为你提供了一个平台,在这里,你可以认识很多纯粹的技术爱好者,开源贡献者是最符合 geek 
定义的那群人,你所接触到的往往是某个领域最厉害的那批人。</p>
-<h4>1.3 建立口碑</h4>
+<h3>1.3 建立口碑</h3>
 <p>这是一个很好的展示个人实力的地方,俗话说:talk is cheap,show me the code. 作为技术人员,没有什么比一个漂亮的 
Github 主页更有说服力的了。如果你能够为开源项目做出可观的贡献,你也将收获到业界的知名度,此时开源项目的成就和你是密不可分的。</p>
-<h4>1.4 传承开源精神</h4>
+<h3>1.4 传承开源精神</h3>
 <p>只有源源不断的贡献者给开源项目添砖加瓦,才可以为 Github 一类的开源社区形成良好的开源风气。否则,只有输出没有输入,开源会失去活力。</p>
-<h4>1.5 养成习惯</h4>
+<h3>1.5 养成习惯</h3>
 <p>相信我,一旦养成了每天提交代码的习惯,就像你不想中断打卡一样,你绝不想中断 commit。不止有英语打卡,健身打卡,还有开源打卡!</p>
 <p><img src="http://ov0zuistv.bkt.clouddn.com/image-20180827141007663.png"; 
alt="开源程序员的日常"></p>
-<h3>2 贡献代码时的一些疑难杂症</h3>
+<h2>2 贡献代码时的一些疑难杂症</h2>
 <p>如果你是一名开源界的新手,可能会对贡献的流程心生畏惧。比如:我该怎么修改代码并提交?我的代码要是存在bug怎么办?我的代码别人会不会很 
low?我该如何寻找合适的开源项目?开源社区那么多的工具和词汇都是什么意思?</p>
 <p>文章的第二部分将从一个<strong>小白</strong>的角度,介绍一下开源中的一些常见问题。</p>
-<h4>2.1 git 常规操作</h4>
+<h3>2.1 git 常规操作</h3>
 <p>一般而言,我们选择使用 git 来作为版本管理的工具,你不一定要非常熟练的使用它,在我看来掌握 clone,add,commit,pull,push 
即可,遇到复杂的场景,你还有谷歌。</p>
 <p><strong>fork 与 clone</strong></p>
 <p><img src="http://ov0zuistv.bkt.clouddn.com/image-20180827143942178.png"; 
alt="fork 与 clone"></p>
@@ -52,27 +53,27 @@ git merge upstream/master
 <p><strong>源仓库视角的 pull request</strong></p>
 <p><img src="http://ov0zuistv.bkt.clouddn.com/image-20180827155239155.png"; 
alt="pull request management"></p>
 <p>管理者会对 pull request 涉及的改动进行 review,以确保你的代码是符合规范的,逻辑有没有偏差,以及符合框架的功能需求。</p>
-<h4>2.2 Travis CI</h4>
+<h3>2.2 Travis CI</h3>
 <p>一些自动化的 CI 流程被植入在每一次 pull request 
的构建之中,用于给开源仓库去校验提交者的代码是否符合既定的规范,如:是否有编译问题,单元测试是否通过,覆盖率是否达标,代码风格是否合规等等。</p>
 <p><img src="http://ov0zuistv.bkt.clouddn.com/image-20180827160503114.png"; 
alt="CI报告"></p>
 <p>一般情况下,必须通过 CI,你的 pull request 才会被管理 review。</p>
-<h4>2.3 Mailing list</h4>
+<h3>2.3 Mailing list</h3>
 <p>每个开源项目都会有自己的贡献规范,可以参考首页的 Contributing,来获取具体的信息。incubator-dubbo 作为一个孵化中的 
apache 项目,遵守了 apache 的传统,在 <a 
href="https://github.com/apache/incubator-dubbo/blob/master/CONTRIBUTING.md";>Contributing</a>
 中描述道:当你有新特性想要贡献给 Dubbo 时,官方推荐使用 Mailing list 的方式描述一遍你想要做的改动。</p>
 <p>Mailing list 简单来说,就是一个邮件通知机制,所有的 Dubbo 
开发者都会订阅该邮箱:d...@dubbo.incubator.apache.org。有任何新特性的改动,或者什么建议想要通知其他开发者,都可以通过向该邮箱发送邮件来达到这个目的,相同地,你也会收到其转发的其他开发者的邮件。</p>
 <p>或者你是一个 Dubbo 的使用者,你想要得知开发者的改造方向,也可以订阅,这个<a 
href="https://github.com/apache/incubator-dubbo/wiki/Mailing-list-subscription-guide";>指南</a>可以帮助你订阅
 Dubbo 的 Mailing list。</p>
 <blockquote>
 <p>作为一个 modern developer,你可能觉得 mailing list 的交流方式存在滞后性,这样的沟通方式不是特别的高效,但它作为 
apache 项目的推荐交流方式存在其特殊的原因,在此不多赘述。总之遵循一个原则:bug fix或者讨论,可以在 github issue 
中进行,影响较大的特性和讨论则推荐在 mailing list 中展开。</p>
 </blockquote>
-<h3>3 其他贡献形式</h3>
+<h2>3 其他贡献形式</h2>
 <p>不仅仅只有贡献代码,修复 bug 等行为才算作为开源做贡献,以下这些行为也属于主要形式:</p>
-<h4>3.1 撰写文档</h4>
+<h3>3.1 撰写文档</h3>
 <p><a 
href="http://dubbo.apache.org/zh-cn/";>Dubbo文档</a>是其开源组成成分的重要一环,其内容源文件位于:<a 
href="https://github.com/apache/incubator-dubbo-website%E3%80%82%E5%90%8C%E6%A0%B7%E4%B9%9F%E6%98%AF%E4%B8%80%E4%B8%AA";>https://github.com/apache/incubator-dubbo-website。同样也是一个</a>
 Git 仓库,任何你想要对 dubbo 知识点的补充,都可以在这儿提交 pull request,只需要一些 markdown 的语法知识,和一些可有可无的 
npm 语法即可。如果你觉得贡献代码对于现在的自己仍然有点难度,不妨从贡献文档开始接触开源。</p>
-<h4>3.2 ISSUE</h4>
+<h3>3.2 ISSUE</h3>
 <p>无论是 Github 中的 Issue 还是 mailing list 中的讨论,无论是提出问题,汇报 bug,还是回答问题(bugfix 
则不仅仅需要 Issue 了),协助管理者 review pull request,都是贡献的一种形式,勿以善小而不为。</p>
-<h4>3.3 其他行为</h4>
+<h3>3.3 其他行为</h3>
 <p>任何你能够想到的,可以帮助开源项目变得更好的的行为,都属于开源贡献。例如,给每个 Issue 打上合适的 tag,关闭重复的 Issue,链接相关联的 
Issue,线下组织沙龙,回答 Stack Overflow 上相关的问题,以及文档中一个错别字的修改等等。</p>
-<h3>4 开源最佳实践</h3>
-<h4>4.1 有效沟通</h4>
+<h2>4 开源最佳实践</h2>
+<h3>4.1 有效沟通</h3>
 <p>无论你处于什么样的目的:仅仅是一次性的贡献,亦或是永久性的加入社区,都的和他人进行沟通和交往,这是你要在开源圈发展必须修炼的技能。</p>
 <p>在你开启一个isse或PR之前,或者是在聊天室问问题之前,请牢记下面所列出的几点建议,会让你的工作更加的高效。</p>
 <p><strong>给出上下文</strong> 
以便于让其他人能够快速的理解。比方说你运行程序时遇到一个错误,要解释你是如何做的,并描述如何才能再现错误现象。又比方说你是提交一个新的想法,要解释你为什么这么想,对于项目有用处吗(不仅仅是只有你!)</p>
@@ -106,7 +107,7 @@ git merge upstream/master
 <p>😢 <em>“你为什么不支持我的用例?这是不可接受的!”</em></p>
 </blockquote>
 <p><strong>以上几点,要铭记在心。</strong> 
开源是由来自世界各地的人们共同协作实现的。面临的问题是跨语言、跨文化、不同的地理为止、不同的时区,另外,撰写文字的沟通更是难上加难,无法传达语气和情绪。请让这些会话都充满善意吧!在以下情形中请保持礼貌:推动一个想法、请求更多的上下文、进一步澄清你的立场。既然你在互联网找到了自己的所需,那么请尝试让它变得更好!</p>
-<h4>4.2 创建 issue</h4>
+<h3>4.2 创建 issue</h3>
 <p>你应该在遇到下列情况下,去创建一个 issue:</p>
 <ul>
 <li>报告你自己无法解决的错误</li>
@@ -119,7 +120,7 @@ git merge upstream/master
 <li><strong>如果说某个issue已经开放很久了,</strong> 
这可能是已经有人正在解决中,又或者是早已经解决过了,所以也请添加评论,在打算开始工作之前,最好是确认一下。</li>
 <li><strong>如果你创建了一个issue,但是没多久自己解决了,</strong> 
也要添加评论,让其他人知道,然后关闭该issue。记录本身就是对社区的贡献。</li>
 </ul>
-<h4>4.3 创建 pull request</h4>
+<h3>4.3 创建 pull request</h3>
 <p>在下面的情形时,请你务必使用 PR:</p>
 <ul>
 <li>提交补丁 (例如,纠正拼写错误、损坏的链接、或者是其它较明显的错误)</li>
@@ -135,7 +136,7 @@ git merge upstream/master
 <li><strong>测试你的改动!</strong> 
若测试用例存在的话,跑一遍,以覆盖你的更改,若没有的话,则创建相应的用例。无论测试是否存在,一定要确保你的改动不会破坏掉现有的项目。</li>
 <li><strong>和项目现有的风格保持一致</strong> 
尽你最大的努力,这也就是意味着在使用缩进、分号、以及注释很可能和你自己的风格大相径庭,但是为了节省维护者的精力,以及未来他人更好的理解和维护,还请你容忍一下。</li>
 </ul>
-<h3>5 成为一个开源贡献者</h3>
+<h2>5 成为一个开源贡献者</h2>
 
<p>如果你有志于参与开源事业,可以尝试从自己最熟悉的项目开始,开源并不是属于高级开发者的专属词汇,它就是由你我这样的人在需求,修复,构建中演进下去的。Let's
 try it !</p>
 </section><footer class="footer-container" data-reactid="19"><div 
class="footer-body" data-reactid="20"><img src="/img/dubbo_gray.png" 
data-reactid="21"/><img class="apache" src="/img/apache_logo.png" 
data-reactid="22"/><div class="cols-container" data-reactid="23"><div 
class="col col-12" data-reactid="24"><h3 data-reactid="25">Disclaimer</h3><p 
data-reactid="26">Apache Dubbo is an effort undergoing incubation at The Apache 
Software Foundation (ASF), sponsored by the Incubator. Incubatio [...]
        <script 
src="https://f.alicdn.com/react/15.4.1/react-with-addons.min.js";></script>
diff --git a/zh-cn/blog/dubbo-contribue-to-opensource.json 
b/zh-cn/blog/dubbo-contribue-to-opensource.json
index f6f1ca5..5622e3d 100644
--- a/zh-cn/blog/dubbo-contribue-to-opensource.json
+++ b/zh-cn/blog/dubbo-contribue-to-opensource.json
@@ -1,4 +1,4 @@
 {
   "filename": "dubbo-contribue-to-opensource.md",
-  "__html": "<h2>以Dubbo为例,聊聊如何向开源项目做贡献</h2>\n<p>Github 上有众多优秀的开源项目,大多数 IT 
从业者将其当做了予取予求的工具库,遇到什么需求,先去 Github 搜一把,但有没有想过有一天自己也可以给开源事业做一些贡献呢?本文将会以 
incubator-dubbo 项目为例,向你阐释,给开源项目做贡献并不是一件难事。</p>\n<h3>1 
为何要给开源贡献力量</h3>\n<p>为开源项目做贡献得到的收益是多方面的,为了让你有足够的信心加入到开源项目中,我在文章最开始列举出它的诸多好处。</p>\n<h4>1.1
 巩固技能</h4>\n<p>无论你是提交代码,撰写文档,提交 
Issue,组织活动,当你切身参与到一个开源项目中,相关的技能都会得到历练,并且在开源项目中找到自己的位置。一方面,日常工作中我们中的大多数人接触到的是业务场景,并没有太多机会接触到基础架�
 ��组件,开源项目为我们提供了一个平台,在这里,你可以尽情挑选自己熟悉的项目为它添砖加瓦(以 Dubbo 为例,并不是所有 IT 
公司都有能力自研服务治理框架); [...]
+  "__html": "<h1>以Dubbo为例,聊聊如何向开源项目做贡献</h1>\n<hr>\n<p>Github 上有众多优秀的开源项目,大多数 
IT 从业者将其当做了予取予求的工具库,遇到什么需求,先去 Github 搜一把,但有没有想过有一天自己也可以给开源事业做一些贡献呢?本文将会以 
incubator-dubbo 项目为例,向你阐释,给开源项目做贡献并不是一件难事。</p>\n<h2>1 
为何要给开源贡献力量</h2>\n<p>为开源项目做贡献得到的收益是多方面的,为了让你有足够的信心加入到开源项目中,我在文章最开始列举出它的诸多好处。</p>\n<h3>1.1
 巩固技能</h3>\n<p>无论你是提交代码,撰写文档,提交 
Issue,组织活动,当你切身参与到一个开源项目中,相关的技能都会得到历练,并且在开源项目中找到自己的位置。一方面,日常工作中我们中的大多数人接触到的是业务场景,并没有太多机会接触到基�
 ��架构组件,开源项目为我们提供了一个平台,在这里,你可以尽情挑选自己熟悉的项目为它添砖加瓦(以 Dubbo 为例,并不是所有 IT 公司都有能力自研服务 
[...]
 }
\ No newline at end of file
diff --git a/zh-cn/blog/dubbo-generic-invoke.html 
b/zh-cn/blog/dubbo-generic-invoke.html
index b0e865f..962718c 100644
--- a/zh-cn/blog/dubbo-generic-invoke.html
+++ b/zh-cn/blog/dubbo-generic-invoke.html
@@ -12,7 +12,7 @@
        <link rel="stylesheet" href="/build/blogDetail.css" />
 </head>
 <body>
-       <div id="root"><div class="blog-detail-page" data-reactroot="" 
data-reactid="1" data-react-checksum="-1656407808"><header 
class="header-container header-container-normal" data-reactid="2"><div 
class="header-body" data-reactid="3"><a href="/zh-cn/index.html" 
data-reactid="4"><img class="logo" src="/img/dubbo_colorful.png" 
data-reactid="5"/></a><span class="language-switch language-switch-normal" 
data-reactid="6">En</span><div class="header-menu" data-reactid="7"><img 
class="header-menu-t [...]
+       <div id="root"><div class="blog-detail-page" data-reactroot="" 
data-reactid="1" data-react-checksum="228800740"><header 
class="header-container header-container-normal" data-reactid="2"><div 
class="header-body" data-reactid="3"><a href="/zh-cn/index.html" 
data-reactid="4"><img class="logo" src="/img/dubbo_colorful.png" 
data-reactid="5"/></a><span class="language-switch language-switch-normal" 
data-reactid="6">En</span><div class="header-menu" data-reactid="7"><img 
class="header-menu-tog [...]
 <p>以下几种场景可以考虑使用泛化调用:</p>
 <ul>
 <li>服务测试平台</li>
@@ -20,7 +20,7 @@
 </ul>
 <p>泛化调用主要用于消费端没有 API 接口的情况;不需要引入接口 jar 包,而是直接通过 GenericService 
接口来发起服务调用,参数及返回值中的所有 POJO 均用 <code>Map</code> 表示。泛化调用对于服务端无需关注,按正常服务进行暴露即可。</p>
 <p>下面来看看消费端如何使用泛化调用进行服务调用。</p>
-<h4>通过 Spring XML 配置进行泛化调用</h4>
+<h2>通过 Spring XML 配置进行泛化调用</h2>
 <p>在 Spring 配置申明 <code>generic=&quot;true&quot;</code>,如:</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">"userService"</span> 
<span class="hljs-attr">interface</span>=<span 
class="hljs-string">"com.alibaba.dubbo.samples.generic.api.IUserService"</span> 
<span class="hljs-attr">generic</span>=<span 
class="hljs-string">"true"</span>/&gt;</span>
 </code></pre>
@@ -41,7 +41,7 @@ System.out.println(name);
 </ol>
 </li>
 </ol>
-<h4>通过 API 编程进行泛化调用</h4>
+<h2>通过 API 编程进行泛化调用</h2>
 <pre><code>ApplicationConfig application = new 
ApplicationConfig()ApplicationConfig application = new ApplicationConfig();
 application.setName(&quot;api-generic-consumer&quot;);
 
@@ -65,7 +65,7 @@ String name = (String) 
genericService.$invoke(&quot;delete&quot;, new String[]{i
 System.out.println(name);
 </code></pre>
 <p>通过 API 的方式,不需要像 XML 的方式需要提前将服务配置好,可以动态构建 ReferenceConfig;相对 XML 来说,API 
的方式更常见。</p>
-<h4>参数或返回值是 POJO 的场景</h4>
+<h2>参数或返回值是 POJO 的场景</h2>
 <p>比如方法签名是 <code>User get(Params params);</code>其中 User 有 id 和 name 
两个属性,Params 有 query 一个属性。</p>
 <p>以下是消费端的调用代码:</p>
 <pre><code class="language-java">String[] parameterTypes = <span 
class="hljs-keyword">new</span> String[]{<span 
class="hljs-string">"com.alibaba.dubbo.samples.generic.api.Params"</span>};
@@ -81,7 +81,7 @@ System.out.println(<span class="hljs-string">"sample one 
result: "</span> + user
 <p>这里,Dubbo 框架会自动将 POJO 的返回值转换成 Map。可以看到,返回值 <code>user</code> 是一个 
HashMap,里面分别存放了 name、id、class 三个 k/v。</p>
 <h4>泛接口实现</h4>
 <p>泛接口实现方式主要用于服务端没有 API 接口的情况,参数及返回值中的所有 POJO 均用 Map 表示,通常用于框架集成,如实现一个通用的远程服务 
Mock 框架,可通过实现 GenericService 接口处理所有服务请求。</p>
-<h5>服务端实现 GenericService</h5>
+<h3>服务端实现 GenericService</h3>
 <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">GenericServiceImpl</span> <span 
class="hljs-keyword">implements</span> <span 
class="hljs-title">GenericService</span> </span>{
     <span class="hljs-meta">@Override</span>
     <span class="hljs-keyword">public</span> Object $invoke(String method, 
String[] parameterTypes, Object[] args) <span 
class="hljs-keyword">throws</span> GenericException {
@@ -95,7 +95,7 @@ System.out.println(<span class="hljs-string">"sample one 
result: "</span> + user
     }
 }
 </code></pre>
-<h5>服务端暴露服务</h5>
+<h3>服务端暴露服务</h3>
 <pre><code class="language-java">ApplicationConfig application = <span 
class="hljs-keyword">new</span> ApplicationConfig();
 application.setName(<span class="hljs-string">"api-generic-provider"</span>);
 
@@ -119,7 +119,7 @@ service2.setRef(genericService);
 service2.export();
 </code></pre>
 <p>同样,也可以使用 XML 配置的方式暴露服务;此时服务端是没有依赖 HiService 和 HelloService 这两个接口的。</p>
-<h5>消费端进行服务调用</h5>
+<h3>消费端进行服务调用</h3>
 <pre><code class="language-java">ApplicationConfig application = <span 
class="hljs-keyword">new</span> ApplicationConfig();
 application.setName(<span class="hljs-string">"api-generic-consumer"</span>);
 
@@ -146,7 +146,7 @@ System.out.println(helloService.hello(<span 
class="hljs-string">"community"</spa
 </code></pre>
 <p>同样,消费端也可以使用 XML 
配置的方式引用服务,然后进行调用。这里可以看到调用方式为普通的服务调用,并非泛化调用。当然使用泛化调用也是可以的。</p>
 <p>到这里为止,一个简易的服务 Mock 平台就成功上线了!</p>
-<h4>其他</h4>
+<h2>其他</h2>
 <ul>
 <li>本文介绍的泛化调用和泛接口实现,都是在原生的 <code>Dubbo</code> 协议之上的。在 2.6.2 版本之前,其他协议如 
http/hessian 等是不支持泛化调用的,2.6.3 版本将会对这两个协议的泛化调用做支持。</li>
 <li>本文中提到的相关示例代码可以在 dubbo-samples中找到:<a 
href="https://github.com/dubbo/dubbo-samples/tree/master/dubbo-samples-generic";>https://github.com/dubbo/dubbo-samples/tree/master/dubbo-samples-generic</a></li>
diff --git a/zh-cn/blog/dubbo-generic-invoke.json 
b/zh-cn/blog/dubbo-generic-invoke.json
index 5372105..e645e56 100644
--- a/zh-cn/blog/dubbo-generic-invoke.json
+++ b/zh-cn/blog/dubbo-generic-invoke.json
@@ -1,4 +1,4 @@
 {
   "filename": "dubbo-generic-invoke.md",
-  "__html": 
"<h1>Dubbo的泛化调用</h1>\n<p>以下几种场景可以考虑使用泛化调用:</p>\n<ul>\n<li>服务测试平台</li>\n<li>API 
服务网关</li>\n</ul>\n<p>泛化调用主要用于消费端没有 API 接口的情况;不需要引入接口 jar 包,而是直接通过 
GenericService 接口来发起服务调用,参数及返回值中的所有 POJO 均用 <code>Map</code> 
表示。泛化调用对于服务端无需关注,按正常服务进行暴露即可。</p>\n<p>下面来看看消费端如何使用泛化调用进行服务调用。</p>\n<h4>通过 
Spring XML 配置进行泛化调用</h4>\n<p>在 Spring 配置申明 
<code>generic=&quot;true&quot;</code>,如:</p>\n<pre><code 
class=\"language-xml\"><span class=\"hljs-tag\">&lt;<span 
class=\"hljs-name\">dubbo:reference</span> [...]
+  "__html": 
"<h1>Dubbo的泛化调用</h1>\n<p>以下几种场景可以考虑使用泛化调用:</p>\n<ul>\n<li>服务测试平台</li>\n<li>API 
服务网关</li>\n</ul>\n<p>泛化调用主要用于消费端没有 API 接口的情况;不需要引入接口 jar 包,而是直接通过 
GenericService 接口来发起服务调用,参数及返回值中的所有 POJO 均用 <code>Map</code> 
表示。泛化调用对于服务端无需关注,按正常服务进行暴露即可。</p>\n<p>下面来看看消费端如何使用泛化调用进行服务调用。</p>\n<h2>通过 
Spring XML 配置进行泛化调用</h2>\n<p>在 Spring 配置申明 
<code>generic=&quot;true&quot;</code>,如:</p>\n<pre><code 
class=\"language-xml\"><span class=\"hljs-tag\">&lt;<span 
class=\"hljs-name\">dubbo:reference</span> [...]
 }
\ No newline at end of file
diff --git a/zh-cn/blog/dubbo-invoke.html b/zh-cn/blog/dubbo-invoke.html
index d41c236..9264a37 100644
--- a/zh-cn/blog/dubbo-invoke.html
+++ b/zh-cn/blog/dubbo-invoke.html
@@ -12,7 +12,7 @@
        <link rel="stylesheet" href="/build/blogDetail.css" />
 </head>
 <body>
-       <div id="root"><div class="blog-detail-page" data-reactroot="" 
data-reactid="1" data-react-checksum="835866257"><header 
class="header-container header-container-normal" data-reactid="2"><div 
class="header-body" data-reactid="3"><a href="/zh-cn/index.html" 
data-reactid="4"><img class="logo" src="/img/dubbo_colorful.png" 
data-reactid="5"/></a><span class="language-switch language-switch-normal" 
data-reactid="6">En</span><div class="header-menu" data-reactid="7"><img 
class="header-menu-tog [...]
+       <div id="root"><div class="blog-detail-page" data-reactroot="" 
data-reactid="1" data-react-checksum="-1740419465"><header 
class="header-container header-container-normal" data-reactid="2"><div 
class="header-body" data-reactid="3"><a href="/zh-cn/index.html" 
data-reactid="4"><img class="logo" src="/img/dubbo_colorful.png" 
data-reactid="5"/></a><span class="language-switch language-switch-normal" 
data-reactid="6">En</span><div class="header-menu" data-reactid="7"><img 
class="header-menu-t [...]
 <p>我们知道,Dubbo 缺省协议采用单一长连接,底层实现是 Netty 的 NIO 异步通讯机制;基于这种机制,Dubbo 
实现了以下几种调用方式:</p>
 <ul>
 <li>同步调用</li>
@@ -20,7 +20,7 @@
 <li>参数回调</li>
 <li>事件通知</li>
 </ul>
-<h3>同步调用</h3>
+<h2>同步调用</h2>
 <p>同步调用是一种阻塞式的调用方式,即 Consumer 端代码一直阻塞等待,直到 Provider 端返回为止;</p>
 <p>通常,一个典型的同步调用过程如下:</p>
 <ol>
@@ -34,20 +34,20 @@
 <li>Consumer 收到结果后,如何唤醒业务线程往后执行的?</li>
 </ol>
 <p>其实,Dubbo 的底层 IO 操作都是异步的。Consumer 端发起调用后,得到一个 Future 
对象。对于同步调用,业务线程通过<code>Future#get(timeout)</code>,阻塞等待 Provider 
端将结果返回;<code>timeout</code>则是 Consumer 端定义的超时时间。当结果返回后,会设置到此 
Future,并唤醒阻塞的业务线程;当超时时间到结果还未返回时,业务线程将会异常返回。</p>
-<h3>异步调用</h3>
+<h2>异步调用</h2>
 <p>基于 Dubbo 底层的异步 NIO 实现异步调用,对于 Provider 响应时间较长的场景是必须的,它能有效利用 Consumer 
端的资源,相对于 Consumer 端使用多线程来说开销较小。</p>
 <p>异步调用,对于 Provider 端不需要做特别的配置。下面的例子中,Provider 端接口定义如下:</p>
 <pre><code class="language-java"><span class="hljs-keyword">public</span> 
<span class="hljs-class"><span class="hljs-keyword">interface</span> <span 
class="hljs-title">AsyncService</span> </span>{
     <span class="hljs-function">String <span 
class="hljs-title">goodbye</span><span class="hljs-params">(String 
name)</span></span>;
 }
 </code></pre>
-<h5>Consumer 配置</h5>
+<h3>Consumer 配置</h3>
 <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">"asyncService"</span> 
<span class="hljs-attr">interface</span>=<span 
class="hljs-string">"com.alibaba.dubbo.samples.async.api.AsyncService"</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">"goodbye"</span> 
<span class="hljs-attr">async</span>=<span 
class="hljs-string">"true"</span>/&gt;</span>
 <span class="hljs-tag">&lt;/<span 
class="hljs-name">dubbo:reference</span>&gt;</span>
 </code></pre>
 <p>需要异步调用的方法,均需要使用 <code>&lt;dubbo:method/&gt;</code>标签进行描述。</p>
-<h5>Consumer 端发起调用</h5>
+<h3>Consumer 端发起调用</h3>
 <pre><code class="language-java">AsyncService service = ...;
 String result = service.goodbye(<span 
class="hljs-string">"samples"</span>);<span class="hljs-comment">// 
这里的返回值为空,请不要使用</span>
 Future&lt;String&gt; future = RpcContext.getContext().getFuture();
@@ -70,9 +70,9 @@ result = future.get(); <span class="hljs-comment">// 阻塞需要获取异步结
 <p>整个异步调用的时序图如下:</p>
 <p><img src="../../img/blog/dubbo-async.svg" alt="异步调用"></p>
 <p>此示例代码位于:<a 
href="https://github.com/dubbo/dubbo-samples/tree/master/dubbo-samples-async";>https://github.com/dubbo/dubbo-samples/tree/master/dubbo-samples-async</a></p>
-<h3>参数回调</h3>
+<h2>参数回调</h2>
 <p>参数回调有点类似于本地 Callback 机制,但 Callback 并不是 Dubbo 内部的类或接口,而是由 Provider 
端自定义的;Dubbo 将基于长连接生成反向代理,从而实现从 Provider 端调用 Consumer 端的逻辑。</p>
-<h5>Provider 端定义 Service 和 Callback</h5>
+<h3>Provider 端定义 Service 和 Callback</h3>
 <pre><code class="language-java"><span class="hljs-keyword">public</span> 
<span class="hljs-class"><span class="hljs-keyword">interface</span> <span 
class="hljs-title">CallbackService</span> </span>{
     <span class="hljs-function"><span class="hljs-keyword">void</span> <span 
class="hljs-title">addListener</span><span class="hljs-params">(String key, 
CallbackListener listener)</span></span>;
 }
@@ -81,7 +81,7 @@ result = future.get(); <span class="hljs-comment">// 阻塞需要获取异步结
     <span class="hljs-function"><span class="hljs-keyword">void</span> <span 
class="hljs-title">changed</span><span class="hljs-params">(String 
msg)</span></span>;
 }
 </code></pre>
-<h5>Provider 端 Service 实现</h5>
+<h4>Provider 端 Service 实现</h4>
 <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">CallbackServiceImpl</span> <span 
class="hljs-keyword">implements</span> <span 
class="hljs-title">CallbackService</span> </span>{
 
     <span class="hljs-keyword">private</span> <span 
class="hljs-keyword">final</span> Map&lt;String, CallbackListener&gt; listeners 
= <span class="hljs-keyword">new</span> ConcurrentHashMap&lt;String, 
CallbackListener&gt;();
@@ -119,7 +119,7 @@ result = future.get(); <span class="hljs-comment">// 
阻塞需要获取异步结
     }
 }
 </code></pre>
-<h5>Provider 端暴露服务</h5>
+<h4>Provider 端暴露服务</h4>
 <pre><code class="language-xml"><span class="hljs-tag">&lt;<span 
class="hljs-name">bean</span> <span class="hljs-attr">id</span>=<span 
class="hljs-string">"callbackService"</span> <span 
class="hljs-attr">class</span>=<span 
class="hljs-string">"com.alibaba.dubbo.samples.callback.impl.CallbackServiceImpl"</span>/&gt;</span>
 
 <span class="hljs-tag">&lt;<span class="hljs-name">dubbo:service</span> <span 
class="hljs-attr">interface</span>=<span 
class="hljs-string">"com.alibaba.dubbo.samples.callback.api.CallbackService"</span>
 <span class="hljs-attr">ref</span>=<span 
class="hljs-string">"callbackService"</span> <span 
class="hljs-attr">connections</span>=<span class="hljs-string">"1"</span> <span 
class="hljs-attr">callbacks</span>=<span 
class="hljs-string">"1000"</span>&gt;</span>
@@ -130,7 +130,7 @@ result = future.get(); <span class="hljs-comment">// 
阻塞需要获取异步结
 <span class="hljs-tag">&lt;/<span 
class="hljs-name">dubbo:service</span>&gt;</span>
 </code></pre>
 <p>这里,Provider 需要在方法中声明哪个参数是 Callback 参数。</p>
-<h5>Consumer 端实现 Callback 接口</h5>
+<h4>Consumer 端实现 Callback 接口</h4>
 <pre><code class="language-java">CallbackService callbackService = ...;
 callbackService.addListener(<span class="hljs-string">"foo.bar"</span>, <span 
class="hljs-keyword">new</span> CallbackListener() {
         <span class="hljs-function"><span class="hljs-keyword">public</span> 
<span class="hljs-keyword">void</span> <span 
class="hljs-title">changed</span><span class="hljs-params">(String msg)</span> 
</span>{
@@ -141,7 +141,7 @@ callbackService.addListener(<span 
class="hljs-string">"foo.bar"</span>, <span cl
 <p>Callback 接口的实现类在 Consumer 端,当方法发生调用时,Consumer 端会自动 export 一个 Callback 服务。而 
Provider 端在处理调用时,判断如果参数是 Callback,则生成了一个 proxy,因此服务实现类里在调用 Callback 方法的时候,会被传递到 
Consumer 端执行 Callback 实现类的代码。</p>
 <p>上述示例代码位于:<a 
href="https://github.com/dubbo/dubbo-samples/tree/master/dubbo-samples-callback";>https://github.com/dubbo/dubbo-samples/tree/master/dubbo-samples-callback</a></p>
 <p>这种调用方式有点像消息的发布和订阅,但又有区别。比如当 Consumer 端 完成了Callback 服务的 export 后,如果后续重启了,这时 
Provider 端就会调不通;同时 Provider 端如何清理掉这个 proxy 也是一个问题。</p>
-<h3>事件通知</h3>
+<h2>事件通知</h2>
 <p>事件通知允许 Consumer 端在调用之前、调用之后或出现异常时,触发 
<code>oninvoke</code>、<code>onreturn</code>、<code>onthrow</code> 三个事件。</p>
 <p>可以通过在配置 Consumer 时,指定事件需要通知的方法,如:</p>
 <pre><code class="language-xml"><span class="hljs-tag">&lt;<span 
class="hljs-name">bean</span> <span class="hljs-attr">id</span>=<span 
class="hljs-string">"demoCallback"</span> <span 
class="hljs-attr">class</span>=<span 
class="hljs-string">"com.alibaba.dubbo.samples.notify.impl.NotifyImpl"</span> 
/&gt;</span>
diff --git a/zh-cn/blog/dubbo-invoke.json b/zh-cn/blog/dubbo-invoke.json
index 5eaaf2d..a8aefcb 100644
--- a/zh-cn/blog/dubbo-invoke.json
+++ b/zh-cn/blog/dubbo-invoke.json
@@ -1,4 +1,4 @@
 {
   "filename": "dubbo-invoke.md",
-  "__html": "<h1>Dubbo 关于同步/异步调用的几种方式</h1>\n<p>我们知道,Dubbo 缺省协议采用单一长连接,底层实现是 
Netty 的 NIO 异步通讯机制;基于这种机制,Dubbo 
实现了以下几种调用方式:</p>\n<ul>\n<li>同步调用</li>\n<li>异步调用</li>\n<li>参数回调</li>\n<li>事件通知</li>\n</ul>\n<h3>同步调用</h3>\n<p>同步调用是一种阻塞式的调用方式,即
 Consumer 端代码一直阻塞等待,直到 Provider 
端返回为止;</p>\n<p>通常,一个典型的同步调用过程如下:</p>\n<ol>\n<li>Consumer 业务线程调用远程接口,向 Provider 
发送请求,同时当前线程处于<code>阻塞</code>状态;</li>\n<li>Provider 接到 Consumer 
的请求后,开始处理请求,将结果返回给 Consumer;</li>\n<li>Consumer 
收到结果后,当前线程继续往后执行。</li>\n</ol>\n<p>这里 [...]
+  "__html": "<h1>Dubbo 关于同步/异步调用的几种方式</h1>\n<p>我们知道,Dubbo 缺省协议采用单一长连接,底层实现是 
Netty 的 NIO 异步通讯机制;基于这种机制,Dubbo 
实现了以下几种调用方式:</p>\n<ul>\n<li>同步调用</li>\n<li>异步调用</li>\n<li>参数回调</li>\n<li>事件通知</li>\n</ul>\n<h2>同步调用</h2>\n<p>同步调用是一种阻塞式的调用方式,即
 Consumer 端代码一直阻塞等待,直到 Provider 
端返回为止;</p>\n<p>通常,一个典型的同步调用过程如下:</p>\n<ol>\n<li>Consumer 业务线程调用远程接口,向 Provider 
发送请求,同时当前线程处于<code>阻塞</code>状态;</li>\n<li>Provider 接到 Consumer 
的请求后,开始处理请求,将结果返回给 Consumer;</li>\n<li>Consumer 
收到结果后,当前线程继续往后执行。</li>\n</ol>\n<p>这里 [...]
 }
\ No newline at end of file
diff --git a/zh-cn/blog/introduction-to-dubbo-qos.html 
b/zh-cn/blog/introduction-to-dubbo-qos.html
index 40052cc..97ad6cf 100644
--- a/zh-cn/blog/introduction-to-dubbo-qos.html
+++ b/zh-cn/blog/introduction-to-dubbo-qos.html
@@ -12,10 +12,10 @@
        <link rel="stylesheet" href="/build/blogDetail.css" />
 </head>
 <body>
-       <div id="root"><div class="blog-detail-page" data-reactroot="" 
data-reactid="1" data-react-checksum="111731636"><header 
class="header-container header-container-normal" data-reactid="2"><div 
class="header-body" data-reactid="3"><a href="/zh-cn/index.html" 
data-reactid="4"><img class="logo" src="/img/dubbo_colorful.png" 
data-reactid="5"/></a><span class="language-switch language-switch-normal" 
data-reactid="6">En</span><div class="header-menu" data-reactid="7"><img 
class="header-menu-tog [...]
+       <div id="root"><div class="blog-detail-page" data-reactroot="" 
data-reactid="1" data-react-checksum="-84548702"><header 
class="header-container header-container-normal" data-reactid="2"><div 
class="header-body" data-reactid="3"><a href="/zh-cn/index.html" 
data-reactid="4"><img class="logo" src="/img/dubbo_colorful.png" 
data-reactid="5"/></a><span class="language-switch language-switch-normal" 
data-reactid="6">En</span><div class="header-menu" data-reactid="7"><img 
class="header-menu-tog [...]
 <p>QoS,全称为<code>Quality of Service</code>, 是常见于网络设备中的一个术语 
,例如在路由器中,可以通过Qos动态的调整和控制某些端口的权重,从而优先的保障运行在这些端口上的服务质量。</p>
 
<p>在Dubbo中,QoS这个概念被用于动态的对服务进行查询和控制。例如对获取当前提供和消费的所有服务,以及对服务进行动态的上下线,即从注册中心上进行注册和反注册操作。</p>
-<h3>QoS工作机制</h3>
+<h2>QoS工作机制</h2>
 <p>从Dubbo 
2.5.8开始,默认引入了Qos功能,默认处于启动状态。所有的QoS功能被抽象成一个个的命令,通过执行这些命令,Qos会返回响应的结果。</p>
 <blockquote>
 <p>Qos功能基于Netty4实现,在Dubbo 
2.6.x之前的版本中,默认依赖的是Netty3,因此需要显示的添加Netty4的依赖,才能确保Netty4正常工作。如果使用http://start.dubbo.io自动生成的Dubbo应用,则无需添加额外的配置,因为已经默认加上了Netty4的依赖。</p>
@@ -28,7 +28,7 @@
 <li>针对不同的协议进行解码,解析出需要执行的命令</li>
 <li>执行命令并返回结果</li>
 </ol>
-<h3>QoS命令</h3>
+<h2>QoS命令</h2>
 <p>QoS目前支持的命令包括:</p>
 <ul>
 <li>help: 帮助命令,列出</li>
@@ -38,7 +38,7 @@
 <li>quit: 退出当前telnet会话</li>
 </ul>
 <p>下面,我们具体来操作一下如何通过用QoS对服务进行动态控制。</p>
-<h4>通过Telnet方式访问QoS</h4>
+<h3>通过Telnet方式访问QoS</h3>
 <p>假设我们的Dubbo服务端已经启动,我们通过Telnet方式进行连接:</p>
 <pre><code>$ telnet localhost 22222
 Trying 127.0.0.1...
@@ -119,7 +119,7 @@ As Consumer side:
 BYE!
 Connection closed by foreign host.
 </code></pre>
-<h4>通过HTTP方式访问QOS</h4>
+<h3>通过HTTP方式访问QOS</h3>
 
<p>在上面的例子中,我们已经对<code>org.apache.dubbo.demo.provider.DemoService</code>进行了下线操作,下面,我们通过对Http方式对上面的服务进行注册操作:</p>
 <pre><code>$ curl -i 
http://localhost:22222/online?service=org.apache.dubbo.demo.provider.DemoService
 HTTP/1.1 200 OK
@@ -149,7 +149,7 @@ As Consumer side:
 +---------------------+---+
 </code></pre>
 <p>可以看到服务的<code>PUB</code>状态已经变成了<code>Y</code>。</p>
-<h3>QoS相关参数说明</h3>
+<h2>QoS相关参数说明</h2>
 <p>QoS提供了一些启动参数,来对启动进行配置,他们主要包括:</p>
 <table>
 <thead>
@@ -188,18 +188,18 @@ As Consumer side:
 <li>Spring-boot自动装配方式</li>
 </ul>
 <p>其中,上述方式的优先顺序为系统属性 &gt; dubbo.properties &gt; XML/Spring-boot自动装配方式。</p>
-<h4>使用系统属性方式进行配置</h4>
+<h3>使用系统属性方式进行配置</h3>
 <pre><code>-Ddubbo.application.qos.enable=true
 -Ddubbo.application.qos.port=33333
 -Ddubbo.application.qos.accept.foreign.ip=false
 </code></pre>
-<h4>使用dubbo.properties文件进行配置</h4>
+<h3>使用dubbo.properties文件进行配置</h3>
 <p>在项目的<code>src/main/resources</code>目录下添加dubbo.properties文件,内容如下:</p>
 <pre><code>dubbo.application.qos.enable=true
 dubbo.application.qos.port=33333
 dubbo.application.qos.accept.foreign.ip=false
 </code></pre>
-<h4>使用XML方法进行配置</h4>
+<h3>使用XML方法进行配置</h3>
 <p>如果要通过XML配置响应的QoS相关的参数,可以进行如下配置:</p>
 <pre><code class="language-xml"><span class="php"><span 
class="hljs-meta">&lt;?</span>xml version=<span 
class="hljs-string">"1.0"</span> encoding=<span 
class="hljs-string">"UTF-8"</span><span class="hljs-meta">?&gt;</span></span>
 <span class="hljs-tag">&lt;<span class="hljs-name">beans</span> <span 
class="hljs-attr">xmlns</span>=<span 
class="hljs-string">"http://www.springframework.org/schema/beans";</span>
@@ -219,7 +219,7 @@ dubbo.application.qos.accept.foreign.ip=false
   <span class="hljs-tag">&lt;<span class="hljs-name">bean</span> <span 
class="hljs-attr">id</span>=<span class="hljs-string">"demoService"</span> 
<span class="hljs-attr">class</span>=<span 
class="hljs-string">"org.apache.dubbo.demo.provider.DemoServiceImpl"</span>/&gt;</span>
 <span class="hljs-tag">&lt;/<span class="hljs-name">beans</span>&gt;</span>
 </code></pre>
-<h4>使用spring-boot自动装配方式配置</h4>
+<h3>使用spring-boot自动装配方式配置</h3>
 
<p>如果是spring-boot的应用,可以在<code>application.properties</code>或者<code>application.yml</code>上配置:</p>
 <pre><code>dubbo.application.qosEnable=true
 dubbo.application.qosPort=33333
diff --git a/zh-cn/blog/introduction-to-dubbo-qos.json 
b/zh-cn/blog/introduction-to-dubbo-qos.json
index cf6adb1..f09b4e1 100644
--- a/zh-cn/blog/introduction-to-dubbo-qos.json
+++ b/zh-cn/blog/introduction-to-dubbo-qos.json
@@ -1,4 +1,4 @@
 {
   "filename": "introduction-to-dubbo-qos.md",
-  "__html": "<h1>通过QoS对服务进行动态控制</h1>\n<p>QoS,全称为<code>Quality of 
Service</code>, 是常见于网络设备中的一个术语 
,例如在路由器中,可以通过Qos动态的调整和控制某些端口的权重,从而优先的保障运行在这些端口上的服务质量。</p>\n<p>在Dubbo中,QoS这个概念被用于动态的对服务进行查询和控制。例如对获取当前提供和消费的所有服务,以及对服务进行动态的上下线,即从注册中心上进行注册和反注册操作。</p>\n<h3>QoS工作机制</h3>\n<p>从Dubbo
 
2.5.8开始,默认引入了Qos功能,默认处于启动状态。所有的QoS功能被抽象成一个个的命令,通过执行这些命令,Qos会返回响应的结果。</p>\n<blockquote>\n<p>Qos功能基于Netty4实现,在Dubbo
 
2.6.x之前的版本中,默认依赖的是Netty3,因此需要显示的添加Netty4的依赖,才能确保Netty4正常工作。如果使用http://start.dubbo.io自�
 �生成的Dubbo应用,则无需添加额外 [...]
+  "__html": "<h1>通过QoS对服务进行动态控制</h1>\n<p>QoS,全称为<code>Quality of 
Service</code>, 是常见于网络设备中的一个术语 
,例如在路由器中,可以通过Qos动态的调整和控制某些端口的权重,从而优先的保障运行在这些端口上的服务质量。</p>\n<p>在Dubbo中,QoS这个概念被用于动态的对服务进行查询和控制。例如对获取当前提供和消费的所有服务,以及对服务进行动态的上下线,即从注册中心上进行注册和反注册操作。</p>\n<h2>QoS工作机制</h2>\n<p>从Dubbo
 
2.5.8开始,默认引入了Qos功能,默认处于启动状态。所有的QoS功能被抽象成一个个的命令,通过执行这些命令,Qos会返回响应的结果。</p>\n<blockquote>\n<p>Qos功能基于Netty4实现,在Dubbo
 
2.6.x之前的版本中,默认依赖的是Netty3,因此需要显示的添加Netty4的依赖,才能确保Netty4正常工作。如果使用http://start.dubbo.io自�
 �生成的Dubbo应用,则无需添加额外 [...]
 }
\ No newline at end of file
diff --git a/zh-cn/blog/introduction-to-dubbo-spi-2.html 
b/zh-cn/blog/introduction-to-dubbo-spi-2.html
index 95e158c..763bfde 100644
--- a/zh-cn/blog/introduction-to-dubbo-spi-2.html
+++ b/zh-cn/blog/introduction-to-dubbo-spi-2.html
@@ -12,10 +12,10 @@
        <link rel="stylesheet" href="/build/blogDetail.css" />
 </head>
 <body>
-       <div id="root"><div class="blog-detail-page" data-reactroot="" 
data-reactid="1" data-react-checksum="-208425083"><header 
class="header-container header-container-normal" data-reactid="2"><div 
class="header-body" data-reactid="3"><a href="/zh-cn/index.html" 
data-reactid="4"><img class="logo" src="/img/dubbo_colorful.png" 
data-reactid="5"/></a><span class="language-switch language-switch-normal" 
data-reactid="6">En</span><div class="header-menu" data-reactid="7"><img 
class="header-menu-to [...]
+       <div id="root"><div class="blog-detail-page" data-reactroot="" 
data-reactid="1" data-react-checksum="978103749"><header 
class="header-container header-container-normal" data-reactid="2"><div 
class="header-body" data-reactid="3"><a href="/zh-cn/index.html" 
data-reactid="4"><img class="logo" src="/img/dubbo_colorful.png" 
data-reactid="5"/></a><span class="language-switch language-switch-normal" 
data-reactid="6">En</span><div class="header-menu" data-reactid="7"><img 
class="header-menu-tog [...]
 <hr>
-<p>在<a 
href="#/blog/introduction-to-dubbo-spi.md">Dubbo可扩展机制实战</a>中,我们了解了Dubbo扩展机制的一些概念,初探了Dubbo中LoadBalance的实现,并自己实现了一个LoadBalance。是不是觉得Dubbo的扩展机制很不错呀,接下来,我们就深入Dubbo的源码,一睹庐山真面目。</p>
-<h1>ExtensionLoader</h1>
+<p>在<a 
href="./introduction-to-dubbo-spi.md">Dubbo可扩展机制实战</a>中,我们了解了Dubbo扩展机制的一些概念,初探了Dubbo中LoadBalance的实现,并自己实现了一个LoadBalance。是不是觉得Dubbo的扩展机制很不错呀,接下来,我们就深入Dubbo的源码,一睹庐山真面目。</p>
+<h2>ExtensionLoader</h2>
 <p>ExtentionLoader是最核心的类,负责扩展点的加载和生命周期管理。我们就以这个类开始吧。
 Extension的方法比较多,比较常用的方法有:</p>
 <ul>
@@ -166,7 +166,7 @@ Extension的方法比较多,比较常用的方法有:</p>
 
自动包装就是要实现类似于Spring的AOP功能。Dubbo利用它在内部实现一些通用的功能,比如日志,监控等。关于扩展实例自动包装的内容,也会在后面单独讲解。</li>
 </ol>
 <p>经过上面的4步,Dubbo就创建并初始化了一个扩展实例。这个实例的依赖被注入了,也根据需要被包装了。到此为止,这个扩展实例就可以被使用了。</p>
-<h1>Dubbo SPI高级用法之自动装配</h1>
+<h2>Dubbo SPI高级用法之自动装配</h2>
 <p>自动装配的相关代码在injectExtension方法中:</p>
 <pre><code class="language-java"><span class="hljs-function"><span 
class="hljs-keyword">private</span> T <span 
class="hljs-title">injectExtension</span><span class="hljs-params">(T 
instance)</span> </span>{
     <span class="hljs-keyword">for</span> (Method method : 
instance.getClass().getMethods()) {
@@ -228,7 +228,7 @@ Extension的方法比较多,比较常用的方法有:</p>
 </code></pre>
 
<p>AdaptiveExtensionLoader类有@Adaptive注解。前面提到了,Dubbo会为每一个扩展创建一个自适应实例。如果扩展类上有@Adaptive,会使用该类作为自适应类。如果没有,Dubbo会为我们创建一个。所以<code>ExtensionLoader.getExtensionLoader(ExtensionFactory.class).getAdaptiveExtension())</code>会返回一个AdaptiveExtensionLoader实例,作为自适应扩展实例。
 
AdaptiveExtentionLoader会遍历所有的ExtensionFactory实现,尝试着去加载扩展。如果找到了,返回。如果没有,在下一个ExtensionFactory中继续找。Dubbo内置了两个ExtensionFactory,分别从Dubbo自身的扩展机制和Spring容器中去寻找。由于ExtensionFactory本身也是一个扩展点,我们可以实现自己的ExtensionFactory,让Dubbo的自动装配支持我们自定义的组件。比如,我们在项目中使用了Google的guice这个IoC容器。我们可以实现自己的GuiceExtensionFactory,让Dubbo支持从guice容器中加载扩展。</p>
-<h1>Dubbo SPI高级用法之AoP</h1>
+<h2>Dubbo SPI高级用法之AoP</h2>
 <p>在用Spring的时候,我们经常会用到AOP功能。在目标类的方法前后插入其他逻辑。比如通常使用Spring AOP来实现日志,监控和鉴权等功能。
 
Dubbo的扩展机制,是否也支持类似的功能呢?答案是yes。在Dubbo中,有一种特殊的类,被称为Wrapper类。通过装饰者模式,使用包装类包装原始的扩展点实例。在原始扩展点实现前后插入其他逻辑,实现AOP功能。</p>
 <h3>什么是Wrapper类</h3>
@@ -274,7 +274,7 @@ ProtocolFilterWrapper代码如下:</p>
     }
 </code></pre>
 <p>ProtocolFilterWrapper有一个构造函数<code>public ProtocolFilterWrapper(Protocol 
protocol)</code>,参数是扩展点Protocol,所以它是一个Dubbo扩展机制中的Wrapper类。ExtensionLoader会把它缓存起来,供以后创建Extension实例的时候,使用这些包装类依次包装原始扩展点。</p>
-<h1>扩展点自适应</h1>
+<h2>扩展点自适应</h2>
 
<p>前面讲到过,Dubbo需要在运行时根据方法参数来决定该使用哪个扩展,所以有了扩展点自适应实例。其实是一个扩展点的代理,将扩展的选择从Dubbo启动时,延迟到RPC调用时。Dubbo中每一个扩展点都有一个自适应类,如果没有显式提供,Dubbo会自动为我们创建一个,默认使用Javaassist。
 先来看下创建自适应扩展类的代码:</p>
 <pre><code class="language-java"><span class="hljs-function"><span 
class="hljs-keyword">public</span> T <span 
class="hljs-title">getAdaptiveExtension</span><span 
class="hljs-params">()</span> </span>{
diff --git a/zh-cn/blog/introduction-to-dubbo-spi-2.json 
b/zh-cn/blog/introduction-to-dubbo-spi-2.json
index 4092360..8f01df7 100644
--- a/zh-cn/blog/introduction-to-dubbo-spi-2.json
+++ b/zh-cn/blog/introduction-to-dubbo-spi-2.json
@@ -1,4 +1,4 @@
 {
   "filename": "introduction-to-dubbo-spi-2.md",
-  "__html": "<h1>Dubbo可扩展机制源码解析</h1>\n<hr>\n<p>在<a 
href=\"#/blog/introduction-to-dubbo-spi.md\">Dubbo可扩展机制实战</a>中,我们了解了Dubbo扩展机制的一些概念,初探了Dubbo中LoadBalance的实现,并自己实现了一个LoadBalance。是不是觉得Dubbo的扩展机制很不错呀,接下来,我们就深入Dubbo的源码,一睹庐山真面目。</p>\n<h1>ExtensionLoader</h1>\n<p>ExtentionLoader是最核心的类,负责扩展点的加载和生命周期管理。我们就以这个类开始吧。\nExtension的方法比较多,比较常用的方法有:</p>\n<ul>\n<li><code>public
 static &lt;T&gt; ExtensionLoader&lt;T&gt; getExtensionLoader(Class&lt;T&gt; 
type)</code></li>\n<li><code>public T getExtension(S [...]
+  "__html": "<h1>Dubbo可扩展机制源码解析</h1>\n<hr>\n<p>在<a 
href=\"./introduction-to-dubbo-spi.md\">Dubbo可扩展机制实战</a>中,我们了解了Dubbo扩展机制的一些概念,初探了Dubbo中LoadBalance的实现,并自己实现了一个LoadBalance。是不是觉得Dubbo的扩展机制很不错呀,接下来,我们就深入Dubbo的源码,一睹庐山真面目。</p>\n<h2>ExtensionLoader</h2>\n<p>ExtentionLoader是最核心的类,负责扩展点的加载和生命周期管理。我们就以这个类开始吧。\nExtension的方法比较多,比较常用的方法有:</p>\n<ul>\n<li><code>public
 static &lt;T&gt; ExtensionLoader&lt;T&gt; getExtensionLoader(Class&lt;T&gt; 
type)</code></li>\n<li><code>public T getExtension(String [...]
 }
\ No newline at end of file
diff --git a/zh-cn/blog/introduction-to-dubbo-spi.html 
b/zh-cn/blog/introduction-to-dubbo-spi.html
index 8469d4b..b2b769c 100644
--- a/zh-cn/blog/introduction-to-dubbo-spi.html
+++ b/zh-cn/blog/introduction-to-dubbo-spi.html
@@ -12,8 +12,9 @@
        <link rel="stylesheet" href="/build/blogDetail.css" />
 </head>
 <body>
-       <div id="root"><div class="blog-detail-page" data-reactroot="" 
data-reactid="1" data-react-checksum="1806745375"><header 
class="header-container header-container-normal" data-reactid="2"><div 
class="header-body" data-reactid="3"><a href="/zh-cn/index.html" 
data-reactid="4"><img class="logo" src="/img/dubbo_colorful.png" 
data-reactid="5"/></a><span class="language-switch language-switch-normal" 
data-reactid="6">En</span><div class="header-menu" data-reactid="7"><img 
class="header-menu-to [...]
-<h1>1. Dubbo的扩展机制</h1>
+       <div id="root"><div class="blog-detail-page" data-reactroot="" 
data-reactid="1" data-react-checksum="-307969909"><header 
class="header-container header-container-normal" data-reactid="2"><div 
class="header-body" data-reactid="3"><a href="/zh-cn/index.html" 
data-reactid="4"><img class="logo" src="/img/dubbo_colorful.png" 
data-reactid="5"/></a><span class="language-switch language-switch-normal" 
data-reactid="6">En</span><div class="header-menu" data-reactid="7"><img 
class="header-menu-to [...]
+<hr>
+<h2>1. Dubbo的扩展机制</h2>
 <p>在Dubbo的官网上,Dubbo描述自己是一个高性能的RPC框架。今天我想聊聊Dubbo的另一个很棒的特性, 就是它的可扩展性。
 
如同罗马不是一天建成的,任何系统都一定是从小系统不断发展成为大系统的,想要从一开始就把系统设计的足够完善是不可能的,相反的,我们应该关注当下的需求,然后再不断地对系统进行迭代。在代码层面,要求我们适当的对关注点进行抽象和隔离,在软件不断添加功能和特性时,依然能保持良好的结构和可维护性,同时允许第三方开发者对其功能进行扩展。在某些时候,软件设计者对扩展性的追求甚至超过了性能。</p>
 <p>在谈到软件设计时,可扩展性一直被谈起,那到底什么才是可扩展性,什么样的框架才算有良好的可扩展性呢?它必须要做到以下两点:</p>
@@ -22,7 +23,7 @@
 <li>作为框架的使用者,在添加一个新功能时,不需要去修改框架的源码,在自己的工程中添加代码即可。</li>
 </ol>
 <p>Dubbo很好的做到了上面两点。这要得益于Dubbo的微内核+插件的机制。接下来的章节中我们会慢慢揭开Dubbo扩展机制的神秘面纱。</p>
-<h1>2. 可扩展的几种解决方案</h1>
+<h2>2. 可扩展的几种解决方案</h2>
 <p>通常可扩展的实现有下面几种:</p>
 <ul>
 <li>Factory模式</li>
@@ -30,7 +31,7 @@
 <li>OSGI容器</li>
 </ul>
 
<p>Dubbo作为一个框架,不希望强依赖其他的IoC容器,比如Spring,Guice。OSGI也是一个很重的实现,不适合Dubbo。最终Dubbo的实现参考了Java原生的SPI机制,但对其进行了一些扩展,以满足Dubbo的需求。</p>
-<h1>3. Java SPI机制</h1>
+<h2>3. Java SPI机制</h2>
 <p>既然Dubbo的扩展机制是基于Java原生的SPI机制,那么我们就先来了解下Java 
SPI吧。了解了Java的SPI,也就是对Dubbo的扩展机制有一个基本的了解。如果对Java SPI比较了解的同学,可以跳过。</p>
 <p>Java SPI(Service Provider 
Interface)是JDK内置的一种动态加载扩展点的实现。在ClassPath的<code>META-INF/services</code>目录下放置一个与接口同名的文本文件,文件的内容为接口的实现类,多个实现类用换行符分隔。JDK中使用<code>java.util.ServiceLoader</code>来加载具体的实现。
 让我们通过一个简单的例子,来看看Java SPI是如何工作的。</p>
@@ -81,7 +82,7 @@ class:testDubbo.MongoRepository
 Save tom to Mongo
 class:testDubbo.MysqlRepository
 Save tom to Mysql</p>
-<h1>4. Dubbo的SPI机制</h1>
+<h2>4. Dubbo的SPI机制</h2>
 <p>Java SPI的使用很简单。也做到了基本的加载扩展点的功能。但Java SPI有以下的不足:</p>
 <ul>
 <li>需要遍历所有的实现,并实例化,然后我们在循环中才能找到我们需要的实现。</li>
@@ -91,7 +92,7 @@ Save tom to Mysql</p>
 <li>扩展很难和其他的框架集成,比如扩展里面依赖了一个Spring bean,原生的Java SPI不支持</li>
 </ul>
 <p>所以Java 
SPI应付一些简单的场景是可以的,但对于Dubbo,它的功能还是比较弱的。Dubbo对原生SPI机制进行了一些扩展。接下来,我们就更深入地了解下Dubbo的SPI机制。</p>
-<h1>5. Dubbo扩展点机制基本概念</h1>
+<h2>5. Dubbo扩展点机制基本概念</h2>
 <p>在深入学习Dubbo的扩展机制之前,我们先明确Dubbo SPI中的一些基本概念。在接下来的内容中,我们会多次用到这些术语。</p>
 <h3>5.1 扩展点(Extension Point)</h3>
 <p>是一个Java的接口。</p>
@@ -126,7 +127,7 @@ 
roundrobin=com.alibaba.dubbo.rpc.cluster.loadbalance.RoundRobinLoadBalance
 <li><code>META-INF/dubbo</code></li>
 <li><code>META-INF/services</code></li>
 </ul>
-<h1>6. Dubbo的LoadBalance扩展点解读</h1>
+<h2>6. Dubbo的LoadBalance扩展点解读</h2>
 <p>在了解了Dubbo的一些基本概念后,让我们一起来看一个Dubbo中实际的扩展点,对这些概念有一个更直观的认识。</p>
 
<p>我们选择的是Dubbo中的LoadBalance扩展点。Dubbo中的一个服务,通常有多个Provider,consumer调用服务时,需要在多个Provider中选择一个。这就是一个LoadBalance。我们一起来看看在Dubbo中,LoadBalance是如何成为一个扩展点的。</p>
 <h3>6.1 LoadBalance接口</h3>
@@ -160,7 +161,7 @@ 
consistenthash=com.alibaba.dubbo.rpc.cluster.loadbalance.ConsistentHashLoadBalan
 <pre><code class="language-java">LoadBalance lb = 
ExtensionLoader.getExtensionLoader(LoadBalance.class).getExtension(loadbalanceName);
 </code></pre>
 
<p>使用ExtensionLoader.getExtensionLoader(LoadBalance.class)方法获取一个ExtensionLoader的实例,然后调用getExtension,传入一个扩展的别名来获取对应的扩展实例。</p>
-<h1>7. 自定义一个LoadBalance扩展</h1>
+<h2>7. 自定义一个LoadBalance扩展</h2>
 <p>本节中,我们通过一个简单的例子,来自己实现一个LoadBalance,并把它集成到Dubbo中。我会列出一些关键的步骤和代码,也可以从这个地址(<a 
href="https://github.com/vangoleo/dubbo-spi-demo";>https://github.com/vangoleo/dubbo-spi-demo</a>)下载完整的demo。</p>
 <h3>7.1 实现LoadBalance接口</h3>
 
<p>首先,编写一个自己实现的LoadBalance,因为是为了演示Dubbo的扩展机制,而不是LoadBalance的实现,所以这里LoadBalance的实现非常简单,选择第一个invoker,并在控制台输出一条日志。</p>
@@ -184,7 +185,7 @@ 
consistenthash=com.alibaba.dubbo.rpc.cluster.loadbalance.ConsistentHashLoadBalan
 <p>在consumer端的<a 
href="dubbo:reference">dubbo:reference</a>中配置&lt;loadbalance=&quot;demo&quot;&gt;</p>
 <h3>7.4 启动Dubbo</h3>
 <p>启动Dubbo,调用一次IHelloService,可以看到控制台会输出一条<code>DemoLoadBalance: Select the 
first invoker...</code>日志。说明Dubbo的确是使用了我们自定义的LoadBalance。</p>
-<h1>总结</h1>
+<h2>总结</h2>
 <p>到此,我们从Java SPI开始,了解了Dubbo SPI 
的基本概念,并结合了Dubbo中的LoadBalance加深了理解。最后,我们还实践了一下,创建了一个自定义LoadBalance,并集成到Dubbo中。相信通过这里理论和实践的结合,大家对Dubbo的可扩展有更深入的理解。
 总结一下,Dubbo SPI有以下的特点:</p>
 <ul>
diff --git a/zh-cn/blog/introduction-to-dubbo-spi.json 
b/zh-cn/blog/introduction-to-dubbo-spi.json
index d72c4cc..1f56434 100644
--- a/zh-cn/blog/introduction-to-dubbo-spi.json
+++ b/zh-cn/blog/introduction-to-dubbo-spi.json
@@ -1,4 +1,4 @@
 {
   "filename": "introduction-to-dubbo-spi.md",
-  "__html": "<h2>Dubbo可扩展机制实战</h2>\n<h1>1. 
Dubbo的扩展机制</h1>\n<p>在Dubbo的官网上,Dubbo描述自己是一个高性能的RPC框架。今天我想聊聊Dubbo的另一个很棒的特性, 
就是它的可扩展性。\n如同罗马不是一天建成的,任何系统都一定是从小系统不断发展成为大系统的,想要从一开始就把系统设计的足够完善是不可能的,相反的,我们应该关注当下的需求,然后再不断地对系统进行迭代。在代码层面,要求我们适当的对关注点进行抽象和隔离,在软件不断添加功能和特性时,依然能保持良好的结构和可维护性,同时允许第三方开发者对其功能进行扩展。在某些时候,软件设计者对扩展性的追求甚至超过了性能。</p>\n<p>在谈到软件设计时,可扩展性一直被谈起,那到底什么才是可扩展性,什么样的框架才算有良好的可扩展性呢?它必须要做到以下两点:</p>\
 
n<ol>\n<li>作为框架的维护者,在添加一个新功能时,只需要添加一些新代码,而不用大量的修改现有的代码,即符合开闭原则。</li>\n<li>作为框架的使用者,在添加一个新功能时,不需要去修改框架
 [...]
+  "__html": "<h1>Dubbo可扩展机制实战</h1>\n<hr>\n<h2>1. 
Dubbo的扩展机制</h2>\n<p>在Dubbo的官网上,Dubbo描述自己是一个高性能的RPC框架。今天我想聊聊Dubbo的另一个很棒的特性, 
就是它的可扩展性。\n如同罗马不是一天建成的,任何系统都一定是从小系统不断发展成为大系统的,想要从一开始就把系统设计的足够完善是不可能的,相反的,我们应该关注当下的需求,然后再不断地对系统进行迭代。在代码层面,要求我们适当的对关注点进行抽象和隔离,在软件不断添加功能和特性时,依然能保持良好的结构和可维护性,同时允许第三方开发者对其功能进行扩展。在某些时候,软件设计者对扩展性的追求甚至超过了性能。</p>\n<p>在谈到软件设计时,可扩展性一直被谈起,那到底什么才是可扩展性,什么样的框架才算有良好的可扩展性呢?它必须要做到以下两点
 
:</p>\n<ol>\n<li>作为框架的维护者,在添加一个新功能时,只需要添加一些新代码,而不用大量的修改现有的代码,即符合开闭原则。</li>\n<li>作为框架的使用者,在添加一个新功能时,不需
 [...]
 }
\ No newline at end of file
diff --git a/zh-cn/blog/spring-boot-dubbo-start-stop-analysis.html 
b/zh-cn/blog/spring-boot-dubbo-start-stop-analysis.html
index 5e32612..d2e6940 100644
--- a/zh-cn/blog/spring-boot-dubbo-start-stop-analysis.html
+++ b/zh-cn/blog/spring-boot-dubbo-start-stop-analysis.html
@@ -12,14 +12,14 @@
        <link rel="stylesheet" href="/build/blogDetail.css" />
 </head>
 <body>
-       <div id="root"><div class="blog-detail-page" data-reactroot="" 
data-reactid="1" data-react-checksum="1504542408"><header 
class="header-container header-container-normal" data-reactid="2"><div 
class="header-body" data-reactid="3"><a href="/zh-cn/index.html" 
data-reactid="4"><img class="logo" src="/img/dubbo_colorful.png" 
data-reactid="5"/></a><span class="language-switch language-switch-normal" 
data-reactid="6">En</span><div class="header-menu" data-reactid="7"><img 
class="header-menu-to [...]
-<h3>背景介绍</h3>
+       <div id="root"><div class="blog-detail-page" data-reactroot="" 
data-reactid="1" data-react-checksum="-616595780"><header 
class="header-container header-container-normal" data-reactid="2"><div 
class="header-body" data-reactid="3"><a href="/zh-cn/index.html" 
data-reactid="4"><img class="logo" src="/img/dubbo_colorful.png" 
data-reactid="5"/></a><span class="language-switch language-switch-normal" 
data-reactid="6">En</span><div class="header-menu" data-reactid="7"><img 
class="header-menu-to [...]
+<h2>背景介绍</h2>
 <p><a 
href="https://github.com/apache/incubator-dubbo-spring-boot-project";>Dubbo 
Spring Boot</a> 工程致力于简化 Dubbo RPC 框架在Spring Boot应用场景的开发。同时也整合了 Spring Boot 
特性:</p>
 <ul>
 <li><a 
href="https://github.com/apache/incubator-dubbo-spring-boot-project/blob/master/dubbo-spring-boot-autoconfigure";>自动装配</a>
 (比如: 注解驱动, 自动装配等).</li>
 <li><a 
href="https://github.com/apache/incubator-dubbo-spring-boot-project/blob/master/dubbo-spring-boot-actuator";>Production-Ready</a>
 (比如: 安全, 健康检查, 外部化配置等).</li>
 </ul>
-<h3>DubboConsumer启动分析</h3>
+<h2>DubboConsumer启动分析</h2>
 
<p>你有没有想过一个问题?<code>incubator-dubbo-spring-boot-project</code>中的<code>DubboConsumerDemo</code>应用就一行代码,<code>main</code>方法执行完之后,为什么不会直接退出呢?</p>
 <pre><code class="language-java"><span 
class="hljs-meta">@SpringBootApplication</span>(scanBasePackages = <span 
class="hljs-string">"com.alibaba.boot.dubbo.demo.consumer.controller"</span>)
 <span class="hljs-keyword">public</span> <span class="hljs-class"><span 
class="hljs-keyword">class</span> <span 
class="hljs-title">DubboConsumerDemo</span> </span>{
@@ -127,7 +127,7 @@ main:35, DubboConsumerDemo 
(com.alibaba.boot.dubbo.demo.consumer.bootstrap)
 <p>在await方法中,实际上当前线程在一个while循环中每10秒检查一次 
<code>stopAwait</code>这个变量,它是一个<code>volatile</code>类型变量,用于确保被另一个线程修改后,当前线程能够立即看到这个变化。如果没有变化,就会一直处于while循环中。这就是该线程不退出的原因,也就是整个spring-boot应用不退出的原因。</p>
 <p>因为Springboot应用同时启动了8080和8081(management 
port)两个端口,实际是启动了两个Tomcat,因此会有两个线程<code>container-0</code>和<code>container-1</code>。</p>
 <p>接下来,我们再看看,这个Spring-boot应用又是如何退出的呢?</p>
-<h3>DubboConsumer退出分析</h3>
+<h2>DubboConsumer退出分析</h2>
 
<p>在前面的描述中提到,有一个线程持续的在检查<code>stopAwait</code>这个变量,那么我们自然想到,在Stop的时候,应该会有一个线程去修改<code>stopAwait</code>,打破这个while循环,那又是谁在修改这个变量呢?</p>
 
<p>通过对源码分析,可以看到只有一个方法修改了<code>stopAwait</code>,即<code>org.apache.catalina.core.StandardServer#stopAwait</code>,我们在此处加个断点,看看是谁在调用。</p>
 <blockquote>
@@ -175,14 +175,14 @@ run:<span class="hljs-number">929</span>, 
AbstractApplicationContext$<span class
 <li>响应外部的信号,例如Ctrl+C(其实发送的是SIGINT信号),或者是<code>SIGTERM</code>信号(默认<code>kill 
$PID</code>发送的是<code>SIGTERM</code>信号)</li>
 </ol>
 <p>因此,正常的应用在停止过程中(<code>kill -9 
$PID</code>除外),都会执行上述ShutdownHook,它的作用不仅仅是关闭tomcat,还有进行其他的清理工作,在此不再赘述。</p>
-<h3>总结</h3>
+<h2>总结</h2>
 <ol>
 <li>在<code>DubboConsumer</code>启动的过程中,通过启动一个独立的非daemon线程循环检查变量的状态,确保进程不退出</li>
 
<li>在<code>DubboConsumer</code>停止的过程中,通过执行spring容器的shutdownhook,修改了变量的状态,使得程序正常退出</li>
 </ol>
-<h3>问题</h3>
+<h2>问题</h2>
 
<p>在DubboProvider的例子中,我们看到Provider并没有启动Tomcat提供HTTP服务,那又是如何实现不退出的呢?我们将在下一篇文章中回答这个问题。</p>
-<h4>彩蛋</h4>
+<h3>彩蛋</h3>
 <p>在<code>Intellij 
IDEA</code>中运行了如下的单元测试,创建一个线程执行睡眠1000秒的操作,我们惊奇的发现,代码并没有线程执行完就退出了,这又是为什么呢?(被创建的线程是非daemon线程)</p>
 <pre><code class="language-java">    <span class="hljs-meta">@Test</span>
     <span class="hljs-function"><span class="hljs-keyword">public</span> <span 
class="hljs-keyword">void</span> <span class="hljs-title">test</span><span 
class="hljs-params">()</span> </span>{
diff --git a/zh-cn/blog/spring-boot-dubbo-start-stop-analysis.json 
b/zh-cn/blog/spring-boot-dubbo-start-stop-analysis.json
index bbcae1d..59eb5d4 100644
--- a/zh-cn/blog/spring-boot-dubbo-start-stop-analysis.json
+++ b/zh-cn/blog/spring-boot-dubbo-start-stop-analysis.json
@@ -1,4 +1,4 @@
 {
   "filename": "spring-boot-dubbo-start-stop-analysis.md",
-  "__html": "<h1>Spring-boot+Dubbo应用启停源码分析</h1>\n<h3>背景介绍</h3>\n<p><a 
href=\"https://github.com/apache/incubator-dubbo-spring-boot-project\";>Dubbo 
Spring Boot</a> 工程致力于简化 Dubbo RPC 框架在Spring Boot应用场景的开发。同时也整合了 Spring Boot 
特性:</p>\n<ul>\n<li><a 
href=\"https://github.com/apache/incubator-dubbo-spring-boot-project/blob/master/dubbo-spring-boot-autoconfigure\";>自动装配</a>
 (比如: 注解驱动, 自动装配等).</li>\n<li><a 
href=\"https://github.com/apache/incubator-dubbo-spring-boot-project/blob/master/dubbo-sprin
 [...]
+  "__html": "<h1>Spring-boot+Dubbo应用启停源码分析</h1>\n<h2>背景介绍</h2>\n<p><a 
href=\"https://github.com/apache/incubator-dubbo-spring-boot-project\";>Dubbo 
Spring Boot</a> 工程致力于简化 Dubbo RPC 框架在Spring Boot应用场景的开发。同时也整合了 Spring Boot 
特性:</p>\n<ul>\n<li><a 
href=\"https://github.com/apache/incubator-dubbo-spring-boot-project/blob/master/dubbo-spring-boot-autoconfigure\";>自动装配</a>
 (比如: 注解驱动, 自动装配等).</li>\n<li><a 
href=\"https://github.com/apache/incubator-dubbo-spring-boot-project/blob/master/dubbo-sprin
 [...]
 }
\ No newline at end of file
diff --git a/zh-cn/docs/user/demos/group-merger.html 
b/zh-cn/docs/user/demos/group-merger.html
index 3d5c01c..b5082ea 100644
--- a/zh-cn/docs/user/demos/group-merger.html
+++ b/zh-cn/docs/user/demos/group-merger.html
@@ -12,9 +12,9 @@
        <link rel="stylesheet" href="/build/documentation.css" />
 </head>
 <body>
-       <div id="root"><div class="documentation-page" data-reactroot="" 
data-reactid="1" data-react-checksum="-1003121568"><header 
class="header-container header-container-normal" data-reactid="2"><div 
class="header-body" data-reactid="3"><a href="/zh-cn/index.html" 
data-reactid="4"><img class="logo" src="/img/dubbo_colorful.png" 
data-reactid="5"/></a><span class="language-switch language-switch-normal" 
data-reactid="6">En</span><div class="header-menu" data-reactid="7"><img 
class="header-menu [...]
+       <div id="root"><div class="documentation-page" data-reactroot="" 
data-reactid="1" data-react-checksum="1900116738"><header 
class="header-container header-container-normal" data-reactid="2"><div 
class="header-body" data-reactid="3"><a href="/zh-cn/index.html" 
data-reactid="4"><img class="logo" src="/img/dubbo_colorful.png" 
data-reactid="5"/></a><span class="language-switch language-switch-normal" 
data-reactid="6">En</span><div class="header-menu" data-reactid="7"><img 
class="header-menu- [...]
 <p>按组合并返回结果 <sup class="footnote-ref"><a href="#fn1" 
id="fnref1">[1]</a></sup>,比如菜单服务,接口一样,但有多种实现,用group区分,现在消费方需从每种group中调用一次返回结果,合并结果返回,这样就可以实现聚合菜单项。</p>
-<p>相关代码可以参考 <a 
href="https://github.com/apache/incubator-dubbo/tree/master/dubbo-test/dubbo-test-examples/src/main/java/com/alibaba/dubbo/examples/merge";>dubbo
 项目中的示例</a></p>
+<p>相关代码可以参考 <a 
href="https://github.com/dubbo/dubbo-samples/tree/master/dubbo-samples-merge";>dubbo
 项目中的示例</a></p>
 <h2>配置</h2>
 <p>搜索所有分组</p>
 <pre><code class="language-xml"><span class="hljs-tag">&lt;<span 
class="hljs-name">dubbo:reference</span> <span 
class="hljs-attr">interface</span>=<span 
class="hljs-string">"com.xxx.MenuService"</span> <span 
class="hljs-attr">group</span>=<span class="hljs-string">"*"</span> <span 
class="hljs-attr">merger</span>=<span class="hljs-string">"true"</span> 
/&gt;</span>
@@ -47,7 +47,7 @@
 <ol class="footnotes-list">
 <li id="fn1" class="footnote-item"><p>从 <code>2.1.0</code> 版本开始支持 <a 
href="#fnref1" class="footnote-backref">↩︎</a></p>
 </li>
-<li id="fn2" class="footnote-item"><p>参见:<a 
href="http://dubbo.apache.org/books/dubbo-dev-book/impls/merger.html";>合并结果扩展</a>
 <a href="#fnref2" class="footnote-backref">↩︎</a></p>
+<li id="fn2" class="footnote-item"><p>参见:<a 
href="http://dubbo.apache.org/zh-cn/docs/dev/impls/merger.html";>合并结果扩展</a> <a 
href="#fnref2" class="footnote-backref">↩︎</a></p>
 </li>
 </ol>
 </section>
diff --git a/zh-cn/docs/user/demos/group-merger.json 
b/zh-cn/docs/user/demos/group-merger.json
index b30a918..ab88251 100644
--- a/zh-cn/docs/user/demos/group-merger.json
+++ b/zh-cn/docs/user/demos/group-merger.json
@@ -1,4 +1,4 @@
 {
   "filename": "group-merger.md",
-  "__html": "<h1>分组聚合</h1>\n<p>按组合并返回结果 <sup class=\"footnote-ref\"><a 
href=\"#fn1\" 
id=\"fnref1\">[1]</a></sup>,比如菜单服务,接口一样,但有多种实现,用group区分,现在消费方需从每种group中调用一次返回结果,合并结果返回,这样就可以实现聚合菜单项。</p>\n<p>相关代码可以参考
 <a 
href=\"https://github.com/apache/incubator-dubbo/tree/master/dubbo-test/dubbo-test-examples/src/main/java/com/alibaba/dubbo/examples/merge\";>dubbo
 项目中的示例</a></p>\n<h2>配置</h2>\n<p>搜索所有分组</p>\n<pre><code 
class=\"language-xml\"><span class=\"hljs-tag\">&lt;<span 
class=\"hljs-name\">dubbo: [...]
+  "__html": "<h1>分组聚合</h1>\n<p>按组合并返回结果 <sup class=\"footnote-ref\"><a 
href=\"#fn1\" 
id=\"fnref1\">[1]</a></sup>,比如菜单服务,接口一样,但有多种实现,用group区分,现在消费方需从每种group中调用一次返回结果,合并结果返回,这样就可以实现聚合菜单项。</p>\n<p>相关代码可以参考
 <a 
href=\"https://github.com/dubbo/dubbo-samples/tree/master/dubbo-samples-merge\";>dubbo
 项目中的示例</a></p>\n<h2>配置</h2>\n<p>搜索所有分组</p>\n<pre><code 
class=\"language-xml\"><span class=\"hljs-tag\">&lt;<span 
class=\"hljs-name\">dubbo:reference</span> <span 
class=\"hljs-attr\">interface</span>=< [...]
 }
\ No newline at end of file

Reply via email to