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

liujun 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 ef71019  update async blog: format source
ef71019 is described below

commit ef7101962ec68c82a8cd75358048cbd35dd3077e
Author: ken.lj <[email protected]>
AuthorDate: Fri Apr 19 00:17:11 2019 +0800

    update async blog: format source
---
 blog/zh-cn/dubbo-new-async.md | 151 +++++++++++-------------------------------
 1 file changed, 38 insertions(+), 113 deletions(-)

diff --git a/blog/zh-cn/dubbo-new-async.md b/blog/zh-cn/dubbo-new-async.md
index 79e8f66..d3aab4c 100644
--- a/blog/zh-cn/dubbo-new-async.md
+++ b/blog/zh-cn/dubbo-new-async.md
@@ -15,15 +15,15 @@ description: 本文回顾了 2.6.x 版本的异步实现,然后引出了 2.7.0
 > 2. 你是否需要RPC请求可以是Cold,在subscribe后触发,CompletableFuture总是hot的
 > 3. 你的依赖的编程上下文中是否已经在大量使用Reactive的编程接口
 > 4. 你是否需要Rx框架提供的更丰富的Operator,而这点和1又是密切相关的
-
-关于参数回调,其本质上是一种服务端的数据推送能力,这是终端应用很常见的一种需求,关于这部分的重构计划,不在本文讨论范围。
-                                                                               
                                          
+                                                                               
                                         
 
 
 ## 2.6.x版本之前的异步方式
 
 
