dubbo 集群容错模式源码学习 -- FaibackCluster

#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 + "第一个完成响应";
    };
}

}

猜你喜欢

转载自blog.csdn.net/ZHANGYONGHAO604/article/details/81635796
今日推荐