ZooKeeper集群中的跟隨者對客戶端請求的處理流程解讀(二)

jopen 9年前發布 | 12K 次閱讀 ZooKeeper 分布式/云計算/大數據

前篇簡要回顧:在ZooKeeper集群選舉完成之后,各個集群節點各就各位,領導者開始領導、跟隨者開始跟隨,我們已經看到跟隨者建立和領導者的連接,并接受領導者的命令開始恢復,恢復完成之后領導者給了跟隨者一個UPTODATE命令,跟隨者開始進入接客狀態。。。


那么這里出現了兩條線,跟隨者一方面開始接客(接收并處理客戶端的讀寫請求,為ZK客戶端服務),另一方面跟隨者保持和領導者的密切連接,通過連接做一些事情,這個會在后面講到,我們先看看跟隨者是如何接客的,這也是和文章的標題相呼應。


跟隨者為客戶端服務的入口在這里我們通過NettyServerCnxnFactory這個類介紹,這個類是ZK通過Netty(NIO框架)來處理網絡層業務的實現,我的之前一篇文章(http://jvmplus.duapp.com /blog/view/B143299758)有介紹Netty在ZooKeeper中的應用,其中介紹了NettyServerCnxnFactory 是如何基于Netty建立網絡連接、獲取連接通道、接收和發送網絡數據的,關于這部分讀者可以直接簡要閱讀下那篇文章,這里我么你直接往下走,看ZK是如 何和客戶端進行互動的。

看下NettyServerCnxnFactory的 processMessage方法,這個方法主要是用來處理通道數據的,這里ZK對客戶端的連接通道主要消息類型有兩種,分別是 ResumeMessageEvent(回復通道事件)和Netty從通道拿到數據并封裝的原始類型,即非ResumeMessageEvent類型。 ResumeMessageEvent類型消息是ZK通過實現Netty的MessageEvent接口實現的一種消息事件類型,主要是用來區別是原始網 絡通道讀取的客戶端消息事件,還是ZK通過Netty的ChannelPipeline類的sendUpstream方法向通道上傳的消息事件類型數據, 后面processMessage方法會針對這兩種不同類型的消息事件類型做不同的事情。


當從通道中讀取ResumeMessageEvent類型的消息事件類型的時候,ZK做的事情主要是回復通道,將通道設置為可讀(OP_READ)模式。


這里主要是看下ZK對非 ResumeMessageEvent類型的消息事件類型的處理,ZK為了防止通道的數據量太大,發生擁堵現象,ZK給 NettyServerCnxn(代表ZK和客戶端連接的抽象)設置了一個字段throttled,它用來標識當前通道的數據是不是可以直接拿來處理,也 就是當處理的速度跟不上IO的速度額度時候,ZK會將throttled這個值設置為true,如果是throttled狀態,則ZK將讀取的消息放入內 存等待處理隊列里面;如果當前通道處于非throttled狀態,ZK首先看看等待隊列是不是有數據在等待,如果有,ZK將讀取的數據寫入等待隊列里面, 然后開始處理隊列數據。如果隊列為空,則ZK直接處理通道的數據,然后看看是否還有剩余,如果通道有剩余數據則將剩余數據寫入等待隊列。下面用圖簡單表示 一下ZK在這里對客戶端端口網絡消息的處理流程:



接 下來就是NettyServerCnxn的receiveMessage方法是如何對通道拿到的消息進行處理的,ZK這里會首先判斷是否有可讀消息,并且 再次判斷throttled的狀態,如果不滿足可讀的條件則關閉和客戶端的連接,通常正常狀態的ZK和客戶端的連接應該是長連接,這里為什么為斷開?這里 應該是發生了異常,也就是通道接收到了消息事件,但是又是不可讀,則ZK會關閉和客戶端的連接。


這 里ZK會判斷連接的狀態,如果是未初始化狀態則ZK會把這個請求是當做連接請求,否則會會交給processPacket來處理。 processPacket會首先解析客戶端請求包的類型,包括auth、sasl和普通類型三種,前兩種類型是認證和授權相關的,后面有機會再介紹,這 里主要介紹普通類型包的處理過程,于是到了ZooKeeperServer的submitRequest這個方法,總算快要開始ZK對客戶端請求處理流程 的核心部分了。


下篇文章進入ZooKeeper對客戶端請求處理流程的核心部分。


來自:http://jvmplus.duapp.com/blog/view/B143719118

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!