我有一个来自Java进程的长期运行的Tibrv连接。
今天我惊讶地看到这个日志条目(打印在stderr上):
2018-02-01 :15:44 RV: TIB/交会错误未由进程处理:{ADV_CLASS=“警告”ADV_SOURCE=系统“ADV_NAME=”RVD.DISCONNECTED}
,捕获错误并重新连接的正确方法是什么?
我的过程需要容错。(我认为另一边的服务器是重新启动的。)
示例连接代码:
Tibrv.open(Tibrv.IMPL_NATIVE);
final TibrvRvdTransport tibrvRvdTransport =
new TibrvRvdTransport(tibrvService, nullableTibrvNetwork, tibrvDaemon);
根据官方Tibrv文档 (p282),有一个名为_RV.WARN.SYSTEM.RVD.DISCONNECTED
的系统咨询消息。但是,我不知道侦听此消息的正确方法,也不知道收到消息后会尝试恢复。
发布于 2018-02-03 11:30:12
这花了我一段时间才弄明白,所以我正在回答我自己的问题。
简而言之,Tibrv库使用一个私有线程来自动监视断开和重新连接。“用户空间”监视的目的是为这些事件提供优雅的处理(容错等)。
技术解决方案是侦听两条特殊的RVD消息:
_RV.WARN.SYSTEM.RVD.DISCONNECTED
_RV.INFO.SYSTEM.RVD.CONNECTED
可以使用带有主题通配符的单个TibrvListener
。
final String subjectWildcard = "_RV.*.SYSTEM.RVD.*";
final Object nullableClosure = null;
new TibrvListener(
Tibrv.defaultQueue(),
// @NotThreadSafe
new TibrvMsgCallback() {
@Override
public void onMsg(TibrvListener tibrvListener, TibrvMsg tibrvMsg) {
final String sendSubject = tibrvMsg.getSendSubject();
if ("_RV.WARN.SYSTEM.RVD.DISCONNECTED".equals(sendSubject)) {
// TODO
}
else if ("_RV.INFO.SYSTEM.RVD.CONNECTED".equals(sendSubject)) {
// TODO
}
}
},
tibrvRvdTransport, subjectWildcard, nullableClosure);
// Next: Setup a daemon thread to dispatch incoming Tibrv messages.
{
final Thread thread = new Thread(() -> {
final TibrvQueue tibrvQueue = Tibrv.defaultQueue();
while (true) {
try {
tibrvQueue.dispatch();
}
catch (Exception e) {
throw new RuntimeException(e);
}
}
});
thread.setDaemon(true);
thread.start();
}
如何测试断开和重新连接事件:
$ tibrvlisten -service 8800 -daemon tcp:8800 TEST.MESSAGE
$ tibrvsend -service 8800 -daemon ${tibrvlisten.hostname}:8800 TEST.MESSAGE hello
tibrvlisten
应该记录:subject=TEST.MESSAGE, message={DATA="hello"}
new TibrvRvdTransport("8800", null, "${tibrvlisten.hostname}:8800")
tibrvlisten
和Ctrl+C,然后关闭后台进程rvd
,例如$ ps -efjww | egrep 'rvd +-listen' | awk '{print $2}' | xargs kill
final TibrvMsg m = new TibrvMsg(); m.setSendSubject("TEST.MESSAGE"); m.add("DATA", "hello"); tibrvRvdTransport.send(m);
send()
将与TibrvException
一起失败: error=21,message=“无法连接到守护进程”int TibrvException.error
值可以在这里找到:TibrvStatus
,例如,DAEMON_NOT_CONNECTED = 21
tibrvlisten
并等待Java后台线程自动重新连接.https://stackoverflow.com/questions/48563653
复制相似问题