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