在2.6.x及之前的版本提供了一定的异步编程能力,包括Consumer端[异步调用](http://dubbo.apache.org/zh-cn/docs/user/demos/async-call.html)、[参数回调](http://dubbo.apache.org/zh-cn/docs/user/demos/callback-parameter.html)、[事件通知](http://dubbo.apache.org/zh-cn/docs/user/demos/events-notify.html)等,在上面的文档链接中有关于使用方式的简单介绍和Demo。
 
+关于参数回调,其本质上是一种服务端的数据推送能力,这是终端应用很常见的一种需求,关于这部分的重构计划,不在本文讨论范围。
+
 但当前的异步方式存在以下问题:
 
 - Future获取方式不够直接
@@ -34,13 +34,13 @@ description: 本文回顾了 2.6.x 版本的异步实现,然后引出了 2.7.0
 
 1. 定义一个普通的同步接口并声明支持异步调用
 
-```
+```java
 public interface FooService {
     String findFoo(String name);
 }
 ```
 
-```
+```xml
 <dubbo:reference id="fooService" interface="com.alibaba.foo.FooService">
       <dubbo:method name="findFoo" async="true" />
 </dubbo:reference>
@@ -48,7 +48,7 @@ public interface FooService {
 
 2. 通过RpcContext获取Future
 
-```
+```java
 // 此调用会立即返回null
 fooService.findFoo(fooId);
 // 拿到调用的Future引用,当结果返回后,会被通知和设置到此Future
@@ -58,7 +58,7 @@ fooFuture.get();
 
 或
 
-```
+```java
 // 此调用会立即返回null
 fooService.findFoo(fooId);
 // 拿到Dubbo内置的ResponseFuture并设置回调
@@ -92,14 +92,11 @@ Dubbo在2.7.0版本已经升级了对Java 8的支持,同时基于CompletableFu
 
    
 
-   ```
+   ```java
    public interface AsyncService {
        CompletableFuture<String> sayHello(String name);
    }
    ```
-
-   
-
    
 
 2. 
如果你不想将接口的返回值定义为Future类型,或者存在定义好的同步类型接口,则可以选择重载原始方法并为新方法定义CompletableFuture类型返回值。
@@ -131,7 +128,9 @@ Dubbo在2.7.0版本已经升级了对Java 8的支持,同时基于CompletableFu
    这样,Provider依然可以只实现sayHi方法;而Consumer通过直接调用新增的sayHi重载方法可以拿到一个Future实例。
    
 
-3. 如果你的原始接口定义是同步的,这时要实现Provider端异步,则可以使用AsyncContext(类似Servlet 
3.0里的AsyncContext的编程接口)。注意:在已有CompletabeFuture返回类型的接口上,不建议再使用AsyncContext,请直接利用CompletableFuture带来的异步能力。
+3. 如果你的原始接口定义是同步的,这时要实现Provider端异步,则可以使用AsyncContext(类似Servlet 
3.0里的AsyncContext的编程接口)。
+
+> 
注意:在已有CompletabeFuture返回类型的接口上,不建议再使用AsyncContext,请直接利用CompletableFuture带来的异步能力。
  
 
    ```
@@ -172,31 +171,23 @@ Dubbo在2.7.0版本已经升级了对Java 8的支持,同时基于CompletableFu
 
 ## 示例1:CompletableFuture类型接口
 
-CompletableFuture类型的接口既可以用作同步调用,也可以实现Consumer或Provider的异步调用。本示例实现了Consumer和Provider端异步调用,代码参见[dubbo-samples-async-original-future](https://github.com/apache/incubator-dubbo-samples/tree/master/dubbo-samples-async/dubbo-samples-async-original-future)。
+CompletableFuture类型的接口既可以用作同步调用,也可以实现Consumer或Provider的异步调用。本示例实现了Consumer和Provider端异步调用,代码参见[dubbo-samples-async-original-future](https://github.com/apache/incubator-dubbo-samples/tree/3.x/dubbo-samples-async/dubbo-samples-async-original-future)。
 
 1. 定义接口
-
    
-
-   ```
+   ```java
    public interface AsyncService {
        CompletableFuture<String> sayHello(String name);
    }
    ```
 
-   
-
    注意接口的返回类型是`CompletableFuture<String>`。
 
 2. Provider端
 
-   
-
    - 实现
 
-     
-
-     ```
+     ```java
      public class AsyncServiceImpl implements AsyncService {
          public CompletableFuture<String> sayHello(String name) {
              return CompletableFuture.supplyAsync(() -> {
@@ -211,46 +202,29 @@ CompletableFuture类型的接口既可以用作同步调用,也可以实现Con
      }
      ```
 
-     
-
      可以看到这里通过supplyAsync将业务代码切换到了新的线程执行,因此实现了Provider端异步。
 
    - 配置
 
-     
-
-     ```
+     ```xml
      <bean id="asyncService" 
class="com.alibaba.dubbo.samples.async.impl.AsyncServiceImpl"/>
      <dubbo:service 
interface="com.alibaba.dubbo.samples.async.api.AsyncService" 
ref="asyncService"/>
      ```
 
-     
-
-     配置方式和普通接口是一样。
+     配置方式和普通接口是一样的。
 
 3. Consumer端
 
-   
-
    - 配置
 
-   
-
-   ```
+   ```xml
    <dubbo:reference id="asyncService" timeout="10000" 
interface="com.alibaba.dubbo.samples.async.api.AsyncService"/>
    ```
-
-   
-
-   ​   配置方式和普通接口是一样。
-
-   
+   ​   配置方式和普通接口是一样的。
 
    - 调用远程服务
 
-   
-
-   ```
+   ```java
    public static void main(String[] args) throws Exception {
            ClassPathXmlApplicationContext context = new 
ClassPathXmlApplicationContext(new 
String[]{"META-INF/spring/async-consumer.xml"});
            context.start();
@@ -269,8 +243,6 @@ CompletableFuture类型的接口既可以用作同步调用,也可以实现Con
        }
    ```
 
-   
-
    `CompletableFuture<String> future = asyncService.sayHello("async call 
request");`很自然的返回了Future示例,这样就实现了Consumer端的异步服务调用。
 
 ## 示例2:重载同步接口
@@ -279,41 +251,32 @@ CompletableFuture类型的接口既可以用作同步调用,也可以实现Con
 
 1. 定义接口
 
-   
-
-   ```
+   ```java
    @DubboAsync
    public interface GreetingsService {
        String sayHi(String name);
    }
    ```
 
-   
-
    修改接口,增加重载方法
 
     ```java
     public interface GreetingsService {
         String sayHi(String name);
       
-        default CompletableFuture<String> sayHi(String name, boolean 
placeHolder) {
+        default CompletableFuture<String> sayHi(String name, boolean isAsync) {
           return CompletableFuture.completedFuture(sayHello(name));
         }
     }
     ```
-    
-    
-   
 
 2. Provider端
 
-   
 
    - 配置
 
-   
 
-   ```
+   ```xml
    <bean id="greetingsService" 
class="com.alibaba.dubbo.samples.async.impl.GreetingsServiceImpl"/>
    <dubbo:service interface="com.alibaba.dubbo.samples.api.GreetingsService" 
ref="greetingsService"/>
    ```
@@ -322,9 +285,7 @@ CompletableFuture类型的接口既可以用作同步调用,也可以实现Con
 
    - 服务实现
 
-   
-
-   ```
+   ```java
    public class GreetingsServiceImpl implements GreetingsService {
        @Override
        public String sayHi(String name) {
@@ -335,33 +296,21 @@ CompletableFuture类型的接口既可以用作同步调用,也可以实现Con
 
 3. Consumer端
 
-   
-
    - 配置
 
-   
-
-   ```
+   ```xml
     <dubbo:reference id="greetingsService" 
interface="com.alibaba.dubbo.samples.api.GreetingsService"/>
    ```
 
-   
-
-   注意,服务接口用的是**GreetingsServiceAsync**
-
-   
-
    - 调用服务
 
-   
-
-   ```
+   ```java
     public static void main(String[] args) throws Exception {
            ClassPathXmlApplicationContext context = new 
ClassPathXmlApplicationContext(new 
String[]{"META-INF/spring/async-consumer.xml"});
            context.start();
    
            GreetingsService greetingsService = (GreetingsService) 
context.getBean("greetingsService");
-           CompletableFuture<String> future = greetingsService.sayHi("async 
call reqeust");
+           CompletableFuture<String> future = greetingsService.sayHi("async 
call reqeust", true);
            System.out.println("async call ret :" + future.get());
         
            System.in.read();
@@ -370,46 +319,34 @@ CompletableFuture类型的接口既可以用作同步调用,也可以实现Con
 
    
 
-   这样,我们就可以直接使用`CompletableFuture<String> future = 
greetingsService.sayHi("async call reqeust");`,直接返回CompletableFuture。
+   这样,我们就可以直接使用`CompletableFuture<String> future = 
greetingsService.sayHi("async call reqeust", true);`,直接返回CompletableFuture。
 
 ## 示例3:使用AsyncContext
 
 
本示例演示了如何在同步接口的基础上,通过AsyncContext实现Provider端异步执行,示例代码参见[dubbo-samples-async-provider](https://github.com/apache/incubator-dubbo-samples/tree/3.x/dubbo-samples-async/dubbo-samples-async-provider)。
 
-1. 定义接口
+> 之前已经提到过,已经是CompletableFuture签名的接口,要实现Provider端异步没必要再用AsyncContext。
 
-   
+1. 定义接口
 
-   ```
+   ```java
    public interface AsyncService {
        String sayHello(String name);
    }
    ```
 
-   
-
-   
-
 2. Provider端,和普通provider端配置完全一致
 
-   
-
    - 配置
 
-   
-
-   ```
+   ```xml
    <bean id="asyncService" 
class="com.alibaba.dubbo.samples.async.impl.AsyncServiceImpl"/>
    <dubbo:service async="true" 
interface="com.alibaba.dubbo.samples.async.api.AsyncService" 
ref="asyncService"/>
    ```
 
-   
-
    - 异步执行实现
-
    
-
-   ```
+   ```java
    public class AsyncServiceImpl implements AsyncService {
        public String sayHello(String name) {
            final AsyncContext asyncContext = RpcContext.startAsync();
@@ -429,23 +366,15 @@ CompletableFuture类型的接口既可以用作同步调用,也可以实现Con
 
 3. Consumer端
 
-   
-
    - 配置
 
-   
-
-   ```
+   ```xml
    <dubbo:reference id="asyncService" 
interface="com.alibaba.dubbo.samples.async.api.AsyncService"/>
    ```
 
-   
-
    - 服务调用
 
-   
-
-   ```
+   ```java
     public static void main(String[] args) throws Exception {
            ClassPathXmlApplicationContext context = new 
ClassPathXmlApplicationContext(new 
String[]{"META-INF/spring/async-consumer.xml"});
            context.start();
@@ -457,19 +386,15 @@ CompletableFuture类型的接口既可以用作同步调用,也可以实现Con
        }
    ```
 
-   
-
-   
-
 ## 异步引入的新问题
 
 ### Filter链
 
-以下是一次普通Dubbo调用的完整Filter链
+以下是一次普通Dubbo调用的完整Filter链(Filter链路图待补充)。
 
 而采用异步调用后,由于异步结果在异步线程中单独执行,所以流经后半段Filter链的Result是空值,当真正的结果返回时已无法被Filter链处理。
 
-为了解决这个问题,2.7.0中引入了PostProcessFilter和AbstractPostProcessFilter,其中,PostProcessFilter接口继承自Filter接口,AbstractPostProcessFilter是PostProcessFilter的抽象实现。
+为了解决这个问题,2.7.0中为Filter增加了回调接口onResponse。
 
 以下是一个扩展Filter并支持异步Filter链的例子
 
@@ -496,7 +421,7 @@ public class AsyncPostprocessFilter implements Filter {
 
 当前我们考虑的上下文主要是指保存在RpcContext中的数据,大多数场景是需要用户在切换业务线程前自己完成Context的传递。
 
-```
+```java
 public class AsyncServiceImpl implements AsyncService {
     // 保存当前线程的上下文
     RpcContext context = RpcContext.getContext();
@@ -517,7 +442,7 @@ public class AsyncServiceImpl implements AsyncService {
 
 不过AsyncContext也提供了signalContextSwitch()的方法来实现方便的Context切换。
 
-```
+```java
 public class AsyncServiceImpl implements AsyncService {
     public String sayHello(String name) {
         final AsyncContext asyncContext = RpcContext.startAsync();

Reply via email to