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

git-site-role 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 c849e88  Website updated with 3078d28eb0e1b6b8f2523cbd90a619062396670c
c849e88 is described below

commit c849e88e411f2ae271e46fdf6de935a186e31c34
Author: jenkins <us...@infra.apache.org>
AuthorDate: Fri Sep 6 09:18:17 2019 +0000

    Website updated with 3078d28eb0e1b6b8f2523cbd90a619062396670c
---
 COMMIT_ID                          |   2 +-
 en-us/blog/dubboAsync_client.html  | 102 +++++++++++++++++++++++++++++++++++++
 en-us/blog/dubboAsync_client.json  |  10 ++++
 img/blog/dubboasyn_client/1_en.png | Bin 0 -> 17755 bytes
 md_json/blog.json                  |   9 ++++
 zh-cn/blog/dubboAsync_client.html  |   2 +-
 zh-cn/blog/dubboAsync_client.json  |   2 +-
 7 files changed, 124 insertions(+), 3 deletions(-)

diff --git a/COMMIT_ID b/COMMIT_ID
index 6563b9b..66d5d4c 100644
--- a/COMMIT_ID
+++ b/COMMIT_ID
@@ -1 +1 @@
-54aa1ad736ce575d5ae6cfe37f0b12fee43be1fc
+3078d28eb0e1b6b8f2523cbd90a619062396670c
diff --git a/en-us/blog/dubboAsync_client.html 
b/en-us/blog/dubboAsync_client.html
new file mode 100644
index 0000000..7ad1786
--- /dev/null
+++ b/en-us/blog/dubboAsync_client.html
@@ -0,0 +1,102 @@
+<!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, Asynchronous, Reactive" />
+       <meta name="description" content="Implementation background and 
practice of Dubbo client asynchronous interface" />
+       <!-- 网页标签标题 -->
+       <title>Implementation background and practice of Dubbo client 
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><img src="../../img/blog/dubboasyn_client/1_en.png" alt="image | left"></p>
+<p>Let's start with a brief introduction about the stages of a complete Dubbo 
invocation.</p>
+<ol>
+<li>
+<p>Biz~ represents business thread, that is, the thread where the business 
logic is located. Biz~ thread pool may be created and maintained by business 
itself, most of which may be managed by system framework itself (for example, a 
web system runs under Tomcat container, Biz~ thread is maintained by Tomcat); 
IO~ stands for network data processing thread, which is created and maintained 
by IO framework (such as Netty, Grizzly). Dubbo Remoting's default Netty 
implementation is NioEventloop [...]
+</li>
+<li>
+<p>As we all know, the way of data communication between threads is shared 
variables. The data communication between Biz and IO is Queue. Specifically to 
Dubbo, Biz put a task in EventLoop's LinkedBlockingQueue in the client side 
implementation (i.e. the steps labeled in Figure 1 above), and the 
corresponding Thread in the EventLoop will keep iteration the Queue to keep on 
executing the information the task contains. Specific code can refer to 
SingleThreadEventExecutor (by the way, the d [...]
+</li>
+<li>
+<p>As shown in the figure above, a standard RPC call passes through four 
message (event) transfers of 1,2,3,4, respectively are the client business 
thread sending requests to the client IO thread, the server business logic 
thread receiving the server IO thread requests, the server logic thread 
responding to the server IO thread after processing, and the client IO thread 
receiving the results feedback to the business logic thread.</p>
+</li>
+</ol>
+<h2>Client Asynchronization</h2>
+<h3>Background</h3>
+<p>In the Java language (other languages are not clear), a call of the local 
interface can be transparently converted into the call of remote RPC through 
the proxy mechanism. Most business parties prefer this programming method 
similar to the local interface to do remote service invocation. Therefore, 
although RPC is naturally asynchronous internally, users using Dubbo mostly use 
synchronization, while asynchrony becomes a minority use scenario. The 
advantage of synchronization is that t [...]
+<p>Therefore, the motivation of client asynchronization is to save thread 
resource overhead at the cost of understanding how asynchronization is used. In 
the synchronous mode, the return type of API interface represents a certain 
business class, while in the asynchronous case, the response and the request 
are completely independent events, so it is most suitable for the return type 
of API interface to be CompletionStage mentioned above, which is the inevitable 
asynchronization supported  [...]
+<p>The example blow is to illustrate it.</p>
+<h3>The sample</h3>
+<p>Refer to the example code for event notification: <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>
+<p>Event notification allows the Consumer to trigger 'oninvoke', 'onreturn' 
and 'onthrow' events, which respectively represent before the call, after the 
call returns normally, or when an exception occurs.</p>
+<p>You can specify a method for notifying events when configuring the 
Consumer, such as:</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>
+
+<span class="hljs-tag">&lt;<span class="hljs-name">dubbo:reference</span> 
<span class="hljs-attr">id</span>=<span 
class="hljs-string">"demoService"</span> <span 
class="hljs-attr">check</span>=<span class="hljs-string">"false"</span> <span 
class="hljs-attr">interface</span>=<span 
class="hljs-string">"com.alibaba.dubbo.samples.notify.api.DemoService"</span> 
<span class="hljs-attr">version</span>=<span class="hljs-string">"1.0.0"</span> 
<span class="hljs-attr">group</span>=<span class="hljs [...]
+    <span class="hljs-tag">&lt;<span class="hljs-name">dubbo:method</span> 
<span class="hljs-attr">name</span>=<span class="hljs-string">"sayHello"</span> 
<span class="hljs-attr">onreturn</span>=<span 
class="hljs-string">"demoCallback.onreturn"</span> <span 
class="hljs-attr">onthrow</span>=<span 
class="hljs-string">"demoCallback.onthrow"</span>/&gt;</span>
+<span class="hljs-tag">&lt;/<span 
class="hljs-name">dubbo:reference</span>&gt;</span>
+</code></pre>
+<p>The code for NotifyImpl is as follows:</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">NotifyImpl</span> <span 
class="hljs-keyword">implements</span> <span 
class="hljs-title">Notify</span></span>{
+
+    <span class="hljs-keyword">public</span> Map&lt;Integer, String&gt; ret = 
<span class="hljs-keyword">new</span> HashMap&lt;Integer, String&gt;();
+    
+    <span class="hljs-function"><span class="hljs-keyword">public</span> <span 
class="hljs-keyword">void</span> <span class="hljs-title">onreturn</span><span 
class="hljs-params">(String name, <span class="hljs-keyword">int</span> 
id)</span> </span>{
+        ret.put(id, name);
+        System.out.println(<span class="hljs-string">"onreturn: "</span> + 
name);
+    }
+
+    <span class="hljs-function"><span class="hljs-keyword">public</span> <span 
class="hljs-keyword">void</span> <span class="hljs-title">onthrow</span><span 
class="hljs-params">(Throwable ex, String name, <span 
class="hljs-keyword">int</span> id)</span> </span>{
+        System.out.println(<span class="hljs-string">"onthrow: "</span> + 
name);
+    }
+}
+</code></pre>
+<p>It is important to note that the parameters for the three methods in the 
custom Notify interface are as follows:</p>
+<ul>
+<li><code>oninvoke</code> The parameters of the method are the same as those 
of the calling method.</li>
+<li><code>onreturn</code> The first parameter of the method is the return 
value of the calling method, and the rest is the parameters of the calling 
method.</li>
+<li><code>onthrow</code> The first parameter to the method is the call 
exception, and the rest is the parameter to the calling method.</li>
+</ul>
+<p>In the above configuration, the <code>sayHello</code> method is called 
synchronously, so the execution of the event notification method is also 
synchronously executed. <code>async=true</code> can be configured to make the 
method call asynchronous, and the notification event method is also executed 
asynchronously. In particular, the <code>oninvoke</code> method executes 
synchronously, regardless of whether it is invoked asynchronously or not.</p>
+<h3>Practical advice</h3>
+<ul>
+<li>
+<div data-type="alignment" data-value="justify" style="text-align:justify">
+<div data-type="p">Logical Non-Strongly dependent results after RPC 
invocation: Asynchronous callbacks are suitable for client-side asynchronous 
invocation when the client <strong>is not strongly dependent on the server 
response</strong>.</div>
+</div>
+</li>
+<li>
+<div data-type="alignment" data-value="justify" style="text-align:justify">
+<div data-type="p">RX scenario: after learning about reactive programming 
model, I believe that as long as the programming thinking can embrace reactive 
and the state machine design of business model can be adjusted appropriately, 
asynchronous solutions can be applied in all scenarios, so as to achieve better 
terminal response experience. For Dubbo, the current asynchronous interface 
model needs to be improved like the reactive model interface in order to make 
the user more naturally app [...]
+</div>
+</li>
+</ul>
+<h3>Conclusions</h3>
+<ul>
+<li>The motivation of client asynchronization is that the request sending and 
response processing are two different independent events, how the response is 
handled and in which thread is handled are not required to be coupled with the 
business logic thread of the request sending event.</li>
+<li>The processing logic of response event callbacks in which thread to 
process is to be selected according to the situation. It is recommended that if 
the callback logic is relatively simple, it should be directly in the IO 
thread; if it contains IO type synchronization operations such as remote access 
or DB access, it is recommended that it be processed in a separate thread 
pool.</li>
+</ul>
+</section><footer class="footer-container"><div class="footer-body"><img 
src="/img/dubbo_gray.png"/><img class="apache" src="/img/apache_logo.png"/><div 
class="cols-container"><div class="col col-12"><h3></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_client.json 
b/en-us/blog/dubboAsync_client.json
new file mode 100644
index 0000000..dcad29e
--- /dev/null
+++ b/en-us/blog/dubboAsync_client.json
@@ -0,0 +1,10 @@
+{
+  "filename": "dubboAsync_client.md",
+  "__html": "<h1>Implementation background and practice of Dubbo client 
asynchronous interface</h1>\n<h2>Preface</h2>\n<p><img 
src=\"../../img/blog/dubboasyn_client/1_en.png\" alt=\"image | 
left\"></p>\n<p>Let's start with a brief introduction about the stages of a 
complete Dubbo invocation.</p>\n<ol>\n<li>\n<p>Biz~ represents business thread, 
that is, the thread where the business logic is located. Biz~ thread pool may 
be created and maintained by business itself, most of which may be m [...]
+  "link": "/en-us/blog/dubboAsync_client.html",
+  "meta": {
+    "title": "Implementation background and practice of Dubbo client 
asynchronous interface",
+    "keywords": "Dubbo, Asynchronous, Reactive",
+    "description": "Implementation background and practice of Dubbo client 
asynchronous interface"
+  }
+}
\ No newline at end of file
diff --git a/img/blog/dubboasyn_client/1_en.png 
b/img/blog/dubboasyn_client/1_en.png
new file mode 100644
index 0000000..6e12e51
Binary files /dev/null and b/img/blog/dubboasyn_client/1_en.png differ
diff --git a/md_json/blog.json b/md_json/blog.json
index 1b92cd4..3fb6727 100644
--- a/md_json/blog.json
+++ b/md_json/blog.json
@@ -163,6 +163,15 @@
       }
     },
     {
+      "filename": "dubboAsync_client.md",
+      "link": "/en-us/blog/dubboAsync_client.html",
+      "meta": {
+        "title": "Implementation background and practice of Dubbo client 
asynchronous interface",
+        "keywords": "Dubbo, Asynchronous, Reactive",
+        "description": "Implementation background and practice of Dubbo client 
asynchronous interface"
+      }
+    },
+    {
       "filename": "gsoc-2018.md",
       "link": "/en-us/blog/gsoc-2018.html",
       "meta": {
diff --git a/zh-cn/blog/dubboAsync_client.html 
b/zh-cn/blog/dubboAsync_client.html
index 436abd2..958acfa 100644
--- a/zh-cn/blog/dubboAsync_client.html
+++ b/zh-cn/blog/dubboAsync_client.html
@@ -29,7 +29,7 @@
 </ol>
 <h2>客户端异步</h2>
 <h3>实现背景</h3>
-<p>在Java语言(其他语言不清楚)下一次本地接口的调用可以透明地通过代理机制转为远程RPC的调用,大多数业务方也比较喜欢这种与本地接口类似的编程方式做远程服务集成,所以虽然RPC内部天然是异步的,但使用Dubbo的用户使用最广泛的还是同步,而异步反而成为小众的使用场景。同步的优点是编程模型更加符合业务方的“传统”习惯,代价是在图中的1代表的请求发出事件后需要阻塞当前的Biz~线程,一直等到4代表的响应处理后才能唤醒。在这个短则微妙级别,长则秒级的1,2,3,4处理过程中都要阻塞Biz~线程,就会消耗线程资源,增加系统资源的开销。</p>
+<p>在Java语言(其他语言不清楚)下一次本地接口的调用可以透明地通过代理机制转为远程RPC的调用,大多数业务方也比较喜欢这种与本地接口类似的编程方式做远程服务集成,所以虽然RPC内部天然是异步的,但使用Dubbo的用户使用最广泛的还是同步,而异步反而成为小众的使用场景。同步的优点是编程模型更加符合业务方的“传统”习惯,代价是在图中的1代表的请求发出事件后需要阻塞当前的Biz~线程,一直等到4代表的响应处理后才能唤醒。在这个短则微秒级别,长则秒级的1,2,3,4处理过程中都要阻塞Biz~线程,就会消耗线程资源,增加系统资源的开销。</p>
 
<p>所以,客户端异步的出发点是节省线程资源开销,代价是需要了解下异步的使用方式:)。在同步方式下API接口的返回类型是代表着某个业务类,而当异步情况下,响应返回与请求发出是完全独立的两个事件,需要API接口的返回类型变为上述中说的CompletionStage才是最贴合的,这是Dubbo在异步上支持的必然异步。回到最近的Dubbo发布版,是不改变接口的情况下,需要在服务创建时注册一个回调接口来处理响应返回事件。</p>
 <p>下面以示例来说。</p>
 <h3>示例</h3>
diff --git a/zh-cn/blog/dubboAsync_client.json 
b/zh-cn/blog/dubboAsync_client.json
index d4159f3..6367a61 100644
--- a/zh-cn/blog/dubboAsync_client.json
+++ b/zh-cn/blog/dubboAsync_client.json
@@ -1,6 +1,6 @@
 {
   "filename": "dubboAsync_client.md",
-  "__html": "<h1>Dubbo客户端异步接口的实现背景和实践</h1>\n<h2>铺垫</h2>\n<p><img 
src=\"../../img/blog/dubboasyn_client/1.png\" alt=\"image | 
left\"></p>\n<p>先简单介绍下一次完整的Dubbo调用所经历的线程阶段。几个信息这里罗列下</p>\n<ol>\n<li>\n<p>Biz~代表业务线程,即便是业务逻辑处理所处的线程,Biz~线程池可能是业务自己创建维护,大多数的可能是系统框架自身管理的(比如web型的业务系统跑在Tomcat容器下,Biz~线程就是Tomcat维护);IO~代表网络数据处理线程,是IO框架(比如Netty,Grizzly)创建维护,Dubbo
 
Remoting所默认Netty实现是NioEventloopLoopGroup;另外按照Channel与IO线程的绑定关系,也可以直接把IO~看成一个可接受事件消息的Channel。像Biz和IO这样的异步处理阶段在JDK8中有个很精确地抽象描述,叫CompletionStage。</
 [...]
+  "__html": "<h1>Dubbo客户端异步接口的实现背景和实践</h1>\n<h2>铺垫</h2>\n<p><img 
src=\"../../img/blog/dubboasyn_client/1.png\" alt=\"image | 
left\"></p>\n<p>先简单介绍下一次完整的Dubbo调用所经历的线程阶段。几个信息这里罗列下</p>\n<ol>\n<li>\n<p>Biz~代表业务线程,即便是业务逻辑处理所处的线程,Biz~线程池可能是业务自己创建维护,大多数的可能是系统框架自身管理的(比如web型的业务系统跑在Tomcat容器下,Biz~线程就是Tomcat维护);IO~代表网络数据处理线程,是IO框架(比如Netty,Grizzly)创建维护,Dubbo
 
Remoting所默认Netty实现是NioEventloopLoopGroup;另外按照Channel与IO线程的绑定关系,也可以直接把IO~看成一个可接受事件消息的Channel。像Biz和IO这样的异步处理阶段在JDK8中有个很精确地抽象描述,叫CompletionStage。</
 [...]
   "link": "/zh-cn/blog/dubboAsync_client.html",
   "meta": {
     "title": "Dubbo客户端异步接口的实现背景和实践",

Reply via email to