dubbo连接zookeeper注册中心因为断网导致线程无限等待问题
来源:互联网 发布:网上商城java源码 编辑:程序博客网 时间:2024/06/05 17:43
最近维护的系统切换了网络环境,由联通换成了电信网络,因为某些过滤规则导致系统连不上zookeeper服务器(应用系统机器在深圳,网络为电信线路,zookeeper服务器在北京,网络为联通线路),因为我不是运维人员也不懂运维相关的技术,所以排查了很久也不知道原因,最后无奈之下把深圳这边的网络切回了联通,系统恢复正常。
但是因为本次事故体现了一个很严重的问题,即当zookeeper注册中心连不上时dubbo的线程会无限等待,因为系统有一些定时任务会比较频繁地开启新线程连接dubbo,所以导致的结果是tomcat一会儿线程池就满了,其它的不依赖dubbo的功能也被阻塞无法使用。
所以需要解决一个问题,即在断网的情况下要保证应用程序可以运行(有很多功能不依赖外网),一开始我以为dubbo应该有对ZKClient连接相关的超时时间配置,结果找了很久也没发现,后来debug了dubbo的源代码发现根本就没有设置超时时间,ZKClient默认的超时时间是Integer.MAX_VALUE,几乎等于无限等待,所以无奈之下只好重写了dubbo的ZookeeperClient实现,好在dubbo的扩展性非常好,基于SPI的扩展非常方便,下面是我的扩展代码:
1、增加一个文件com.alibaba.dubbo.remoting.zookeeper.ZookeeperTransporter放置于项目的META-INF/dubbo/internal文件夹下,dubbo便会自动扫描到这个文件。文件内容很简单就一句话:zkclient=com.gwall.zookeeper.ZkclientZookeeperTransporter
即把dubbo原来的默认实现替换为我的实现。
2、ZkclientZookeeperTransporter并不是我想替换的代码,我要替换的是ZkclientZookeeperTransporter的成员变量ZookeeperClient,只是dubbo只在ZookeeperTransporter上加了SPI注解,所以只好这样办了,ZkclientZookeeperTransporter代码照抄过来。
3、在ZkclientZookeeperTransporter里面使用自己的ZkclientZookeeperClient,代码如下:
package com.gwall.zookeeper;import java.util.List;import org.I0Itec.zkclient.IZkChildListener;import org.I0Itec.zkclient.IZkStateListener;import org.I0Itec.zkclient.ZkClient;import org.I0Itec.zkclient.exception.ZkNoNodeException;import org.I0Itec.zkclient.exception.ZkNodeExistsException;import org.apache.zookeeper.Watcher.Event.KeeperState;import com.alibaba.dubbo.common.URL;import com.alibaba.dubbo.remoting.zookeeper.ChildListener;import com.alibaba.dubbo.remoting.zookeeper.StateListener;import com.alibaba.dubbo.remoting.zookeeper.support.AbstractZookeeperClient;/** * 修改dubbo提供的ZkclientZookeeperClient * 主要目的是增加一个连接zookeeper的超时时间,避免ZkClient默认的无限等待 * @author long.zr * */public class ZkclientZookeeperClient extends AbstractZookeeperClient<IZkChildListener> { private final ZkClient client; private volatile KeeperState state = KeeperState.SyncConnected; public ZkclientZookeeperClient(URL url) { super(url); //设置超时时间为5000毫秒 client = new ZkClient(url.getBackupAddress(),5000); client.subscribeStateChanges(new IZkStateListener() { public void handleStateChanged(KeeperState state) throws Exception { ZkclientZookeeperClient.this.state = state; if (state == KeeperState.Disconnected) { stateChanged(StateListener.DISCONNECTED); } else if (state == KeeperState.SyncConnected) { stateChanged(StateListener.CONNECTED); } } public void handleNewSession() throws Exception { stateChanged(StateListener.RECONNECTED); } }); } public void createPersistent(String path) { try { client.createPersistent(path, true); } catch (ZkNodeExistsException e) { } } public void createEphemeral(String path) { try { client.createEphemeral(path); } catch (ZkNodeExistsException e) { } } public void delete(String path) { try { client.delete(path); } catch (ZkNoNodeException e) { } } public List<String> getChildren(String path) { try { return client.getChildren(path); } catch (ZkNoNodeException e) { return null; } } public boolean isConnected() { return state == KeeperState.SyncConnected; } public void doClose() { client.close(); } public IZkChildListener createTargetChildListener(String path, final ChildListener listener) { return new IZkChildListener() { public void handleChildChange(String parentPath, List<String> currentChilds) throws Exception { listener.childChanged(parentPath, currentChilds); } }; } public List<String> addTargetChildListener(String path, final IZkChildListener listener) { return client.subscribeChildChanges(path, listener); } public void removeTargetChildListener(String path, IZkChildListener listener) { client.unsubscribeChildChanges(path, listener); }}代码基本上是照抄dubbo的,唯一的区别是注释那里传递了一个超时时间为5000毫秒,过了超时时间ZkClient会抛出异常,线程也不会无限等待了。
奇怪的是dubbo为什么不在这里提供超时时间的配置,或许是因为ZkClient本身不属于dubbo的功能吧。
- 【Dubbo】dubbo连接zookeeper注册中心因为断网导致线程无限等待问题
- dubbo连接zookeeper注册中心因为断网导致线程无限等待问题
- dubbo连接zookeeper注册中心因为断网导致线程无限等待问题
- Dubbo注册中心zookeeper
- 安装dubbo注册中心Zookeeper
- Dubbo+zookeeper注册中心安装
- Dubbo注册中心集群Zookeeper
- dubbo--3.注册中心Zookeeper
- 通过zookeeper搭建dubbo注册中心遇到的问题
- 在Windows下安装zookeeper并启动,因为dubbo推荐使用这个注册中心
- dubbo注册中心zookeeper出现异常
- 基于ZooKeeper的Dubbo注册中心
- 基于ZooKeeper的Dubbo注册中心
- 基于ZooKeeper的Dubbo注册中心
- zookeeper作为注册中心,使用dubbo
- (四)dubbo注册中心-zookeeper
- 基于ZooKeeper的Dubbo注册中心
- 基于ZooKeeper的Dubbo注册中心
- 如何使 vlc 支持 fdk-aac 编码(windows平台
- jstl的fmt标签(格式标签)
- 设备模型三(潜谈sysfs)
- 0-1背包(DP经典问题)
- 编写地道的go代码
- dubbo连接zookeeper注册中心因为断网导致线程无限等待问题
- Android sdk content loader 0%的解决方案
- Machine Learn on device performance (Tensor flow way)
- 自动评测(ROUGE)及及踩过的坑
- 成为Java顶尖程序员 ,看这10本书就够了
- freemarker 类型转换
- iOS cocoaPods所集成的第三方框架 import不提示的问题与解决方案
- COdedorce 366 C Dima and Salad 题解(隐形01背包,好题)
- 静态文件编码的一个坑(freemarker)