GridDB Java实现抛出接收超时错误,求排查与解决方法
GridDB SocketTimeoutException 无限循环问题排查与解决
问题描述
使用Java代码操作Docker容器中的GridDB时,触发SocketTimeoutException运行时错误,程序陷入无限循环,每隔一段时间重复抛出该错误。错误表现为连接GridDB节点超时,无法建立或维持与集群的通信。
相关代码
package org.griddb; import com.toshiba.mwcloud.gs.*; import java.util.Date; import java.util.Properties; public class GridDBTest { static class Person { @RowKey public String name; private int age; } static class HeartRate { @RowKey Date ts; int heartRate; String activity; } public static void main(String[] args) throws GSException { Properties props = new Properties(); props.setProperty("notificationAddress", "239.0.0.1"); props.setProperty("notificationPort", "31999"); props.setProperty("clusterName", "defaultCluster"); props.setProperty("user", "admin"); props.setProperty("password", "admin"); GridStore store = GridStoreFactory.getInstance().getGridStore(props); Collection<String, Person> people = store.putCollection("PEOPLE", Person.class); Query<Person> query = people.query("select * where name = 'John'"); RowSet<Person> rs = query.fetch(false); Person person1 = new Person(); person1.age=50; person1.name="John"; TimeSeries<Person> personTimeSeries = store.putTimeSeries("Admin_"+person1.name, Person.class); personTimeSeries.put(person1); while (rs.hasNext()) { // Update the searched Row Person person2 = rs.next(); System.out.println("Name: "+ person2.name +" Age: "+ person2.age); } store.close(); }
问题原因分析
1. 代码结构问题
- 无重试终止机制:GridDB Java客户端默认会自动重试连接,但未设置超时和重试次数限制,导致无限循环重试,反复抛出超时异常。
- 异常未捕获处理:
main方法直接抛出GSException,未对连接失败场景做捕获和终止逻辑,客户端持续发起无效连接尝试。 - 集合操作时机不当:在连接未稳定的情况下执行
store.putCollection操作,触发客户端重试逻辑,加剧循环报错。
2. GridDB服务器(Docker容器)问题
- 多播通信失效:Docker容器默认可能禁用多播,代码中使用的
239.0.0.1多播地址无法让外部客户端发现容器内的GridDB节点。 - 端口映射不完整:运行GridDB容器时未正确暴露
31999(通知端口)、10001/10002(数据端口),导致客户端无法建立有效连接。 - 集群配置不匹配:容器内GridDB的集群名称、用户密码与代码中的配置不一致,连接验证失败后客户端反复重试。
解决步骤
代码结构修复
- 添加超时与重试限制:在Properties中配置连接超时和最大重试次数,避免无限循环:
props.setProperty("connectTimeout", "30000"); // 连接超时30秒 props.setProperty("maxRetryCount", "3"); // 最大重试3次 - 捕获异常并终止程序:用try-catch-finally包裹核心逻辑,捕获异常后直接退出:
public static void main(String[] args) { GridStore store = null; try { Properties props = new Properties(); // 原有配置项 store = GridStoreFactory.getInstance().getGridStore(props); // 原有业务逻辑 } catch (GSException e) { e.printStackTrace(); System.exit(1); // 捕获异常后终止程序 } finally { if (store != null) { try { store.close(); } catch (GSException e) { e.printStackTrace(); } } } } - 调整操作顺序:确认连接成功后再执行集合创建、查询等业务操作,减少无效重试触发。
Docker GridDB配置修复
- 改用单播模式:将通知地址改为GridDB容器的宿主机IP(或容器IP),替代多播:
同时启动容器时完整映射端口:props.setProperty("notificationAddress", "宿主机IP"); // 例如192.168.1.100docker run -d -p 31999:31999 -p 10001:10001 -p 10002:10002 griddb/griddb - 验证集群配置:进入容器确认集群名称、用户密码与代码一致:
docker exec -it <容器ID> /bin/bash su gsadm gs_stat -u admin/admin - 检查网络与防火墙:确保宿主机防火墙允许
31999、10001、10002端口通信,容器网络模式设置为host或端口映射正确。
内容的提问来源于stack exchange,提问作者NebuCodeNezzar
相关产品推荐
相关产品推荐

