考虑其中一个verticals抛出未捕获异常的场景。
接下来会发生什么?如果从系统中删除垂直状态,是否有类似于erlang主管的机制来重新启动垂直状态?
关于这方面的文件不是很清楚。
根据评论更新:我最感兴趣的是从接收消息的处理程序(通过总线)抛出异常的情况
问候
我已经回答了我自己的部分问题(在测试程序的帮助下)
当在事件处理程序中抛出异常时,vert.x会捕获该异常并将其吞下(忽略)。事件处理程序将处理下一条消息。
更新:应用程序可以注册异常处理程序,并将所有未捕获的Throwable传递到此处理程序。在那里你可以执行额外的一般处理
Update2:使用Vertx.exceptionHandler
注册处理程序
Vert.x是关于相同风格的异步编程,主要由回调处理程序突出显示。
要处理部署失败的情况,您必须首先采用编程方式,即您必须通过部署vertical以编程方式部署您的vertical,提供一个将用部署结果填充的完成处理程序,下面是一个使用Java的示例(由于您没有选择特定的语言,我将尽我所能),其中:
MainVerticle
:是您的垂直部署(主要用于部署其他垂直部署)some.package.MyVerticle
:是您真正的vertical,请注意,我在这里使用了id,而不是一个实例
public class MainVerticle extends AbstractVerticle {
public void start() {
vertx.deployVerticle("some.package.MyVerticle", res -> {
if (res.succeeded()) {
// Do whatever if deployment succeeded
} else {
// Handle deployment failure here...
}
});
}
}
现在,当谈到"消息传递失败"时,更难强调特定的情况,因为它可能发生在许多地方,并代表消息传递的两端。
如果你想在发送消息时注册一个失败案例处理程序,你可以实例化一个代表它可以写入的流的MessageProducer<T>
,然后在上面注册一个异常处理程序:
EventBus eb = vertx.eventBus();
MessageProducer<String> sender = eb.sender("someAddress");
sender.exceptionHandler(e -> {
System.out.println("An error occured" + e.getCause());
});
sender.write("Hello...");
另一方面,在读取接收到的消息时,您可以以几乎相同的方式处理失败情况,但这次使用MessageConsumer<T>
:
EventBus eb = vertx.eventBus();
MessageConsumer<String> receiver = eb.consumer("someAddress");
receiver.exceptionHandler(e -> {
System.out.println("An error occured while readeing data" + e.getCause());
}).handler(msg -> {
System.out.println("A message has been received: " + msg.body());
});
要在前面的答案中添加一位,如果您想对所有未捕获的异常做出反应,请在vertx
对象上注册处理程序,如下所示:
vertx.exceptionHandler(new Handler<Throwable>() {
@Override
public void handle(Throwable event) {
// do what you meant to do on uncaught exception, e.g.:
System.err.println("Error");
someLogger.error(event + " throws exception: " + event.getStackTrace());
}
});
我遇到了类似的情况。当在Verticle中处理消息的过程中发生异常时,我只想用异常进行回复。
这个想法是把异常一直冒出来,一直追溯到应用程序的入口点,在那里可以决定如何处理故障,同时捕获整个堆栈。
为了完成它,我写了这个函数:
protected ReplyException buildReplyException(Throwable cause, String message)
{
ReplyException ex = new ReplyException(ReplyFailure.RECIPIENT_FAILURE, -1, message);
ex.initCause(cause);
return ex;
}
然后我用它来构建处理程序,或回复处理程序,如下所示:
reply -> {
if (reply.succeeded()) {
message.reply(true);
} else {
message.reply(buildReplyException(reply.cause(), ""));
}
});
这样,发送原始消息的人将得到一个失败的响应,其中包含一个原因,即一个填充了完整堆栈跟踪的异常
这种方法对我在处理消息时处理错误非常有效。