You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@dubbo.apache.org by gi...@gitbox.apache.org, , bo...@gitbox.apache.org, , ""...@apache.org on 2019/09/29 05:28:22 UTC

[dubbo-website] branch asf-site updated: Automated deployment: Sun Sep 29 05:28:16 UTC 2019 848ed075d643742dd9d14b32f3dca45b2e340b51

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

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


The following commit(s) were added to refs/heads/asf-site by this push:
     new 526f128  Automated deployment: Sun Sep 29 05:28:16 UTC 2019 848ed075d643742dd9d14b32f3dca45b2e340b51
526f128 is described below

commit 526f128375ad9b88db7edbdca60b55e10c80de88
Author: htynkn <ht...@users.noreply.github.com>
AuthorDate: Sun Sep 29 05:28:16 2019 +0000

    Automated deployment: Sun Sep 29 05:28:16 UTC 2019 848ed075d643742dd9d14b32f3dca45b2e340b51
---
 build/blog.js                     |   2 +-
 en-us/blog/dubboAsync_server.html | 100 ++++++++++++++++++++++++++++++++++++++
 en-us/blog/dubboAsync_server.json |  10 ++++
 en-us/blog/index.html             |   2 +-
 md_json/blog.json                 |  11 ++++-
 zh-cn/blog/dubboAsync_server.html |  25 +++++-----
 zh-cn/blog/dubboAsync_server.json |   4 +-
 7 files changed, 135 insertions(+), 19 deletions(-)

