如何在 Java 中重新建立丢失的 KDB 连接
How to re-establish lost KDB connection in Java
在我的 Java 应用程序中,我正在使用
建立 KDB 连接
private void initConnection() throws KException, IOException {
conn = new c(host, port);
conn.tz = TimeZone.getTimeZone(CONNECTION_TIMEZONE);
}
然后我使用conn
在表中异步插入数据成功。
KDB 服务器每周重启一次,当时由于服务器重置连接,我收到异常 java.net.SocketException
。
使用上述异常,我可以再次重新建立丢失的连接,但这不是一个合适的解决方案,因为我丢失了批处理等,而且我不希望在插入时抛出连接异常。
相反,KDB API 中是否有 call-back/listener/Exception 方法,如果连接被服务器关闭/丢失,API 可以预先通知 java 应用程序?
你为什么不做一个
SELECT 1;
在你的连接上。
如果打开它会 运行。
如果它关闭,它应该会因为网络连接失败而抛出错误。
您 运行 仅在您的 kbd 服务器计划重启时进行此测试。
就个人而言,在预定的重启 kbd 数据库的时刻,我会将数据转储到 sqlite 数据库中进行保存,然后当重启框架结束并重新建立连接时转储 sqlite 的内容数据库到kbd数据库。
如果连接丢失,我希望 conn
对象在您尝试攻击 KDB 时抛出 IOException
或其后继对象。
也就是说,你应该抓住 IOException
和
- 调用
initConnection
方法重新建立连接
- 重新执行查询
设置合理的重试阈值也很好。否则,如果 KDb 关闭,代码将继续尝试连接它。
此答案与上面 Anton Dovzhenko 的答案相关(并且可能有所补充),但希望下面的答案也对您有所帮助。
如果我们看一下 kx's documentation for reconnecting to a q process automatically,我们可以从下面的 ReconnectionExample.java
观察到以下代码片段。
//initiate reconnect loop (possibly within a catch block).
while (true) {
try {
System.err.println("Connection failed - retrying..");
//Wait a bit before trying to reconnect
Thread.sleep(5000);
qConnection = qConnFactory.getQConnection();
System.out.println("Connection re-established! Resuming..");
//Exit loop
break;
} catch (IOException | KException e1) {
//resume loop if it fails
continue;
}
…
}
这将是尝试重新连接的一种方式;在一个 catch 块内。但是,要更详细地回答您的问题:
- 要提醒应用程序的其余部分,请在 catch 块中执行此操作。执行此操作的一种方法是调用另一个回调方法来提醒连接现已断开。
- 要重新连接,也请在您的 catch 块中执行此操作。不过,请注意仅在指定的时间间隔内执行此操作。我之所以提到这一点,是因为当 Java 应用程序尝试重新连接时,它将创建一个新的
c
对象。
这应该有助于您的应用程序更有效地处理重新连接,并适当地通知任何其他依赖项。
在我的 Java 应用程序中,我正在使用
建立 KDB 连接private void initConnection() throws KException, IOException {
conn = new c(host, port);
conn.tz = TimeZone.getTimeZone(CONNECTION_TIMEZONE);
}
然后我使用conn
在表中异步插入数据成功。
KDB 服务器每周重启一次,当时由于服务器重置连接,我收到异常 java.net.SocketException
。
使用上述异常,我可以再次重新建立丢失的连接,但这不是一个合适的解决方案,因为我丢失了批处理等,而且我不希望在插入时抛出连接异常。
相反,KDB API 中是否有 call-back/listener/Exception 方法,如果连接被服务器关闭/丢失,API 可以预先通知 java 应用程序?
你为什么不做一个
SELECT 1;
在你的连接上。
如果打开它会 运行。
如果它关闭,它应该会因为网络连接失败而抛出错误。
您 运行 仅在您的 kbd 服务器计划重启时进行此测试。
就个人而言,在预定的重启 kbd 数据库的时刻,我会将数据转储到 sqlite 数据库中进行保存,然后当重启框架结束并重新建立连接时转储 sqlite 的内容数据库到kbd数据库。
如果连接丢失,我希望 conn
对象在您尝试攻击 KDB 时抛出 IOException
或其后继对象。
也就是说,你应该抓住 IOException
和
- 调用
initConnection
方法重新建立连接 - 重新执行查询
设置合理的重试阈值也很好。否则,如果 KDb 关闭,代码将继续尝试连接它。
此答案与上面 Anton Dovzhenko 的答案相关(并且可能有所补充),但希望下面的答案也对您有所帮助。
如果我们看一下 kx's documentation for reconnecting to a q process automatically,我们可以从下面的 ReconnectionExample.java
观察到以下代码片段。
//initiate reconnect loop (possibly within a catch block).
while (true) {
try {
System.err.println("Connection failed - retrying..");
//Wait a bit before trying to reconnect
Thread.sleep(5000);
qConnection = qConnFactory.getQConnection();
System.out.println("Connection re-established! Resuming..");
//Exit loop
break;
} catch (IOException | KException e1) {
//resume loop if it fails
continue;
}
…
}
这将是尝试重新连接的一种方式;在一个 catch 块内。但是,要更详细地回答您的问题:
- 要提醒应用程序的其余部分,请在 catch 块中执行此操作。执行此操作的一种方法是调用另一个回调方法来提醒连接现已断开。
- 要重新连接,也请在您的 catch 块中执行此操作。不过,请注意仅在指定的时间间隔内执行此操作。我之所以提到这一点,是因为当 Java 应用程序尝试重新连接时,它将创建一个新的
c
对象。
这应该有助于您的应用程序更有效地处理重新连接,并适当地通知任何其他依赖项。