1500字范文,内容丰富有趣,写作好帮手!
1500字范文 > 0920-TCP断线重连 reconnect

0920-TCP断线重连 reconnect

时间:2023-12-12 18:16:21

相关推荐

0920-TCP断线重连 reconnect

问题

最近使用AD域LDAP通信碰到一个TCP底层问题,一个链接第一次点击失败,再点击就正常;

过一段时间又会出现这一情况;

跟踪日志发现:The connection is not established

定位问题:连接是有的,但是没有保活(自行百度)

建立连接后,过了很久连接中断,但是客户端没有收到服务端的信息,认为是有效连接,尝试连接时会报错

解决办法

1 客户端和服务端设置保活

理论上,下一个心跳周期前连接断了,还是会有这个问题

//TCP保活 超时时间options.setUseKeepAlive(true);options.setConnectTimeoutMillis(CONNECT_TIMEOUT);options.setResponseTimeoutMillis(RESPONSE_TIMEOUT);connection = new LDAPConnection(sslSocketFactory,options,adIpAddress,adDef.getAdPort(),adminDN,adDef.getAdAdminPassword());connectionPool = new LDAPConnectionPool(connection, adDef.getAdMaxPoolCount());

2 断线重连机制(根本解决)

在发起业务请求前,先发起一个请求检测是否有效,

如果无效会抛出异常,catch异常尝试重连 ,如果超过重试次数抛出异常

//发请求前,随意发起一个状态请求(任何内容,尽可能小),如果抛异常则尝试重连checkAndReconnect(ldapConnection);//发起真正的业务请求modResult = ldapConnection.modify(adUser.getUserDN(), mods);

/*** 检查连接并重试* @param connection LDAP连接*/private static void checkAndReconnect(LDAPConnection connection){Preconditions.checkNotNull(connection, LOG_PREFIX+"空连接,请检查网络");try {connection.getRootDSE();} catch (LDAPException e) {int i;for (i = 0; i < RECONNECT_TIMES; i++) {try {connection.reconnect();log.info(LOG_PREFIX+"重连..{} 成功",i+1);return;} catch (LDAPException e1) {log.info(LOG_PREFIX+"重连..{} 失败{}",i+1,e.getResultString());}}throw Exceptions.newBusinessException(LOG_PREFIX+"重连"+i+"次失败,网络可能已经断开");}}

测试

模拟网络断开

Windows防火墙模拟网络断开

开发机是windows,使用防火墙屏蔽端口,出战规则屏蔽端口,启动规则,模拟连接突然断开

Linux防火墙模拟网络断开

//打开防火墙配置文件vim /etc/sysconfig/iptables//iptables添加屏蔽规则 -A OUTPUT -p tcp --dport 23000 -j DROP//重启iptables使规则生效systemctl restart iptables//telnet模拟防火墙是否生效telnet 192.168.1.17 23000

测试成功(中间开启屏蔽规则,放开后连接成功)

心得体会

不能通过状态检测来确认连接是否正常

比如不能以isConnected()的结果作为是否连接的标准,它只是一个结果

连接本质上是一个对象,所谓的状态只是一个成员变量,可能网络断了,但状态还是之前正常连接的状态

通过尝试连接是否抛异常来判断连接状态及尝试重连

所以简单来说,就是要看方法是否抛异常,如果抛异常,那么它底层的确是去连接了,所以才知道状态

通过防火墙模拟网络连接debug模式可以在需要的时候才打断点,不需要提前打断点

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。