dubbo串連zookeeper註冊中心因為斷網導致線程無限等待問題【轉】

來源:互聯網
上載者:User

標籤:frd   相關   nal   深圳   getch   string   address   ges   unix   

最近維護的系統切換了網路環境,由聯通換成了電信網路,因為某些過濾規則導致系統連不上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);    }}

架構/平台構成:
Maven+Springmvc + Mybatis + Shiro(許可權)+ Tiles(模板) +ActiveMQ(訊息佇列) + Rest(服務) + WebService(服務)+ EHcache(緩衝) + Quartz(定時調度)+ Html5(支援PC、IOS、Android)

使用者權限系統:
組織圖:角色、使用者、使用者組、組織機構;許可權點:頁面、方法、按鈕、資料許可權、分級授權

專案管理新體驗:
快速出原型系統、組件樹、版本控制、模組移植、協同開發、即時監控、發行管理

可持續整合:
所有組件可移植、可定製、可擴充,開發成果不斷積累,形成可持續發展的良性迴圈

支援平台平台: 
Windows XP、Windows 7 、Windows 10 、 Linux 、 Unix

伺服器容器:
Tomcat 5/6/7 、Jetty、JBoss、WebSphere 8.5 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

dubbo串連zookeeper註冊中心因為斷網導致線程無限等待問題【轉】

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.