背景
最近遇到一些問題,比如一個服務(wù)安疗,需要在請求的客戶端上做路由绘搞。這時就需要
- 獲取服務(wù)端在哪幾個服務(wù)器的進(jìn)程上遣钳,
- 需要自行實(shí)現(xiàn)路由扰魂,
- 需要針對服務(wù)端某一些節(jié)點(diǎn)上下線做自動更新。
還有一種場景蕴茴。我有一個監(jiān)控服務(wù)劝评,讀取DB的數(shù)據(jù),當(dāng)DB中需要監(jiān)聽的進(jìn)程達(dá)到上千時倦淀,頻率要求10秒1次蒋畜,這時一臺機(jī)器的監(jiān)聽已經(jīng)不足以承載。需要擴(kuò)展到多進(jìn)程部署撞叽。
思考
以上問題均可以使用zk的curator通知機(jī)制來實(shí)現(xiàn)姻成。
歸納一下問題。
- 需要通知服務(wù)上下線機(jī)制愿棋;
- 需要熱更新科展,類似rehash的過程。
解決
針對場景一種的糠雨,路由+維持DubboRef方式才睹,可以監(jiān)聽zk下的dubbo路徑,dubbo的上下線均會通知過來甘邀,這時將服務(wù)進(jìn)行上下線處理即可琅攘。問題是,在切換的過程中松邪,部分服務(wù)不可用坞琴。因?yàn)閦k延遲,切換也有成本逗抑。
針對場景二種置济,可以在啟動進(jìn)程時解恰,注冊zk節(jié)點(diǎn),根據(jù)自行創(chuàng)建的節(jié)點(diǎn)取模獲取不同的監(jiān)控任務(wù)浙于。這是任務(wù)分發(fā)护盈,用以支持多進(jìn)程擴(kuò)展。
同時如果期望做到HA羞酗,高可用的話腐宋,可以先對數(shù)據(jù)進(jìn)行分發(fā),再對分發(fā)的任務(wù)進(jìn)行備份檀轨。例如1胸竞,2,3數(shù)據(jù)参萄,分別給a,b,c,d,e,f進(jìn)程執(zhí)行卫枝。a,b,c分配到1,2,3執(zhí)行。d,e,f也分配到1,2,3讹挎,但是會監(jiān)聽zk節(jié)點(diǎn)校赤,如果非活動時⊥怖#可以隨時代替掛掉的節(jié)點(diǎn)马篮。這樣就實(shí)現(xiàn)了HA高可用。
思考點(diǎn)
- 擴(kuò)展性怜奖,體現(xiàn)在能否數(shù)據(jù)量上來后浑测,是否有簡潔的擴(kuò)展能力;
- 可用性歪玲,體現(xiàn)在節(jié)點(diǎn)掛掉后迁央,服務(wù)是否有部分/全部不可用的狀態(tài)。
curator監(jiān)聽zk
private void setDubboRemoteListenter(CuratorFramework client) throws Exception{
PathChildrenCache childrenCache = new PathChildrenCache(client, ZkParams.servicePath, true);
PathChildrenCacheListener childrenCacheListener = new PathChildrenCacheListener() {
@Override
public void childEvent(CuratorFramework client, PathChildrenCacheEvent event) throws Exception {
ChildData data = event.getData();
switch (event.getType()) {
case CHILD_ADDED:
case CHILD_UPDATED:
update(data.getPath(), false);
break;
case CHILD_REMOVED:
update(data.getPath(), true);
break;
default:
break;
}
}
};
childrenCache.getListenable().addListener(childrenCacheListener);
childrenCache.start(StartMode.POST_INITIALIZED_EVENT);
}
總結(jié)
zk有多種玩法滥崩,可用來玩共享鎖漱贱,主要還是用來服務(wù)發(fā)現(xiàn),通知夭委。缺陷是支持的并發(fā)略低幅狮,通知延遲服務(wù)狀態(tài)不可用。
如果需要共享鎖株灸,使用redis setnx更為合適崇摄。redis setnx介紹