帶着問題擼源碼系列-zookeeper-客戶端怎麼給sever發請求

問題​

客戶端怎麼給server發請求?

猜測

parse 輸入的command 然後通過某種方式發給server。

預讀代碼

從客戶端main代碼org.apache.zookeeper.ZooKeeperMain看起,看下怎麼給server發請求的。
慢慢追蹤到這:org.apache.zookeeper.ZooKeeperMain#processZKCmd
就是這裏:在這裏插入圖片描述
假設我們現在要發一個create /test
實現類就是CreateCommand
parse不管
看exec函數
一通操作後走到了
org.apache.zookeeper.ZooKeeper#create(java.lang.String, byte[], java.util.List<org.apache.zookeeper.data.ACL>, org.apache.zookeeper.CreateMode)(看參數少點這個)

在這裏插入圖片描述
於是我們可以看到是通過cnxn這個東西去submitRequest的。
再點進去,發現是通過packet發的
在這裏插入圖片描述
那packet是個啥?再點進去發現
調用packet.wait() 意思就是等待request完成

觸碰到知識盲點了:所有object都有wait(),調用的時候發生了什麼?
答:https://www.baeldung.com/java-wait-notify
就是線程suspend了,等待別人喚醒。

所以我們可以想象有別的地方會把這個packet喚醒,通知他請求發送完了。

注意packet是new queuePacket()
點進去可以發現有把packet放到隊列的邏輯:org.apache.zookeeper.ClientCnxn#queuePacket(org.apache.zookeeper.proto.RequestHeader, org.apache.zookeeper.proto.ReplyHeader, org.apache.jute.Record, org.apache.jute.Record, org.apache.zookeeper.AsyncCallback, java.lang.String, java.lang.String, java.lang.Object, org.apache.zookeeper.ZooKeeper.WatchRegistration, org.apache.zookeeper.WatchDeregistration)
在這裏插入圖片描述
這個接口有兩個實現,我們來看NIO的實現
org.apache.zookeeper.ClientCnxnSocketNIO#wakeupCnxn
就是selecor.wakeup()
把數據從socket寫出去
在這裏插入圖片描述

打斷點

那我們就把斷點打在org.apache.zookeeper.ZooKeeper#create(java.lang.String, byte[], java.util.List<org.apache.zookeeper.data.ACL>, org.apache.zookeeper.CreateMode)
在這裏插入圖片描述

環境準備

可以參考: ​https://blog.csdn.net/waltonhuang/article/details/106071393

server 1 debug啓動
server 2、3 run 啓動
server1是follower。

客戶端連接server1,debug方式啓動

在這裏插入圖片描述

寫請求create /test發給server1。

在這裏插入圖片描述

成功斷點在了我們斷點的地方:開心
在這裏插入圖片描述
一路確實走到了咱們的NIO的wakeUpCnxn

結束!完美按照我們設想的路子走到了最後!

回答問題

通過NIO把packet,經過socket,發送給了server

奇怪的知識增加了!

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章