[英]How to catch Tibrv RVD.DISCONNECTED message in Java?
我從Java進程開始的Tibrv連接運行時間長。
我很驚訝今天看到此日志條目(打印在stderr上):
2018-02-01 08:15:44 RV:進程未處理TIB /集合錯誤:{ADV_CLASS =“ WARN” ADV_SOURCE =“ SYSTEM” ADV_NAME =“ RVD.DISCONNECTED”}
捕獲此錯誤並重新連接的正確方法是什么?
我的過程需要容錯。 (我認為另一端的服務器已重新啟動。)
連接代碼示例:
Tibrv.open(Tibrv.IMPL_NATIVE);
final TibrvRvdTransport tibrvRvdTransport =
new TibrvRvdTransport(tibrvService, nullableTibrvNetwork, tibrvDaemon);
根據官方Tibrv文檔 (p282),有一個名為_RV.WARN.SYSTEM.RVD.DISCONNECTED
的系統咨詢消息 。 但是,我不知道收聽此消息的正確方法,也不知道收到后即嘗試恢復。
這花了我一段時間才能弄清楚,所以我在回答自己的問題。
簡而言之,Tibrv Java庫使用私有線程來自動監視斷開連接和重新連接。 “用戶空間”監視的目的是優雅地處理這些事件(容錯等)。
技術解決方案是偵聽兩種特殊的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();
}
感謝TibrvListener
和TibrvQueue.dispatch()
如何測試斷開和重新連接事件:
$ 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
,然后終止后台進程rvd
,例如, $ ps -efjww | egrep 'rvd +-listen' | awk '{print $2}' | xargs kill
$ 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后台線程自動重新連接。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.