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