重试操作
为什么要有这么个操作?
假如我们捕捉到了网络丢失的异常,如果我们的操作是“幂等”的,我们一般期望在一定时间后,网络恢复的情况下,重新执行这个操作来完成之前的操作。如果
我们的操作不是“幂等”的,我们一般是在捕捉到异常后经过确认来决定是否重新操作。因此重试操作在“网络是不可靠”的前提下变得就很有必要。
这里我们定义一个方法:retryOperation()
这个方法的访问级别是"protected",参数是ZooKeeperOperation对象,
ZookeeperOperation对象的定义如下:
public interface ZooKeeperOperation {
public boolean execute() throws KeeperException, InterruptedException;
}
retryOperation()的返回值是Object,抛出"KeeperException,InterruptedException"
retryOperation()的代码如下:
protected Object retryOperation(ZooKeeperOperation operation)
throws KeeperException, InterruptedException {
KeeperException exception = null;
for (int i = 0; i < retryCount//重试次数; i++) {
try {
return operation.execute();
} catch (KeeperException.SessionExpiredException e) {
LOG.warn("Session expired for: " + zookeeper + " so reconnecting due to: " + e, e);
throw e;
} catch (KeeperException.ConnectionLossException e) {
if (exception == null) {
exception = e;
}
LOG.debug("Attempt " + i + " failed with connection loss so " +
"attempting to reconnect: " + e, e);
retryDelay(i);//根据重试的次数定义重试延迟时间
}
}
throw exception;
}
retryOperation()方法没有捕捉SessionExpiredException异常,因为一般session失效是zooKeeper的节点将进入“closed”态,不能恢复
如图所示: