dubbo連接zookeeper注冊(cè)中心因?yàn)閿嗑W(wǎng)導(dǎo)致線程無限等待問題【轉(zhuǎn)】

最近維護(hù)的系統(tǒng)切換了網(wǎng)絡(luò)環(huán)境,由聯(lián)通換成了電信網(wǎng)絡(luò),因?yàn)槟承┻^濾規(guī)則導(dǎo)致系統(tǒng)連不上zookeeper服務(wù)器(應(yīng)用系統(tǒng)機(jī)器在深圳,網(wǎng)絡(luò)為電信線路,zookeeper服務(wù)器在北京,網(wǎng)絡(luò)為聯(lián)通線路),因?yàn)槲也皇沁\(yùn)維人員也不懂運(yùn)維相關(guān)的技術(shù),所以排查了很久也不知道原因,最后無奈之下把深圳這邊的網(wǎng)絡(luò)切回了聯(lián)通,系統(tǒng)恢復(fù)正常。

但是因?yàn)楸敬问鹿鼠w現(xiàn)了一個(gè)很嚴(yán)重的問題,即當(dāng)zookeeper注冊(cè)中心連不上時(shí)dubbo的線程會(huì)無限等待,因?yàn)橄到y(tǒng)有一些定時(shí)任務(wù)會(huì)比較頻繁地開啟新線程連接dubbo,所以導(dǎo)致的結(jié)果是tomcat一會(huì)兒線程池就滿了,其它的不依賴dubbo的功能也被阻塞無法使用。

所以需要解決一個(gè)問題,即在斷網(wǎng)的情況下要保證應(yīng)用程序可以運(yùn)行(有很多功能不依賴外網(wǎng)),一開始我以為dubbo應(yīng)該有對(duì)ZKClient連接相關(guān)的超時(shí)時(shí)間配置,結(jié)果找了很久也沒發(fā)現(xiàn),后來debug了dubbo的源代碼發(fā)現(xiàn)根本就沒有設(shè)置超時(shí)時(shí)間,ZKClient默認(rèn)的超時(shí)時(shí)間是Integer.MAX_VALUE,幾乎等于無限等待,所以無奈之下只好重寫了dubbo的ZookeeperClient實(shí)現(xiàn),好在dubbo的擴(kuò)展性非常好,基于SPI的擴(kuò)展非常方便,下面是我的擴(kuò)展代碼:

1、增加一個(gè)文件com.alibaba.dubbo.remoting.zookeeper.ZookeeperTransporter放置于項(xiàng)目的META-INF/dubbo/internal文件夾下,dubbo便會(huì)自動(dòng)掃描到這個(gè)文件。文件內(nèi)容很簡單就一句話:zkclient=com.gwall.zookeeper.ZkclientZookeeperTransporter

即把dubbo原來的默認(rèn)實(shí)現(xiàn)替換為我的實(shí)現(xiàn)。

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 * 主要目的是增加一個(gè)連接zookeeper的超時(shí)時(shí)間,避免ZkClient默認(rèn)的無限等待 * @author long.zr * */

public class ZkclientZookeeperClient extends AbstractZookeeperClient {

private final ZkClient client;

private volatile KeeperState state = KeeperState.SyncConnected;

public ZkclientZookeeperClient(URL url) {

super(url);

//設(shè)置超時(shí)時(shí)間為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 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 currentChilds)

throws Exception {

listener.childChanged(parentPath, currentChilds);

}

};

}

public List addTargetChildListener(String path, final IZkChildListener listener) {

return client.subscribeChildChanges(path, listener);

}

public void removeTargetChildListener(String path, IZkChildListener listener) {

client.unsubscribeChildChanges(path,? listener);

}

}

框架/平臺(tái)構(gòu)成:

Maven+Springmvc + Mybatis + Shiro(權(quán)限)+ Tiles(模板) +ActiveMQ(消息隊(duì)列) + Rest(服務(wù)) + WebService(服務(wù))+ EHcache(緩存) + Quartz(定時(shí)調(diào)度)+ Html5(支持PC、IOS、Android)

用戶權(quán)限系統(tǒng):

組織結(jié)構(gòu):角色、用戶、用戶組、組織機(jī)構(gòu);權(quán)限點(diǎn):頁面、方法、按鈕、數(shù)據(jù)權(quán)限、分級(jí)授權(quán)

項(xiàng)目管理新體驗(yàn):

快速出原型系統(tǒng)、組件樹、版本控制、模塊移植、協(xié)同開發(fā)、實(shí)時(shí)監(jiān)控、發(fā)布管理

可持續(xù)集成:

所有組件可移植、可定制、可擴(kuò)充,開發(fā)成果不斷積累,形成可持續(xù)發(fā)展的良性循環(huán)

支持平臺(tái)平臺(tái):

Windows XP、Windows 7 、Windows 10 、 Linux 、 Unix

服務(wù)器容器:

Tomcat 5/6/7 、Jetty、JBoss、WebSphere 8.5

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,554評(píng)論 19 139
  • 0 準(zhǔn)備 安裝注冊(cè)中心:Zookeeper、Dubbox自帶的dubbo-registry-simple;安裝Du...
    七寸知架構(gòu)閱讀 14,106評(píng)論 0 88
  • 萬物復(fù)蘇的春天在悄悄走近,除了保養(yǎng)好皮膚、勵(lì)志瘦身藏肉穿上美美的衣服之外,你也許還需要一些或成熟復(fù)古或俏皮可愛的配...
    安雅敏敏閱讀 1,738評(píng)論 4 46
  • 口中三千章懷事,袖里乾坤不自知。 揮筆直書談天地,縱論五行異曲直。 松林定隱觀時(shí)勢,燕雀贏飛笑吾癡。 時(shí)人安知鴻鵠...
    萌萌AC閱讀 527評(píng)論 0 2
  • 目錄|我的奇葩相親經(jīng)歷目錄上一章|第10章戳這里哦 文|瘋狂小梅子 中午和李老師在學(xué)校食堂吃飯。 她特意帶了自己做...
    瘋狂小梅子閱讀 1,999評(píng)論 20 13

友情鏈接更多精彩內(nèi)容