You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@dubbo.apache.org by al...@apache.org on 2021/06/07 07:37:31 UTC

[dubbo-website] branch master updated: create feature docs on 2.7.12 (#820)

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

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


The following commit(s) were added to refs/heads/master by this push:
     new fd76a54  create feature docs on 2.7.12 (#820)
fd76a54 is described below

commit fd76a54ad10cf9b8b865608985e86b7abf26bc6e
Author: Uarealoser <44...@users.noreply.github.com>
AuthorDate: Mon Jun 7 15:37:22 2021 +0800

    create feature docs on 2.7.12 (#820)
    
    * add provider-timeout.md
    
    * add broadcast-resp-collect.md,invoke-with-ip.md,provider-timeout-release.md
    
    * update provider-timeout-release.md
    
    * Create provider-timeout-release.md
    
    * update provider-timeout-release.md,provider-timeout-release.md
    
    * Update provider-timeout-release.md
    
    * Create broadcast-resp-collect.md
    
    * add invoke-with-specified-ip.md
    
    * Create invoke-with-specified-ip.md
    
    * update invoke-with-specified-ip.md
    
    * update
    
    * update weight
    
    Co-authored-by: wuzhihao <wu...@xiaomi.com>
    Co-authored-by: Wei Zhou <69...@users.noreply.github.com>
---
 .../v2.7/user/examples/broadcast-resp-collect.md   |  71 ++++++++++
 .../v2.7/user/examples/invoke-with-specified-ip.md |  78 +++++++++++
 .../v2.7/user/examples/provider-timeout-release.md | 137 +++++++++++++++++++
 .../v2.7/user/examples/broadcast-resp-collect.md   |  72 ++++++++++
 .../v2.7/user/examples/invoke-with-specified-ip.md |  78 +++++++++++
 .../v2.7/user/examples/provider-timeout-release.md | 147 +++++++++++++++++++++
 6 files changed, 583 insertions(+)

diff --git a/content/en/docs/v2.7/user/examples/broadcast-resp-collect.md b/content/en/docs/v2.7/user/examples/broadcast-resp-collect.md
new file mode 100644
index 0000000..3a2aff0
--- /dev/null
+++ b/content/en/docs/v2.7/user/examples/broadcast-resp-collect.md
@@ -0,0 +1,71 @@
+---
+type: docs
+title: "Collect Broadcast Responses"
+linkTitle: "Collect Broadcast Responses"
+weight: 15
+description: "Dubbo broadcast2 broadcast mode collects port responses from all providers"
+---
+
+Applicable scenario: for any Dubbo consumer, broadcast calls multiple service providers. The consumer is able to collect responses from all of the providers. 
+
+{{% alert title="Notice" color="primary" %}}
+support on `2.7.12` or above.
+{{% /alert %}}
+
+## Demo
+
+- consumer demo
+
+@Reference imports providers. Within the brackets, letting cluster = "broadcast2" represents doing one broadcast call that collects providers' responses. 
+
+Broadcast calls all service providers one by one. Is able to return all service providers’ execution outcomes (success or exceptions) completely and stores 
+providers' responses in RpcContext. 
+
+```java
+@RestController
+public class TestServiceConsumer {
+    @Reference(interfaceClass = DubboHealthService.class,cluster = "broadcast2")
+    private DubboHealthService dubboHealthService;
+    
+     @GetMapping("/health")
+         public String broadCast(){
+             try{
+                 dubboHealthService.health();
+             }catch (Exception e){
+                 Map<String, String> m = RpcContext.getServerContext().getAttachments();
+                 return m.toString()+"|"+"fail";
+             }
+             Map<String, String> m = RpcContext.getServerContext().getAttachments();
+             return m.toString()+"|"+"success";
+         }
+}
+```
+
+- provider demo
+
+```java
+@Service
+public class DubboHealthServiceImpl implements DubboHealthService {
+    @Override
+    public String health() {
+//        int i = 1/0;
+        return "i am provider2";
+    }
+}
+```
+
+- execution outcome
+
+All providers succeed:
+
+```
+>curl http://localhost:8081/health
+>{broadcast.results=[{"ip":"10.220.47.253","port":20880,"data":"i am provider1"},{"ip":"10.220.47.253","port":20881,"data":"i am provider2"}]}|success%  
+```
+
+Let one of the providers divide by zero:
+
+```
+>curl http://localhost:8081/health
+>{broadcast.results=[{"ip":"10.220.47.253","port":20880,"data":"i am provider1"},{"ip":"10.220.47.253","port":20881,"exceptionMsg":"/ by zero"}]}|success%     
+```
diff --git a/content/en/docs/v2.7/user/examples/invoke-with-specified-ip.md b/content/en/docs/v2.7/user/examples/invoke-with-specified-ip.md
new file mode 100644
index 0000000..cee10d3
--- /dev/null
+++ b/content/en/docs/v2.7/user/examples/invoke-with-specified-ip.md
@@ -0,0 +1,78 @@
+---
+type: docs
+title: "Invoke provider with specified IP port"
+linkTitle: "Specified IP port"
+weight: 15
+description: "For multiple instances registered in the provider cluster, specify Ip:Port to invoke."
+---
+
+When multiple providers are registered at the register center, dynamically specifying one of the instances’ IP through RpcContext is enabled. Port does Dubbo invoke.
+
+{{% alert title="Notice" color="primary" %}}
+support on `2.7.12` or above.
+{{% /alert %}}
+
+## Demo
+
+- provider demo
+
+Assume two registered providers at the register center are provided, which are 10.220.47.253:20880;10.220.47.253:20881; respectively.  
+
+```java
+// 10.220.47.253:20880
+@Service(interfaceClass = TestService.class)
+public class TestServiceImpl implements TestService {
+    @Override
+    public String sayHello(String name) {
+        return "Hello "+name+" i am provider1";
+    }
+}
+// 10.220.47.253:20881
+@Service(interfaceClass = TestService.class)
+public class TestServiceImpl implements TestService {
+    @Override
+    public String sayHello(String name) {
+        return "Hello "+name+" i am provider2";
+    }
+}
+```
+
+- consumer demo
+
+@DubboReference introduces provider. Setting parameters = {"router","address"} specifies routing method.
+
+For the instance that is going to be invoked, specify its IP, construct Address object with Port and set RpcContext key as "address". Value is that object.
+
+```java
+// require dependent class
+import org.apache.dubbo.rpc.RpcContext;
+import org.apache.dubbo.rpc.cluster.router.address.Address;
+    
+@RestController
+public class TestServiceConsumer {
+    @DubboReference(interfaceClass = TestService.class,group = "dev",parameters = {"router","address"})
+    private TestService testService;
+   
+    @GetMapping("/invokeByIpPortSpecified")
+    public String invokeByIp(){
+        try {
+            // create Address instance based on provider's ip port
+            Address address = new Address("10.220.47.253", 20880);
+            RpcContext.getContext().setObjectAttachment("address", address);
+            return testService.sayHello("Tom");
+        }catch (Throwable ex){
+            return ex.getMessage();
+        }
+    }
+
+}
+```
+
+- execution outcome
+
+After running the code multiple times we can see that the same "Hello Tom i am provider1" is returned. In other words, we always route to the instance where port 20880 is located. 
+
+```
+>curl http://localhost:8081/invokeByIpPortSpecified
+>Hello Tom i am provider1             
+```
diff --git a/content/en/docs/v2.7/user/examples/provider-timeout-release.md b/content/en/docs/v2.7/user/examples/provider-timeout-release.md
new file mode 100644
index 0000000..ff93221
--- /dev/null
+++ b/content/en/docs/v2.7/user/examples/provider-timeout-release.md
@@ -0,0 +1,137 @@
+---
+type: docs
+title: "provider timeout release"
+linkTitle: "provider timeout release"
+weight: 15
+description: "Dubbo provider executes timeout release"
+---
+
+Dubbo allows providers to shutdown operations based on how long the timeout lasts.
+
+Applicable scenario: when a certain operation times out, providers can release that thread instead of simply printing out the timeout log message.
+
+{{% alert title="Notice" color="primary" %}}
+support on `2.7.12` or above.
+{{% /alert %}}
+
+## Main Logic
+
+```java
+public class AllChannelHandler2 extends AllChannelHandler {
+    public static final Timer TIME_OUT_TIMER = new HashedWheelTimer(
+            new NamedThreadFactory("dubbo-server-future-timeout", true),
+            30,
+            TimeUnit.MILLISECONDS);
+    public AllChannelHandler2(ChannelHandler handler, URL url) {
+        super(handler, url);
+    }
+    @Override
+    public void received(Channel channel, Object message) throws RemotingException {
+        ExecutorService executor = getPreferredExecutorService(message);
+        try {
+            Future<?> future = executor.submit(new ChannelEventRunnable(channel, handler, ChannelState.RECEIVED, message));
+            long timeout = this.url.getParameter("timeout", 1000) + 90;
+            TIME_OUT_TIMER.newTimeout(t -> {
+                if (!future.isDone() && (!future.isCancelled())) {
+                    try {
+                        future.cancel(true);
+                    } catch (Throwable ex) {
+                        //ignore
+                    }
+                }
+            }, timeout, TimeUnit.MILLISECONDS);
+        } catch (Throwable t) {
+            if (message instanceof Request && t instanceof RejectedExecutionException) {
+                sendFeedback(channel, (Request) message, t);
+                return;
+            }
+            throw new ExecutionException(message, channel, getClass() + " error when process received event .", t);
+        }
+    }
+}
+```
+
+## Demo
+
+- Set Dubbo ProtocolConfig thread dispatch strategy as "all2".
+
+```java
+	/**
+	 * Configuration Protocol
+	 */
+	@Bean
+	public ProtocolConfig protocolConfig() {
+		ProtocolConfig protocolConfig = new ProtocolConfig();
+		protocolConfig.setName("dubbo");
+		protocolConfig.setPort(-1);
+		protocolConfig.setTransporter("netty4");
+		protocolConfig.setThreadpool("fixed");
+        // Set up thread dispatch strategy
+        protocolConfig.setDispatcher("all2");
+        protocolConfig.setThreads(200);
+		return protocolConfig;
+	}
+```
+
+- provider demo
+
+When timeout, the thread will be stopped. In other words, if providers cannot return results to the consumers in time, then the thread will be stopped.
+
+```java
+// Set provider timeout period as 1000ms
+@Service(interfaceClass = TestService.class,timeout = 1000)
+public class TestServiceImpl implements TestService {
+    @Override
+    public Integer sum(int a, int b) {
+        CountDownLatch latch = new CountDownLatch(2);
+        AtomicInteger i = new AtomicInteger();
+        new Thread(()->{
+            i.incrementAndGet();
+            latch.countDown();
+        }).start();
+        new Thread(()->{
+            try {
+                TimeUnit.MILLISECONDS.sleep(2000); 
+            }catch (InterruptedException e){
+                e.printStackTrace();
+            }
+            i.incrementAndGet();
+            latch.countDown();
+        }).start();
+        try {
+            latch.await();
+            return i.get();
+        }catch (InterruptedException e){
+            // when timeout, return the following
+            throw new RuntimeException("call sum timeout");
+        }
+    }
+}
+```
+As for the provider demo above, when running the last try-catch, if the thread is released then catch InterruptedException and return "call sum timeout".
+
+
+- consumer demo
+
+```java
+    // Set consumer timeout period as 2000 longer than the server execution period
+    @Reference(check = false,interfaceClass = TestService.class,timeout = 3000)
+    private TestService testService;
+    @GetMapping("/sum")
+    public String consumeSum(){
+        Integer ret = 0;
+        try{
+             ret = testService.sum(1,1);
+        }catch (Exception e){
+           return e.getMessage();
+        }
+        return String.valueOf(ret);
+    }
+```
+
+- execution outcome
+
+```
+curl http://localhost:8081/sum
+>call sum timeout 
+```
diff --git a/content/zh/docs/v2.7/user/examples/broadcast-resp-collect.md b/content/zh/docs/v2.7/user/examples/broadcast-resp-collect.md
new file mode 100644
index 0000000..0fa9919
--- /dev/null
+++ b/content/zh/docs/v2.7/user/examples/broadcast-resp-collect.md
@@ -0,0 +1,72 @@
+---
+type: docs
+title: "收集Dubbo广播响应"
+linkTitle: "收集广播响应"
+weight: 15
+description: "Dubbo broadcast2 广播模式收集所有服务提供者的接口响应"
+---
+
+适用场景:对于一个dubbo消费者,广播调用多个dubbo 提供者,该消费者可以收集所有服务提供者的响应结果。
+
+{{% alert title="提示" color="primary" %}}
+支持版本:`2.7.12` 之后
+{{% /alert %}}
+
+## 使用示例
+
+- consumer demo
+
+@Reference引入服务提供者,其中,令cluster="broadcast2",代表进行一个收集响应结果的广播调用。
+
+广播调用所有服务提供者,逐个调用,并且可以完整的返回所有服务提供者的执行结果(正确或异常),并将所有服务提供者的响应结果存于RpcContext。
+
+```java
+@RestController
+public class TestServiceConsumer {
+
+    @Reference(interfaceClass = DubboHealthService.class,cluster = "broadcast2")
+    private DubboHealthService dubboHealthService;
+    
+     @GetMapping("/health")
+         public String broadCast(){
+             try{
+                 dubboHealthService.health();
+             }catch (Exception e){
+                 Map<String, String> m = RpcContext.getServerContext().getAttachments();
+                 return m.toString()+"|"+"fail";
+             }
+             Map<String, String> m = RpcContext.getServerContext().getAttachments();
+             return m.toString()+"|"+"success";
+         }
+}
+```
+
+- provider demo
+
+```java
+@Service
+public class DubboHealthServiceImpl implements DubboHealthService {
+
+    @Override
+    public String health() {
+//        int i = 1/0;
+        return "i am provider2";
+    }
+}
+```
+
+- 执行结果
+
+所有provider全部成功:
+
+```
+>curl http://localhost:8081/health
+>{broadcast.results=[{"ip":"10.220.47.253","port":20880,"data":"i am provider1"},{"ip":"10.220.47.253","port":20881,"data":"i am provider2"}]}|success%  
+```
+
+令其中一个provider执行除以零:
+
+```
+>curl http://localhost:8081/health
+>{broadcast.results=[{"ip":"10.220.47.253","port":20880,"data":"i am provider1"},{"ip":"10.220.47.253","port":20881,"exceptionMsg":"/ by zero"}]}|success%     
+```
\ No newline at end of file
diff --git a/content/zh/docs/v2.7/user/examples/invoke-with-specified-ip.md b/content/zh/docs/v2.7/user/examples/invoke-with-specified-ip.md
new file mode 100644
index 0000000..18d2af4
--- /dev/null
+++ b/content/zh/docs/v2.7/user/examples/invoke-with-specified-ip.md
@@ -0,0 +1,78 @@
+---
+type: docs
+title: "指定Ip Port调用Provider"
+linkTitle: "指定IP"
+weight: 15
+description: "对于Provider集群中注册的多个实例,指定Ip:Port进行调用"
+---
+
+当多个Provider注册到注册中心时,可以通过在RpcContext中动态的指定其中一个实例的Ip,Port进行Dubbo调用。
+
+{{% alert title="提示" color="primary" %}}
+支持版本:`2.7.12` 之后
+{{% /alert %}}
+
+## 用法示例
+
+- provider demo
+
+假定提供2个provider注册于注册中心,分别为10.220.47.253:20880;10.220.47.253:20881;
+
+```java
+// 10.220.47.253:20880
+@Service(interfaceClass = TestService.class)
+public class TestServiceImpl implements TestService {
+    @Override
+    public String sayHello(String name) {
+        return "Hello "+name+" i am provider1";
+    }
+}
+
+// 10.220.47.253:20881
+@Service(interfaceClass = TestService.class)
+public class TestServiceImpl implements TestService {
+    @Override
+    public String sayHello(String name) {
+        return "Hello "+name+" i am provider2";
+    }
+}
+```
+
+- consumer demo
+
+@DubboReference引入provider,其中设定parameters = {"router","address"},指定address路由方式。
+
+对于要调用的实例,指定Ip,Port构造Address对象,并设置RpcContext键为"address",value为该对象。
+
+```java
+// 需要依赖的class
+import org.apache.dubbo.rpc.RpcContext;
+import org.apache.dubbo.rpc.cluster.router.address.Address;
+    
+@RestController
+public class TestServiceConsumer {
+    @DubboReference(interfaceClass = TestService.class,group = "dev",parameters = {"router","address"})
+    private TestService testService;
+
+   @GetMapping("/invokeByIpPortSpecified")
+       public String invokeByIp(){
+           try {
+               // 根据provider的ip,port创建Address实例
+               Address address = new Address("10.220.47.253", 20880);
+               RpcContext.getContext().setObjectAttachment("address", address);
+               return testService.sayHello("Tom");
+           }catch (Throwable ex){
+               return ex.getMessage();
+           }
+       }
+}
+```
+
+- 执行结果
+
+可以看到,多次执行,始终返回"Hello Tom i am provider1",即始终路由到20880端口所在实例。
+
+```
+>curl http://localhost:8081/invokeByIpPortSpecified
+>Hello Tom i am provider1             
+```
\ No newline at end of file
diff --git a/content/zh/docs/v2.7/user/examples/provider-timeout-release.md b/content/zh/docs/v2.7/user/examples/provider-timeout-release.md
new file mode 100644
index 0000000..6dae045
--- /dev/null
+++ b/content/zh/docs/v2.7/user/examples/provider-timeout-release.md
@@ -0,0 +1,147 @@
+---
+type: docs
+title: "provider超时打断"
+linkTitle: "provider超时打断"
+weight: 15
+description: "Dubbo provider执行超时释放执行线程"
+---
+
+支持provider根据超时时间进行业务打断
+
+适用场景:对于一个provider,如果某个操作执行超时,则打断(释放)该执行线程,而不是仅仅打印超时日志。
+
+{{% alert title="提示" color="primary" %}}
+支持版本:`2.7.12` 之后
+{{% /alert %}}
+
+## 核心处理逻辑
+
+```java
+public class AllChannelHandler2 extends AllChannelHandler {
+
+    public static final Timer TIME_OUT_TIMER = new HashedWheelTimer(
+            new NamedThreadFactory("dubbo-server-future-timeout", true),
+            30,
+            TimeUnit.MILLISECONDS);
+
+    public AllChannelHandler2(ChannelHandler handler, URL url) {
+        super(handler, url);
+    }
+
+
+    @Override
+    public void received(Channel channel, Object message) throws RemotingException {
+        ExecutorService executor = getPreferredExecutorService(message);
+        try {
+            Future<?> future = executor.submit(new ChannelEventRunnable(channel, handler, ChannelState.RECEIVED, message));
+            long timeout = this.url.getParameter("timeout", 1000) + 90;
+            TIME_OUT_TIMER.newTimeout(t -> {
+                if (!future.isDone() && (!future.isCancelled())) {
+                    try {
+                        future.cancel(true);
+                    } catch (Throwable ex) {
+                        //ignore
+                    }
+                }
+            }, timeout, TimeUnit.MILLISECONDS);
+
+        } catch (Throwable t) {
+            if (message instanceof Request && t instanceof RejectedExecutionException) {
+                sendFeedback(channel, (Request) message, t);
+                return;
+            }
+            throw new ExecutionException(message, channel, getClass() + " error when process received event .", t);
+        }
+    }
+
+}
+```
+
+## 使用示例
+
+- 设置Dubbo ProtocolConfig 线程分发策略为"all2"。
+
+```java
+	/**
+	 * 配置协议
+	 */
+	@Bean
+	public ProtocolConfig protocolConfig() {
+		ProtocolConfig protocolConfig = new ProtocolConfig();
+		protocolConfig.setName("dubbo");
+		protocolConfig.setPort(-1);
+		protocolConfig.setTransporter("netty4");
+		protocolConfig.setThreadpool("fixed");
+        // 设置线程分发策略
+        protocolConfig.setDispatcher("all2");
+        protocolConfig.setThreads(200);
+		return protocolConfig;
+	}
+```
+
+- provider demo
+
+执行超时,直接对业务线程进行打断。即如果provider不能及时返回给counsumer执行结果,则对执行线程进行打断。
+
+```java
+// 设置provider执行超时时间为1000ms
+@Service(interfaceClass = TestService.class,timeout = 1000)
+public class TestServiceImpl implements TestService {
+    @Override
+    public Integer sum(int a, int b) {
+        CountDownLatch latch = new CountDownLatch(2);
+        AtomicInteger i = new AtomicInteger();
+
+        new Thread(()->{
+            i.incrementAndGet();
+            latch.countDown();
+        }).start();
+
+        new Thread(()->{
+            try {
+                TimeUnit.MILLISECONDS.sleep(2000); 
+            }catch (InterruptedException e){
+                e.printStackTrace();
+            }
+            i.incrementAndGet();
+            latch.countDown();
+        }).start();
+
+        try {
+            latch.await();
+            return i.get();
+        }catch (InterruptedException e){
+            // 业务执行超时,并且被打断,走入此逻辑
+            throw new RuntimeException("call sum timeout");
+        }
+    }
+}
+```
+
+即对于上述provider demo,执行最后一个try catch时,如果业务线程被超时释放,则捕获InterruptedException异常进入catch块,返回"call sum timeout"。
+
+- consumer demo
+
+```java
+    // 设置consumer超时时间大于服务端执行时间2000
+    @Reference(check = false,interfaceClass = TestService.class,timeout = 3000)
+    private TestService testService;
+
+    @GetMapping("/sum")
+    public String consumeSum(){
+        Integer ret = 0;
+        try{
+             ret = testService.sum(1,1);
+        }catch (Exception e){
+           return e.getMessage();
+        }
+        return String.valueOf(ret);
+    }
+```
+
+- 执行结果
+
+```
+curl http://localhost:8081/sum
+>call sum timeout 
+```
\ No newline at end of file