dubbo连接zookeeper注册中心因为断网导致线程无限等待问题【转】
2016-10-12 11:55
501 查看
最近维护的系统切换了网络环境,由联通换成了电信网络,因为某些过滤规则导致系统连不上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,代码如下:
packagecom.gwall.zookeeper;
importjava.util.List;
importorg.I0Itec.zkclient.IZkChildListener;
importorg.I0Itec.zkclient.IZkStateListener;
importorg.I0Itec.zkclient.ZkClient;
importorg.I0Itec.zkclient.exception.ZkNoNodeException;
importorg.I0Itec.zkclient.exception.ZkNodeExistsException;
importorg.apache.zookeeper.Watcher.Event.KeeperState;
importcom.alibaba.dubbo.common.URL;
importcom.alibaba.dubbo.remoting.zookeeper.ChildListener;
importcom.alibaba.dubbo.remoting.zookeeper.StateListener;
importcom.alibaba.dubbo.remoting.zookeeper.support.AbstractZookeeperClient;
/***修改dubbo提供的ZkclientZookeeperClient*主要目的是增加一个连接zookeeper的超时时间,避免ZkClient默认的无限等待*@authorlong.zr**/
publicclassZkclientZookeeperClientextendsAbstractZookeeperClient<IZkChildListener>{
privatefinalZkClientclient;
privatevolatileKeeperStatestate=KeeperState.SyncConnected;
publicZkclientZookeeperClient(URLurl){
super(url);
//设置超时时间为5000毫秒
client=newZkClient(url.getBackupAddress(),5000);
client.subscribeStateChanges(newIZkStateListener(){
publicvoidhandleStateChanged(KeeperStatestate)throwsException{
ZkclientZookeeperClient.this.state=state;
if(state==KeeperState.Disconnected){
stateChanged(StateListener.DISCONNECTED);
}elseif(state==KeeperState.SyncConnected){
stateChanged(StateListener.CONNECTED);
}
}
publicvoidhandleNewSession()throwsException{
stateChanged(StateListener.RECONNECTED);
}
});
}
publicvoidcreatePersistent(Stringpath){
try{
client.createPersistent(path,true);
}catch(ZkNodeExistsExceptione){
}
}
publicvoidcreateEphemeral(Stringpath){
try{
client.createEphemeral(path);
}catch(ZkNodeExistsExceptione){
}
}
publicvoiddelete(Stringpath){
try{
client.delete(path);
}catch(ZkNoNodeExceptione){
}
}
publicList<String>getChildren(Stringpath){
try{
returnclient.getChildren(path);
}catch(ZkNoNodeExceptione){
returnnull;
}
}
publicbooleanisConnected(){
returnstate==KeeperState.SyncConnected;
}
publicvoiddoClose(){
client.close();
}
publicIZkChildListenercreateTargetChildListener(Stringpath,finalChildListenerlistener){
returnnewIZkChildListener(){
publicvoidhandleChildChange(StringparentPath,List<String>currentChilds)
throwsException{
listener.childChanged(parentPath,currentChilds);
}
};
}
publicList<String>addTargetChildListener(Stringpath,finalIZkChildListenerlistener){
returnclient.subscribeChildChanges(path,listener);
}
publicvoidremoveTargetChildListener(Stringpath,IZkChildListenerlistener){
client.unsubscribeChildChanges(path,listener);
}
}
框架/平台构成:
Maven+Springmvc+Mybatis+Shiro(权限)+Tiles(模板)+ActiveMQ(消息队列)+Rest(服务)+WebService(服务)+EHcache(缓存)+Quartz(定时调度)+Html5(支持PC、IOS、Android)
用户权限系统:
组织结构:角色、用户、用户组、组织机构;权限点:页面、方法、按钮、数据权限、分级授权
项目管理新体验:
快速出原型系统、组件树、版本控制、模块移植、协同开发、实时监控、发布管理
可持续集成:
所有组件可移植、可定制、可扩充,开发成果不断积累,形成可持续发展的良性循环
支持平台平台:
WindowsXP、Windows7、Windows10、Linux、Unix
服务器容器:
Tomcat5/6/7、Jetty、JBoss、WebSphere8.5
但是因为本次事故体现了一个很严重的问题,即当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,代码如下:
框架/平台构成:
Maven+Springmvc+Mybatis+Shiro(权限)+Tiles(模板)+ActiveMQ(消息队列)+Rest(服务)+WebService(服务)+EHcache(缓存)+Quartz(定时调度)+Html5(支持PC、IOS、Android)
用户权限系统:
组织结构:角色、用户、用户组、组织机构;权限点:页面、方法、按钮、数据权限、分级授权
项目管理新体验:
快速出原型系统、组件树、版本控制、模块移植、协同开发、实时监控、发布管理
可持续集成:
所有组件可移植、可定制、可扩充,开发成果不断积累,形成可持续发展的良性循环
支持平台平台:
WindowsXP、Windows7、Windows10、Linux、Unix
服务器容器:
Tomcat5/6/7、Jetty、JBoss、WebSphere8.5
相关文章推荐
- dubbo连接zookeeper注册中心因为断网导致线程无限等待问题【转】
- dubbo连接zookeeper注册中心因为断网导致线程无限等待问题【转】
- dubbo连接zookeeper注册中心因为断网导致线程无限等待问题【转】
- dubbo连接zookeeper注册中心因为断网导致线程无限等待问题【转】
- 【Dubbo】dubbo连接zookeeper注册中心因为断网导致线程无限等待问题
- dubbo连接zookeeper注册中心因为断网导致线程无限等待问题【转】
- dubbo连接zookeeper注册中心因为断网导致线程无限等待问题【转】
- dubbo连接zookeeper注册中心因为断网导致线程无限等待问题
- dubbo连接zookeeper注册中心因为断网导致线程无限等待问题【转】
- dubbo连接zookeeper注册中心因为断网导致线程无限等待问题
- dubbo连接zookeeper注册中心因为断网导致线程无限等待问题【转】
- 线程并发-同步synchronized无限等待问题
- java生产者消费者问题(线程同步与线程等待的应用)
- Response.End导致“正在中止线程”异常的问题
- mysql因为锁等待导致导入用户失败(Lock wait timeout exceeded; try restarting transaction)
- Response.End导致“正在中止线程”异常的问题
- 在Win7/Vista下因为Flash 11.3导致Firefox崩溃问题解决方法
- tomcat启动时候,有事会因为某些问题(基本都是配置问题),导致tomcat启动一闪而过,错误看不到.
- axis部署到weblogic因为运行环境为jrockit导致空指针的问题
- Activity中开辟了线程更新UI,线程未结束,退出了Activity,导致问题