這一篇文章我們将學習使用curator來實作計數器。 顧名思義,計數器是用來計數的, 利用zookeeper可以實作一個叢集共享的計數器。 隻要使用相同的path就可以得到最新的計數器值, 這是由zookeeper的一緻性保證的。curator有兩個計數器, 一個是用int來計數,一個用long來計數。
這個類使用int類型來計數。 主要涉及三個類。
sharedcount
sharedcountreader
sharedcountlistener
<code>sharedcount</code>代表計數器, 可以為它增加一個sharedcountlistener,當計數器改變時此listener可以監聽到改變的事件,而sharedcountreader可以讀取到最新的值, 包括字面值和帶版本資訊的值versionedvalue。
例子代碼:
在這個例子中,我們使用<code>basecount</code>來監聽計數值(<code>addlistener</code>方法)。 任意的sharedcount, 隻要使用相同的path,都可以得到這個計數值。 然後我們使用5個線程為計數值增加一個10以内的随機數。
這裡我們使用<code>trysetcount</code>去設定計數器。 第一個參數提供目前的versionedvalue,如果期間其它client更新了此計數值, 你的更新可能不成功, 但是這時你的client更新了最新的值,是以失敗了你可以嘗試再更新一次。 而<code>setcount</code>是強制更新計數器的值。
注意計數器必須<code>start</code>,使用完之後必須調用<code>close</code>關閉它。
在這裡再重複一遍前面講到的, 強烈推薦你監控<code>connectionstatelistener</code>, 盡管我們的有些例子沒有監控它。 在本例中<code>sharedcountlistener</code>擴充了<code>connectionstatelistener</code>。 這一條針對所有的curator recipes都适用,後面的文章中就不專門提示了。
再看一個long類型的計數器。 除了計數的範圍比<code>sharedcount</code>大了之外, 它首先嘗試使用樂觀鎖的方式設定計數器, 如果不成功(比如期間計數器已經被其它client更新了), 它使用<code>interprocessmutex</code>方式來更新計數值。 還記得<code>interprocessmutex</code>是什麼嗎? 它是我們前面跟着執行個體學習zookeeper的用法: 分布式鎖 講的分布式可重入鎖。 這和上面的計數器的實作有顯著的不同。
可以從它的内部實作<code>distributedatomicvalue.tryset</code>中看出端倪。
此計數器有一系列的操作:
get(): 擷取目前值
increment(): 加一
decrement(): 減一
add(): 增加特定的值
subtract(): 減去特定的值
tryset(): 嘗試設定計數值
forceset(): 強制設定計數值
你必須檢查傳回結果的<code>succeeded()</code>, 它代表此操作是否成功。 如果操作成功, <code>prevalue()</code>代表操作前的值, <code>postvalue()</code>代表操作後的值。
我們下面的例子中使用5個線程對計數器進行加一操作,如果成功,将操作前後的值列印出來。