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

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

commit 0c40dce649cb6c53ba94925308505669b28c7a7f
Author: Huxing Zhang <[email protected]>
AuthorDate: Wed Dec 12 11:40:02 2018 +0800

    Add dubbo cluster error handling blog.
---
 blog/zh-cn/dubbo-cluster-error-handling.md | 270 +++++++++++++++++++++++++++++
 site_config/blog.js                        |  19 +-
 2 files changed, 283 insertions(+), 6 deletions(-)

diff --git a/blog/zh-cn/dubbo-cluster-error-handling.md 
b/blog/zh-cn/dubbo-cluster-error-handling.md
new file mode 100644
index 0000000..3a23c8c
--- /dev/null
+++ b/blog/zh-cn/dubbo-cluster-error-handling.md
@@ -0,0 +1,270 @@
+---
+title: Dubbo集群容错
+keywords: Dubbo, RPC, cluster, Error-handling
+description: 
在分布式系统中,集群某个某些节点出现问题是大概率事件,因此在设计分布式RPC框架的过程中,必须要把失败作为设计的一等公民来对待。一次调用失败之后,应该如何选择对失败的选择策略,这是一个见仁见智的问题,每种策略可能都有自己独特的应用场景。因此,作为框架来说,应当针对不同场景提供多种策略,供用户进行选择。本文介绍了Dubbo框架提供的多种错误处理策略,并通过实例说明如何进行配置。
+---
+
+
+### Design For failure
+
+在分布式系统中,集群某个某些节点出现问题是大概率事件,因此在设计分布式RPC框架的过程中,必须要把失败作为设计的一等公民来对待。一次调用失败之后,应该如何选择对失败的选择策略,这是一个见仁见智的问题,每种策略可能都有自己独特的应用场景。因此,作为框架来说,应当针对不同场景提供多种策略,供用户进行选择。
+
+在Dubbo设计中,通过Cluster这个接口的抽象,把一组可供调用的Provider信息组合成为一个统一的`Invoker`供调用方进行调用。经过路由规则过滤,负载均衡选址后,选中一个具体地址进行调用,如果调用失败,则会按照集群配置的容错策略进行容错处理。
+
+Dubbo默认内置了若干容错策略,如果不能满足用户需求,则可以通过自定义容错策略进行配置。
+
+### 内置容错策略
+
+Dubbo主要内置了如下几种策略:
+
+* Failover(失败自动切换)
+* Failsafe(失败安全)
+* Failfast(快速失败)
+* Failback(失败自动恢复)
+* Forking(并行调用)
+* Broadcast(广播调用)
+
+这些名称比较相似,概念也比较容易混淆,下面逐一进行解释。
+
+#### Failover(失败自动切换)
+
+`Failover`是高可用系统中的一个常用概念,服务器通常拥有主备两套机器配置,如果主服务器出现故障,则自动切换到备服务器中,从而保证了整体的高可用性。
+
+Dubbo也借鉴了这个思想,并且把它作为Dubbo`默认的容错策略`。当调用出现失败的时候,根据配置的重试次数,会自动从其他可用地址中重新选择一个可用的地址进行调用,直到调用成功,或者是达到重试的上限位置。
+
+Dubbo里默认配置的重试次数是2,也就是说,算上第一次调用,最多会调用3次。
+
+
+
+其配置方法,容错策略既可以在服务提供方配置,也可以服务调用方进行配置。而重试次数的配置则更为灵活,既可以在服务级别进行配置,也可以在方法级别进行配置。具体优先顺序为:
+
+```
+服务调用方方法级配置 > 服务调用方服务级配置 > 服务提供方方法级配置 > 服务提供方服务级配置
+```
+
+以XML方式为例,具体配置方法如下:
+
+服务提供方,服务级配置
+
+```xml
+<dubbo:service interface="org.apache.dubbo.demo.DemoService" ref="demoService" 
cluster="failover" retries="2" />
+```
+
+服务提供方,方法级配置
+
+```xml
+<dubbo:service interface="org.apache.dubbo.demo.DemoService" 
ref="demoService"cluster="failover">
+     <dubbo:method name="sayHello" retries="2" />
+ </dubbo:reference>
+```
+
+服务调用方,服务级配置
+
+```xml
+<dubbo:reference id="demoService" 
interface="org.apache.dubbo.demo.DemoService" cluster="failover" retries="1"/>
+```
+
+服务调用方,方法级配置:
+
+```xml
+ <dubbo:reference id="demoService" 
interface="org.apache.dubbo.demo.DemoService" cluster="failover">
+     <dubbo:method name="sayHello" retries="3" />
+ </dubbo:reference>
+```
+
+Failover可以自动对失败进行重试,对调用者屏蔽了失败的细节,但是Failover策略也会带来一些副作用:
+
+* 重试会额外增加一下开销,例如增加资源的使用,在高负载系统下,额外的重试可能让系统雪上加霜。
+* 重试会增加调用的响应时间。
+* 
某些情况下,重试甚至会造成资源的浪费。考虑一个调用场景,A->B->C,如果A处设置了超时100ms,再B->C的第一次调用完成时已经超过了100ms,但很不幸B->C失败,这时候会进行重试,但其实这时候重试已经没有意义,因此在A看来这次调用已经超时,A可能已经开始执行其他逻辑。
+
+#### Failsafe(失败安全)
+
+失败安全策略的核心是即使失败了也不会影响整个调用流程。通常情况下用于旁路系统或流程中,它的失败不影响核心业务的正确性。在实现上,当出现调用失败时,会忽略此错误,并记录一条日志,同时返回一个空结果,在上游看来调用是成功的。
+
+应用场景,可以用于写入审计日志等操作。
+
+具体配置方法:
+
+服务提供方,服务级配置
+
+```xml
+<dubbo:service interface="org.apache.dubbo.demo.DemoService" ref="demoService" 
cluster="failsafe" />
+```
+
+服务调用方,服务级配置
+
+```xml
+<dubbo:reference id="demoService" 
interface="org.apache.dubbo.demo.DemoService" cluster="failsafe"/>
+```
+
+其中服务调用方配置优先于服务提供方配置。
+
+#### Failfast(快速失败)
+
+某些业务场景中,某些操作可能是非幂等的,如果重复发起调用,可能会导致出现脏数据等。例如调用某个服务,其中包含一个数据库的写操作,如果写操作完成,但是在发送结果给调用方的过程中出错了,那么在调用发看来这次调用失败了,但其实数据写入已经完成。这种情况下,重试可能并不是一个好策略,这时候就需要使用到`Failfast`策略,调用失败立即报错。让调用方来决定下一步的操作并保证业务的幂等性。
+
+具体配置方法:
+
+服务提供方,服务级配置
+
+```xml
+<dubbo:service interface="org.apache.dubbo.demo.DemoService" ref="demoService" 
cluster="failfast" />
+```
+
+服务调用方,服务级配置
+
+```xml
+<dubbo:reference id="demoService" 
interface="org.apache.dubbo.demo.DemoService" cluster="failfast"/>
+```
+
+其中服务调用方配置优先于服务提供方配置。
+
+#### Failback(失败自动恢复)
+
+`Failback`通常和`Failover`两个概念联系在一起。在高可用系统中,当主机发生故障,通过`Failover`进行主备切换后,待故障恢复后,系统应该具备自动恢复原始配置的能力。
+
+Dubbo中的`Failback`策略中,如果调用失败,则此次失败相当于`Failsafe`,将返回一个空结果。而与`Failsafe`不同的是,Failback策略会将这次调用加入内存中的失败列表中,对于这个列表中的失败调用,会在另一个线程中进行异步重试,重试如果再发生失败,则会忽略,即使重试调用成功,原来的调用方也感知不到了。因此它通常适合于,对于实时性要求不高,且不需要返回值的一些异步操作。
+
+具体配置方法:
+
+服务提供方,服务级配置
+
+```xml
+<dubbo:service interface="org.apache.dubbo.demo.DemoService" ref="demoService" 
cluster="failsafe" />
+```
+
+服务调用方,服务级配置
+
+```xml
+<dubbo:reference id="demoService" 
interface="org.apache.dubbo.demo.DemoService" cluster="failsafe"/>
+```
+
+其中服务调用方配置优先于服务提供方配置。
+
+按照目前的实现,Failback策略还有一些局限,例如内存中的失败调用列表没有上限,可能导致堆积,异步重试的执行间隔无法调整,默认是5秒。
+
+#### Forking(并行调用)
+
+上述几种策略中,主要都是针对调用失败发生后如何进行弥补的角度去考虑的,而`Forking`策略则跟上述几种策略不同,是一种典型的用成本换时间的思路。即第一次调用的时候就同时发起多个调用,只要其中一个调用成功,就认为成功。在资源充足,且对于失败的容忍度较低的场景下,可以采用此策略。
+
+具体配置方法:
+
+服务提供方,服务级配置
+
+```xml
+<dubbo:service interface="org.apache.dubbo.demo.DemoService" ref="demoService" 
cluster="forking" />
+```
+
+服务调用方,服务级配置
+
+```xml
+<dubbo:reference id="demoService" 
interface="org.apache.dubbo.demo.DemoService" cluster="forking"/>
+```
+
+其中服务调用方配置优先于服务提供方配置。
+
+#### Broadcast(广播调用)
+
+在某些场景下,可能需要对服务的所有提供者进行操作,此时可以使用广播调用策略。此策略会逐个调用所有提供者,只要任意有一个提供者出错,则认为此次调用出错。通常用于通知所有提供者更新缓存或日志等本地资源信息。
+
+具体配置方法:
+
+服务提供方,服务级配置
+
+```xml
+<dubbo:service interface="org.apache.dubbo.demo.DemoService" ref="demoService" 
cluster="broadcast" />
+```
+
+服务调用方,服务级配置
+
+```xml
+<dubbo:reference id="demoService" 
interface="org.apache.dubbo.demo.DemoService" cluster="broadcast"/>
+```
+
+其中服务调用方配置优先于服务提供方配置。
+
+#### 各种策略对比
+
+下表对各种策略做一个简单对比,
+
+| 策略名称  | 优点                             | 缺点                                  
 | 主要应用场景                                         |
+| --------- | -------------------------------- | 
-------------------------------------- | 
---------------------------------------------------- |
+| Failover  | 对调用者屏蔽调用失败的信息       | 增加RT,额外资源开销,资源浪费         | 对调用rt不敏感的场景     
                            |
+| Failfast  | 业务快速感知失败状态进行自主决策 | 产生较多报错的信息                     | 
非幂等性操作,需要快速感知失败的场景                 |
+| Failsafe  | 即使失败了也不会影响核心流程     | 对于失败的信息不敏感,需要额外的监控   | 旁路系统,失败不影响核心流程正确性的场景 
            |
+| Failback  | 失败自动异步重试                 | 重试任务可能堆积                       | 
对于实时性要求不高,且不需要返回值的一些异步操作     |
+| Forking   | 并行发起多个调用,降低失败概率   | 消耗额外的机器资源,需要确保操作幂等性 | 
资源充足,且对于失败的容忍度较低,实时性要求高的场景 |
+| Broadcast | 支持对所有的服务提供者进行操作   | 资源消耗很大                           | 
通知所有提供者更新缓存或日志等本地资源信息           |
+
+### 自定义容错策略
+
+如果上述内置的容错策略无法满足你的需求,还可以通过扩展的方式来实现自定义容错策略。
+
+#### 扩展接口
+
+`com.alibaba.dubbo.rpc.cluster.Cluster`
+
+#### 扩展配置
+
+```xml
+<dubbo:service cluster="xxx" />
+```
+
+#### 扩展示例
+
+下面通过一个例子来展示如何使用自定义的容错策略。
+Maven 项目结构:
+
+```
+src
+ |-main
+    |-java
+        |-com
+            |-xxx
+                |-XxxCluster.java (实现Cluster接口)
+    |-resources
+        |-META-INF
+            |-dubbo
+                |-org.apache.dubbo.rpc.cluster.Cluster 
(纯文本文件,内容为:xxx=com.xxx.XxxCluster)
+```
+
+XxxCluster.java:
+
+```java
+package com.xxx;
+ 
+import org.apache.dubbo.rpc.cluster.Cluster;
+import org.apache.dubbo.rpc.cluster.support.AbstractClusterInvoker;
+import org.apache.dubbo.rpc.cluster.Directory;
+import org.apache.dubbo.rpc.cluster.LoadBalance;
+import org.apache.dubbo.rpc.Invoker;
+import org.apache.dubbo.rpc.Invocation;
+import org.apache.dubbo.rpc.Result;
+import org.apache.dubbo.rpc.RpcException;
+
+import java.util.List;
+
+public class XxxCluster implements Cluster {
+
+    @Override
+    public <T> Invoker<T> join(Directory<T> directory) throws RpcException {
+        return new AbstractClusterInvoker<T>() {
+            @Override
+            protected Result doInvoke(Invocation invocation, List<Invoker<T>> 
invokers, LoadBalance loadbalance) throws RpcException {
+                // your custimzed fault tolarence strategy goes here
+            }
+        };
+    }
+
+}
+```
+
+`META-INF/dubbo/com.alibaba.dubbo.rpc.cluster.Cluster`文件的内容为
+
+```
+xxx=com.xxx.XxxCluster
+```
+
+
+
diff --git a/site_config/blog.js b/site_config/blog.js
index 0faf18d..c2b544c 100644
--- a/site_config/blog.js
+++ b/site_config/blog.js
@@ -157,13 +157,20 @@ export default {
     postsTitle: '所有文章',
     list: [
         {
-            title: '在 Dubbo 中使用 Zipkin',
-            author:'@beiwei30',
-            dateStr: 'Oct 12th, 2018',
-            desc: '本文介绍如何使用 Zipkin 在 Dubbo 中进行全链路追踪',
-            link: '/zh-cn/blog/use-zipkin-in-dubbo.html',
+            title: 'Dubbo集群容错',
+            author:'@ralf0131',
+            dateStr: 'Dec 11th, 2018',
+            desc: '本文介绍了Dubbo框架提供的多种错误处理策略,并通过实例说明如何进行配置。',
+            link: '/zh-cn/blog/dubbo-cluster-error-handling.html',
         },
-               {
+        {
+          title: '在 Dubbo 中使用 Zipkin',
+          author:'@beiwei30',
+          dateStr: 'Oct 12th, 2018',
+          desc: '本文介绍如何使用 Zipkin 在 Dubbo 中进行全链路追踪',
+          link: '/zh-cn/blog/use-zipkin-in-dubbo.html',
+        },
+                   {
             title: 'Dubbo在Service Mesh下的思考和方案',
             author: '@JeffLv',
             dateStr: 'Sep 25th, 2018',

Reply via email to