diff --git a/build/blog.js b/build/blog.js
index fed2f6e..a1e740a 100644
--- a/build/blog.js
+++ b/build/blog.js
@@ -1,4 +1,4 @@
-!function(e){function t(r){if(n[r])return n[r].exports;var o=n[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,t),o.l=!0,o.exports}var n={};t.m=e,t.c=n,t.i=function(e){return e},t.d=function(e,n,r){t.o(e,n)||Object.defineProperty(e,n,{configurable:!1,enumerable:!0,get:r})},t.n=function(e){var n=e&&e.__esModule?function(){return e.default}:function(){return e};return t.d(n,"a",n),n},t.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},t.p="/build/",t(t.s=315 [...]
+!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=315 [...]
   Copyright (c) 2017 Jed Watson.
   Licensed under the MIT License (MIT), see
   http://jedwatson.github.io/classnames
diff --git a/en-us/blog/dubboAsync_server.html b/en-us/blog/dubboAsync_server.html
new file mode 100644
index 0000000..10c5a10
--- /dev/null
+++ b/en-us/blog/dubboAsync_server.html
@@ -0,0 +1,100 @@
+<!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, Asynchrony, Reactive" />
+	<meta name="description" content="Implementation background and practice of Dubbo server asynchronous interface" />
+	<!-- 网页标签标题 -->
+	<title>Implementation background and practice of Dubbo server asynchronous interface</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="/en-us/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">中</span><div class="header-menu"><img class="header-menu-toggle" src="/img/menu_gray.png"/><ul><li class="menu-item menu-item-normal"><a hr [...]
+<h2>Preface</h2>
+<p>It is suggested to make an understanding of the thread phase involved in the process of Dubbo first, please refer to <a href="http://dubbo.apache.org/en-us/blog/dubboAsync_client.html">Implementation background and practice of Dubbo client asynchronous interface</a> for details.</p>
+<h2>Implementation background</h2>
+<p>It is necessary to introduce the server-side thread strategy in more detail to deepen the user's judgment basis for selecting server-side asynchrony. It is also necessary to introduce coroutines, the &quot;secret weapon&quot; often used in server-side asynchrony.</p>
+<h3>Server-side thread strategy</h3>
+<p>Dubbo supports a variety of NIO frameworks to implement remoting protocols. Whether Netty, Mina or Grizzly, the implementations are much the same. They are all based on event-driven methods to establish network channels and read data streams. Taking introduction to <a href="https://javaee.github.io/grizzly/iostrategies.html">Thread Strategy</a> of Grizzly as an example, the following four categories are usually supported. Dubbo as an RPC framework, the default choice is the first stra [...]
+<ol>
+<li><strong>Worker-thread Strategy</strong></li>
+</ol>
+<p>The most useful IOStrategy, where Selector thread delegates NIO events processing to a worker threads.</p>
+<p><img src="../../img/blog/dubboasyn_server/1.png" alt="workerthread-strategy.png | center | 371x244"></p>
+<p>This IOStrategy is very scalable and safe. We can change the size of selector and worker thread pool as required and there is no risk that some problem, which may occur during the specific NIO event processing, will impact other Channels registered on the same Selector.</p>
+<p>The disadvantage is the cost of thread context switching.</p>
+<ol start="2">
+<li><strong>Same-thread Strategy</strong></li>
+</ol>
+<p>Potentially the most efficient IOStrategy. Unlike the worker-thread IOStrategy, the same-thread IOStrategy processes NIO events in the current thread, avoiding expensive thread context switches.</p>
+<p><img src="../../img/blog/dubboasyn_server/2.png" alt="samethread-strategy.png | center | 389x264"></p>
+<p>This IOStrategy is still pretty scalable, because we can tune the selector thread pool size, but it does have drawbacks. Care needs to be taken that channel NIO event processing won’t block or execute any long lasting operation, because it may block the processing of other NIO events that occur on the same Selector.</p>
+<ol start="3">
+<li><strong>Dynamic Strategy</strong></li>
+</ol>
+<p>As mentioned previously worker-thread and same-thread strategies have distinct advantages and disadvantages. However, what if a strategy could try to swap them smartly during runtime depending on the current conditions (load, gathered statistics… etc)?</p>
+<p><img src="../../img/blog/dubboasyn_server/3.png" alt="dynamic-strategy.png | center | 361x387"></p>
+<p>Potentially this IOStrategy could bring a lot of benefit and allow finer control of the resources. However, it’s important to not overload the condition evaluation logic, as its complexity will make this IOStrategy inefficient comparing to previous two strategies.</p>
+<p>By the way, I want you to pay more attention to this strategy, which is probably the best combination of Dubbo server asynchrony.</p>
+<ol start="4">
+<li><strong>Leader-follower Strategy</strong></li>
+</ol>
+<p><img src="../../img/blog/dubboasyn_server/4.png" alt="leaderfollower-strategy.png | center | 443x286"></p>
+<p>This IOStrategy is similar to worker-thread IOStrategy, but instead of passing NIO event processing to a worker thread, it changes worker thread to a selector thread by passing it the control over Selector and the actual NIO event processing takes place in the current thread. This strategy actually confuses worker and IO thread stages, which is not recommended.</p>
+<h3>Coroutine and thread</h3>
+<p>In terms of CPU resource management, the minimum scheduling unit of OS and JVM is thread. The coroutine library implemented by business application through extension can have independent running unit. In fact, it is also done based on thread. The principle should be to save the context and switch to another coroutine when IO blocking or lock waiting is encountered.</p>
+<p><strong>In the default Dubbo thread strategy, there are worker thread pools to execute the business logic, but the ThreadPool Full problem often occurs. In order to release worker threads as soon as possible, another thread will be set up in the implementation of the business service. The cost is thread context switching again, and it's necessary to consider link-level data transfer (such as tracing information) and flow-control export controls, etc. Of course, if Dubbo can switch to  [...]
+<h2>The sample</h2>
+<p>Use an example to experience the Dubbo server-side asynchronous interface. For Demo code, visit <a href="https://github.com/dubbo/dubbo-samples/tree/master/dubbo-samples-notify">https://github.com/dubbo/dubbo-samples/tree/master/dubbo-samples-notify</a>。</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">AsyncServiceImpl</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">AsyncService</span> </span>{
+
+    <span class="hljs-meta">@Override</span>
+    <span class="hljs-function"><span class="hljs-keyword">public</span> String <span class="hljs-title">sayHello</span><span class="hljs-params">(String name)</span> </span>{
+        System.out.println(<span class="hljs-string">"Main sayHello() method start."</span>);
+        <span class="hljs-keyword">final</span> AsyncContext asyncContext = RpcContext.startAsync();
+        <span class="hljs-keyword">new</span> Thread(() -&gt; {
+            asyncContext.signalContextSwitch();
+            System.out.println(<span class="hljs-string">"Attachment from consumer: "</span> + RpcContext.getContext().getAttachment(<span class="hljs-string">"consumer-key1"</span>));
+            System.out.println(<span class="hljs-string">"    -- Async start."</span>);
+            <span class="hljs-keyword">try</span> {
+                Thread.sleep(<span class="hljs-number">500</span>);
+            } <span class="hljs-keyword">catch</span> (InterruptedException e) {
+                e.printStackTrace();
+            }
+            asyncContext.write(<span class="hljs-string">"Hello "</span> + name + <span class="hljs-string">", response from provider."</span>);
+            System.out.println(<span class="hljs-string">"    -- Async end."</span>);
+        }).start();
+        System.out.println(<span class="hljs-string">"Main sayHello() method end."</span>);
+        <span class="hljs-keyword">return</span> <span class="hljs-string">"hello, "</span> + name;
+    }
+
+</code></pre>
+<h2>Practical suggestions</h2>
+<ul>
+<li>Don't rely too much on server-side asynchrony.</li>
+<li>Server-side asynchrony is basically a false proposition in the face of event-driven or Reactive.<span data-type="color" style="color:rgb(36, 41, 46)"><span data-type="background" style="background-color:rgb(255, 255, 255)">Supplement the reason: the server asynchrony is said Dubbo server-side business threads (default is 200) is not enough, but in the Event-Driven mode, 200 threads certainly do not need that much, just as much as the number of CPU cores. As long as the business imple [...]
+<li>To use server-side asynchrony, it is recommended that the server-side thread strategy adopt the Same_thread pattern + Coroutine Library.</li>
+</ul>
+<h2>Conclusions</h2>
+<p>When Dubbo supports business applications, it encounters a variety of requirements scenarios, and server-side asynchrony provides users with a solution to deal with ThreadPool Full. In the case of ThreadPool Full, if the current system bottleneck is CPU, this solution is not recommended. If the system load is not high, increasing the number of worker threads or using server asynchrony can be considered.</p>
+</section><footer class="footer-container"><div class="footer-body"><img src="/img/dubbo_gray.png"/><img class="apache" src="/img/apache_logo.png"/><div class="cols-container"><div class="col col-12"><h3></h3><p></p></div><div class="col col-4"><dl><dt>ASF</dt><dd><a href="http://www.apache.org" target="_self">Foundation</a></dd><dd><a href="http://www.apache.org/licenses/" target="_self">License</a></dd><dd><a href="http://www.apache.org/events/current-event" target="_self">Events</a></ [...]
+	<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/en-us/blog/dubboAsync_server.json b/en-us/blog/dubboAsync_server.json
new file mode 100644
index 0000000..5a52347
--- /dev/null
+++ b/en-us/blog/dubboAsync_server.json
@@ -0,0 +1,10 @@
+{
+  "filename": "dubboAsync_server.md",
+  "__html": "<h1>Implementation background and practice of Dubbo server asynchronous interface</h1>\n<h2>Preface</h2>\n<p>It is suggested to make an understanding of the thread phase involved in the process of Dubbo first, please refer to <a href=\"http://dubbo.apache.org/en-us/blog/dubboAsync_client.html\">Implementation background and practice of Dubbo client asynchronous interface</a> for details.</p>\n<h2>Implementation background</h2>\n<p>It is necessary to introduce the server-side [...]
+  "link": "/en-us/blog/dubboAsync_server.html",
+  "meta": {
+    "title": "Implementation background and practice of Dubbo server asynchronous interface",
+    "keywords": "Dubbo, Asynchrony, Reactive",
+    "description": "Implementation background and practice of Dubbo server asynchronous interface"
+  }
+}
\ No newline at end of file
diff --git a/en-us/blog/index.html b/en-us/blog/index.html
index f6a7169..cc9451d 100644
--- a/en-us/blog/index.html
+++ b/en-us/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="/en-us/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">中</span><div class="header-menu"><img class="header-menu-toggle" src="/img/menu_gray.png"/><ul><li class="menu-item menu-item-normal"><a href [...]
+	<div id="root"><div class="blog-list-page" data-reactroot=""><header class="header-container header-container-normal"><div class="header-body"><a href="/en-us/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">中</span><div class="header-menu"><img class="header-menu-toggle" src="/img/menu_gray.png"/><ul><li class="menu-item menu-item-normal"><a href [...]
 	<script src="https://f.alicdn.com/react/15.4.1/react-with-addons.min.js"></script>
 	<script src="https://f.alicdn.com/react/15.4.1/react-dom.min.js"></script>
 	<script>
diff --git a/md_json/blog.json b/md_json/blog.json
index 3fb6727..8e3ddf1 100644
--- a/md_json/blog.json
+++ b/md_json/blog.json
@@ -172,6 +172,15 @@
       }
     },
     {
+      "filename": "dubboAsync_server.md",
+      "link": "/en-us/blog/dubboAsync_server.html",
+      "meta": {
+        "title": "Implementation background and practice of Dubbo server asynchronous interface",
+        "keywords": "Dubbo, Asynchrony, Reactive",
+        "description": "Implementation background and practice of Dubbo server asynchronous interface"
+      }
+    },
+    {
       "filename": "gsoc-2018.md",
       "link": "/en-us/blog/gsoc-2018.html",
       "meta": {
@@ -627,7 +636,7 @@
       "filename": "dubboAsync_server.md",
       "link": "/zh-cn/blog/dubboAsync_server.html",
       "meta": {
-        "title": "Dubbo客户端异步接口的实现背景和实践",
+        "title": "Dubbo服务端异步接口的实现背景和实践",
         "keywords": "Dubbo, 异步, Reactive",
         "description": "Dubbo服务端异步接口的实现背景和实践"
       }
diff --git a/zh-cn/blog/dubboAsync_server.html b/zh-cn/blog/dubboAsync_server.html
index 268722f..a32d064 100644
--- a/zh-cn/blog/dubboAsync_server.html
+++ b/zh-cn/blog/dubboAsync_server.html
@@ -7,7 +7,7 @@
 	<meta name="keywords" content="Dubbo, 异步, Reactive" />
 	<meta name="description" content="Dubbo服务端异步接口的实现背景和实践" />
 	<!-- 网页标签标题 -->
-	<title>Dubbo客户端异步接口的实现背景和实践</title>
+	<title>Dubbo服务端异步接口的实现背景和实践</title>
 	<link rel="shortcut icon" href="/img/dubbo.ico"/>
 	<link rel="stylesheet" href="/build/blogDetail.css" />
 </head>
@@ -18,31 +18,29 @@
 <h2>实现背景</h2>
 <p>有必要比较详细点的介绍下服务端的线程策略来加深用户在选择服务端异步的判断依据,同时有必要引出协程这一在服务端异步中常常会用到的“秘密武器”。</p>
 <h3>服务端的线程策略</h3>
-<p>Dubbo是支持多种NIO框架来做Remoting的协议实现,无论是Netty,Mina或者Grizzly,实现都大同小异,都是基于事件驱动的方式来做网络通道建立,数据流读取的,其中Grizzly对于线程策略介绍的为例,通常支持以下四种。Dubbo作为一个RPC框架,默认选择的是第一种策略,原因在于业务服务是CPU密集型还是IO阻塞性,是无法断定的,第一种策略是最保险的策略。当然,对于这几种策略有了了解后,再结合业务场景做针对性的选择是最完美的。</p>
+<p>Dubbo支持多种NIO框架来做Remoting的协议实现,无论是Netty,Mina或者Grizzly,实现都大同小异,都是基于事件驱动的方式来做网络通道建立,数据流读取的。其中以Grizzly对于<a href="https://javaee.github.io/grizzly/iostrategies.html">线程策略</a>的介绍为例,通常支持以下四种。Dubbo作为一个RPC框架,默认选择的是第一种策略,原因在于业务服务是CPU密集型还是IO阻塞型,是无法断定的,第一种策略是最保险的策略。当然,对于这几种策略有了了解后,再结合业务场景做针对性的选择是最完美的。</p>
 <ol>
-<li><strong>Worker-thread
-策略</strong></li>
+<li><strong>Worker-thread策略</strong></li>
 </ol>
 <p>最常用最普适的策略,其中IO线程将NIO事件处理委托给工作线程。</p>
 <p><img src="../../img/blog/dubboasyn_server/1.png" alt="workerthread-strategy.png | center | 371x244"></p>
-<p>此策略具有很高的伸缩性。我们可以根据需要更改IO和worker线程池的大小,并且不存在在特定NIO事件处理期间可能发生的某些问题将影响在同一IO线程上注册的其他通道的风险。
-缺点是有线程上下文切换的代价。</p>
+<p>此策略具有很高的伸缩性。我们可以根据需要更改IO和worker线程池的大小,并且不存在在特定NIO事件处理期间可能发生的,同一Selector各个Channel之间相互干扰的风险。</p>
+<p>缺点是有线程上下文切换的代价。</p>
 <ol start="2">
 <li><strong>Same-thread策略</strong></li>
 </ol>
 <p>可能是最有效的策略。与第一种不同,同一线程处理当前线程中的NIO事件,避免了昂贵的线程上下文切换。</p>
 <p><img src="../../img/blog/dubboasyn_server/2.png" alt="samethread-strategy.png | center | 389x264"></p>
-<p>考虑到这个策略可以调整IO线程池大小,是具备可伸缩性;缺点也很明显,它要求业务处理中一定不要有阻塞处理,因为它可能会阻止在同一个IO线程上发生的其他NIO事件的处理。</p>
+<p>这个策略可以调整IO线程池大小,也是具备可伸缩性;缺点也很明显,它要求业务处理中一定不要有阻塞处理,因为它可能会阻止在同一个IO线程上发生的其他NIO事件的处理。</p>
 <ol start="3">
-<li>dynamic__策略__</li>
+<li><strong>Dynamic策略</strong></li>
 </ol>
 <p>如前所述,前两种策略具有明显的优点和缺点。但是,如果策略可以尝试在运行时根据当前条件(负载,收集的统计信息等)巧妙地交换它们,何如?</p>
 <p><img src="../../img/blog/dubboasyn_server/3.png" alt="dynamic-strategy.png | center | 361x387"></p>
 <p>这种策略可能会带来很多好处,能更好地控制资源,前提是不要使条件评估逻辑过载,防止评估判断的复杂性会使这种策略效率低下。
 多说一句,希望大家对这个策略多留意一下,它可能是Dubbo服务端异步方式的最佳搭配。我也多扯个淡,这几天关注了些adaptive XX或者predictive XX,这里看到dynamic真是亲切,Dubbo作为产品级生产级的微服务解决方案,是必须既要adaptive,又要predictive,还要dynamic,哈哈。</p>
 <ol start="4">
-<li>__Leader-follower __
-策略</li>
+<li><strong>Leader-follower策略</strong></li>
 </ol>
 <p><img src="../../img/blog/dubboasyn_server/4.png" alt="leaderfollower-strategy.png | center | 443x286"></p>
 <p>此策略类似于第一种,但它不是将NIO事件处理传递给worker线程,而是通过将控制传递给Selector给工作线程,并将实际NIO事件处理当前IO线程中。这种策略其实是把worker和IO线程阶段做了混淆,个人不建议。</p>
@@ -76,10 +74,9 @@
 </code></pre>
 <h2>实践建议</h2>
 <ul>
-<li>不用迷信服务端异步</li>
-<li>不要迷信服务端异步</li>
-<li>服务端异步在Event-Driven或者Reactive面前基本是伪命题.<span data-type="color" style="color:rgb(36, 41, 46)"><span data-type="background" style="background-color:rgb(255, 255, 255)">补充下原因:服务端异步初衷是说Dubbo的服务端业务线程数(默认是200个)不够,但其实在event-driven模式下, 200个肯定不需要那么多,只需要cpu核数那样就可以,只要业务实现是非阻塞的纯异步方式的非阻塞的业务逻辑处理,用再多的线程数就是浪费资源。</span></span></li>
-<li>要用服务端异步,建议服务端的线程策略采用same thread模式+协程包</li>
+<li>不要迷信服务端异步。</li>
+<li>服务端异步在Event-Driven或者Reactive面前基本是伪命题.<span data-type="color" style="color:rgb(36, 41, 46)"><span data-type="background" style="background-color:rgb(255, 255, 255)">补充下原因:服务端异步初衷是说Dubbo的服务端业务线程数(默认是200个)不够,但其实在event-driven模式下,200个肯定不需要那么多,只需要cpu核数那样就可以。只要业务实现是非阻塞的纯异步方式的业务逻辑处理,用再多的线程数都是浪费资源。</span></span></li>
+<li>要用服务端异步,建议服务端的线程策略采用same thread模式+协程包。</li>
 </ul>
 <h2>小结</h2>
 <p>Dubbo在支持业务应用时,会碰到千奇百怪的需求场景,服务端异步为用户提供了一种解决ThreadPool Full的方案。当发生ThreadPool Full的情况下,如果当前系统瓶颈是CPU,不建议用这种方案;如果系统Load不高,调高worker的线程数目,或者采用服务端异步,都是可以考虑的。</p>
diff --git a/zh-cn/blog/dubboAsync_server.json b/zh-cn/blog/dubboAsync_server.json
index 989ea0c..c8800aa 100644
--- a/zh-cn/blog/dubboAsync_server.json
+++ b/zh-cn/blog/dubboAsync_server.json
@@ -1,9 +1,9 @@
 {
   "filename": "dubboAsync_server.md",
-  "__html": "<h1>Dubbo服务端异步接口的实现背景和实践</h1>\n<h2>铺垫</h2>\n<p>建议先对Dubbo的处理过程中涉及的线程阶段先做个了解,具体可参考<a href=\"http://dubbo.apache.org/zh-cn/blog/dubboAsync_client.html\">Dubbo客户端异步接口的实现背景和使用场景</a>。</p>\n<h2>实现背景</h2>\n<p>有必要比较详细点的介绍下服务端的线程策略来加深用户在选择服务端异步的判断依据,同时有必要引出协程这一在服务端异步中常常会用到的“秘密武器”。</p>\n<h3>服务端的线程策略</h3>\n<p>Dubbo是支持多种NIO框架来做Remoting的协议实现,无论是Netty,Mina或者Grizzly,实现都大同小异,都是基于事件驱动的方式来做网络通道建立,数据流读取的,其中Grizzly对于线程策略介绍的为例,通常支持以下四种。Dubbo作为一个RPC框架,默认选择的是第一种策略,原因在于业务服务是CPU密集型还是IO阻�
 ��性,是无法断定的,第一种策 [...]
+  "__html": "<h1>Dubbo服务端异步接口的实现背景和实践</h1>\n<h2>铺垫</h2>\n<p>建议先对Dubbo的处理过程中涉及的线程阶段先做个了解,具体可参考<a href=\"http://dubbo.apache.org/zh-cn/blog/dubboAsync_client.html\">Dubbo客户端异步接口的实现背景和使用场景</a>。</p>\n<h2>实现背景</h2>\n<p>有必要比较详细点的介绍下服务端的线程策略来加深用户在选择服务端异步的判断依据,同时有必要引出协程这一在服务端异步中常常会用到的“秘密武器”。</p>\n<h3>服务端的线程策略</h3>\n<p>Dubbo支持多种NIO框架来做Remoting的协议实现,无论是Netty,Mina或者Grizzly,实现都大同小异,都是基于事件驱动的方式来做网络通道建立,数据流读取的。其中以Grizzly对于<a href=\"https://javaee.github.io/grizzly/iostrategies.html\">线程策略</a>的介绍为例,通常支 [...]
   "link": "/zh-cn/blog/dubboAsync_server.html",
   "meta": {
-    "title": "Dubbo客户端异步接口的实现背景和实践",
+    "title": "Dubbo服务端异步接口的实现背景和实践",
     "keywords": "Dubbo, 异步, Reactive",
     "description": "Dubbo服务端异步接口的实现背景和实践"
   }