我正在尝试使用Java编写长期运行的订户服务。我已经设置了侦听器来侦听订阅服务器服务内的任何故障。我试图使这种容错能力,但我不太了解一些事情,以下是我的疑问/问题。
如下面的代码所示,initializeSubscriber充当状态变量,该状态变量将确定订阅服务器服务是否应重新启动。在while循环内部,将连续监视此变量以确定是否需要重新启动。
我的问题是 1.如何在Subscriber.Listener的failed方法内引发异常,并将其捕获到主while循环中。我试图在失败的方法中抛出一个新的Exception(),然后将其捕获到catch块中,但是,我无法编译代码,因为它是一个已检查的异常。 2.如此处所示,我使用Java Executor线程运行监听器。如何处理侦听器失败?我可以在如下所示的常规Exception catch块下捕获侦听器故障吗?
try {
boolean initializeSubscriber = true;
while (true) {
try {
if (initializeSubscriber) {
createSingleThreadedSubscriber();
addErrorListenerToSubscriber();
subscriber.startAsync().awaitRunning();
initializeSubscriber = false;
}
// Checks the status of subscriber service every minute
Thread.sleep(60000);
} catch (Exception ex) {
LOGGER.error("Could not start the Subscriber service", ex);
cleanupSubscriber();
initializeSubscriber = true;
}
}
} catch (RuntimeException e) {
} finally {
shutdown();
}
private void addErrorListenerToSubscriber() {
subscriber.addListener(
new Subscriber.Listener() {
@Override
public void failed(Subscriber.State from, Throwable failure) throws RuntimeException {
LOGGER.info("Subscriber reached a failed state due to " + failure.getMessage()
+ ",Restarting Subscriber service");
initializeSubscriber = true;
}
},
Executors.newSingleThreadExecutor());
}
private void cleanupSubscriber() {
try {
if (subscriber != null) {
subscriber.stopAsync().awaitTerminated();
}
if (!subscriptionListener.isShutdown()) {
subscriptionListener.shutdown();
}
} catch (Exception ex) {
LOGGER.error("Error in cleaning up Subscriber thread " + ex);
}
}
答案 0 :(得分:1)
如果您只想在失败时重新创建订阅者,则不必向订阅者添加侦听器。您可以改为在awaitTerminated
上捕获异常:
try {
boolean initializeSubscriber = true;
while (initializeSubscriber) {
try {
createSingleThreadedSubscriber();
subscriber.startAsync().awaitRunning();
initializeSubscriber = false;
subscriber.awaitTerminated();
} catch (Exception ex) {
LOGGER.error("Error in the Subscriber service", ex);
cleanupSubscriber();
initializeSubscriber = true;
}
}
} catch (RuntimeException e) {
} finally {
shutdown();
}
如果订户由于调用stopAsync
而成功关闭,则awaitTerminated
将不会引发异常。如果存在某种异常,则awaitTerminated
将抛出IllegalStateException
,因为状态将是FAILED
而不是TERMINATED
。
请注意,瞬时错误由库本身处理。例如,如果服务器由于网络故障而暂时不可用,则库将无缝地重新连接并继续传递消息。导致订户状态改变的故障很可能是永久性故障,例如权限问题(运行订户的帐户无权订阅该订阅)或资源问题(例如该订阅已被删除)。在这些永久性失败的情况下,重新创建用户很可能会导致相同的错误,除非人们采取手动步骤进行干预并解决问题。