dubbo 叢集容錯模式原始碼學習 -- FaibackCluster
阿新 • • 發佈:2018-10-31
#FailbackCluster
當呼叫失敗後,將呼叫失敗的請求放在failed 集合。這個集合是併發訪問,所有的請求失敗的都會放在這個結合中。之後,通過scheduledExecutorService 去定時從新執行這些失敗的請求,只要failed 集合有元素,就會執行。
public class FailbackCluster { private volatile ScheduledFuture<?> retryFuture; // retryFuture 是隻讀的,所以用volatile. private final ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(2); private final List<Node> failed = new CopyOnWriteArrayList<>(); void failbackCluster() { Node node = selectOneNode(); try { String resp = node.doSomething(); }catch (Throwable e) { System.out.println("Node perform failed. will retry in background." + e.getMessage()); addFailed(node); } } private Node selectOneNode() { // 使用負載均衡選擇出一個節點相應 return new Node(1); } private void addFailed(Node node) { if (retryFuture == null) { synchronized (this) { if (retryFuture == null) { // 二次判斷 retry 是否為空, 防止 update on read error. scheduledExecutorService.scheduleAtFixedRate(new Runnable() { // 定時重試任務 @Override public void run() { try { retryFailed(); }catch (Throwable t) { System.out.print("retry failed."); } } }, 5000, 5000, TimeUnit.MILLISECONDS); } } } } private void retryFailed() { if (failed.size() == 0) { return; } for (Node n : failed) { try { n.doSomething(); failed.remove(n); }catch (Throwable t) { System.out.println("Failed to retry node.doSomething" + t.getMessage()); } } } class Node { private int id; Node(int id) { this.id = id; } String doSomething() { return "Node " + id + "第一個完成響應"; }; }
}