ZooKeeper客户端地址列表的随机原理
查看PDF版本
轉(zhuǎn)載請用注明:@ni掌柜nileader@gmail.com
?
在之前一個文章《ZooKeeper Java API 使用樣例》中提到,客戶端使用ZooKeeper的時候,首先會建立與ZooKeeper的連接,方法是通過調(diào)用下面這個構(gòu)造方法來實(shí)現(xiàn)的。
- public?ZooKeeper(String?connectString,?//?
- int?sessionTimeout,?//?
- Watcher?watcher,//?
- boolean?canBeReadOnly?)?
- throws?IOException?
?在這個構(gòu)造方法中,首先要配置的是ZK服務(wù)器的地址列表,即connectString 這個參數(shù),這個參數(shù)通常是這樣一個格式的字符串:
- 192.168.1.1:2181,192.168.1.2:2181,192.168.1.3:2181?
?很明顯,我們可以看到,ZK客戶端允許我們將ZK服務(wù)器的所有地址都配置在這里,于是一個問題就來了,ZK在連接服務(wù)器過程中,是如何選擇服務(wù)器的呢?下面首先來看看ZK客戶端是如何處理這個connectString的:
- new?ZooKeeper(“192.168.1.1:2181,192.168.1.2:2181,192.168.1.3:2181”,...)?
?實(shí)例一個ZooKeeper對象的時候,會要求傳入一個地址列表的字符串,這個字符串就是ZK服務(wù)器的地址列表,用英文狀態(tài)“,“隔開。
- ConnectStringParser?connectStringParser?=??
?之后,這個地址列表會被封裝到一個ConnectStringParser 對象中去,這個類主要就是解析傳入地址列表字符串,將其它保存在一個ArrayList中。這個對象基本結(jié)構(gòu)如下,這里我們主要關(guān)注serverAddresses這個成員。
- public?final?class?ConnectStringParser?{?
- ????private?final?String?chrootPath;?
- ????private?final?ArrayList<InetSocketAddress>?serverAddresses?=?new?ArrayList<InetSocketAddress>();?
- }?
接下去,這個地址列表會被進(jìn)一步封裝成StaticHostProvider對象,并且在運(yùn)行過程中,一直是這個對象來維護(hù)整個地址列表。關(guān)于這個對象,我們主要關(guān)注兩點(diǎn):地址列表的隨機(jī)和地址獲取這兩個過程。首先來看地址列表的隨機(jī):
- public?StaticHostProvider(Collection<InetSocketAddress>?serverAddresses)?
- ????????????throws?UnknownHostException?{?
- ????????……?
- ……?
- ????????Collections.shuffle(this.serverAddresses);?
- ????}?
這里可以看到,對于傳入地址列表,ZK使用java.util.Collections.shuffle(List?list) 來對地址列表隨機(jī)打亂順序,注意,這個隨機(jī)過程是一次性的,也就是說,之后使用過程中一直是按照這樣的順序。再來看看地址列表被隨機(jī)打亂后,又是怎么使用地址的:
- ?public?InetSocketAddress?next(long?spinDelay)?{?
- ????????++currentIndex;?
- ????????if?(currentIndex?==?serverAddresses.size())?{?
- ????????????currentIndex?=?0;?
- ????????}?
- ……?
- ……?
- ????????return?serverAddresses.get(currentIndex);?
- ????}?
看一下StaticHostProvider.next(long spinDelay) 方法就明白了。next方法的實(shí)現(xiàn), 沒錯,就是“Round Robin”。簡單的說,ZK客戶端將所有Server保存在一個List中,然后隨機(jī)打亂,并且形成一個環(huán),具體使用的時候,從0號位開始一個一個使用。
另外兩個注意點(diǎn):
1.通過代碼,可以發(fā)現(xiàn)ZK本質(zhì)上是通過一個List來維護(hù)地址列表的,因此,Server地址能夠重復(fù)配置,這樣能夠彌補(bǔ)客戶端無法設(shè)置Server權(quán)重的缺陷,但是也會加大風(fēng)險。 比如: 192.168.1.1:2181,192.168.1.1:2181,192.168.1.2:2181
2.如果客戶端在進(jìn)行Server切換過程中耗時過長,那么將會收到SESSION_EXPIRED. 這也是上面第1點(diǎn)中的加大風(fēng)險之處。
本文出自 “ni掌柜的筆記” 博客,請務(wù)必保留此出處http://nileader.blog.51cto.com/1381108/932948
轉(zhuǎn)載于:https://www.cnblogs.com/java20130722/p/3206755.html
總結(jié)
以上是生活随笔為你收集整理的ZooKeeper客户端地址列表的随机原理的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 诛仙1电影版有多长时间
- 下一篇: Angularjs集成第三方js插件之U