在前一篇文章中Zookeeper-watcher機制源碼分析(一)說過Watcher的基本流程,在此文中詳細剖析服務端幾首請求處理流程。node
服務端有一個NettyServerCnxn類,用來處理客戶端發送過來的請求 程序員
NettyServerCnxn 數據庫
1編程 2promise 3服務器 4session 5架構 6app 7異步 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 |
|
處理客戶端傳送過來的數據包
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 |
|
負責在服務端提交當前請求
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
|
1.firstProcessor的初始化是在ZookeeperServer的setupRequestProcessor中完成的,代碼以下
1 2 3 4 5 6 7 |
|
從上面咱們能夠看到firstProcessor的實例是一個PrepRequestProcessor,而這個構造方法中又傳遞了一個Processor構成了一個調用鏈。
RequestProcessor syncProcessor = new SyncRequestProcessor(this, finalProcessor);
而syncProcessor的構造方法傳遞的又是一個Processor,對應的是FinalRequestProcessor
2.因此整個調用鏈是PrepRequestProcessor -> SyncRequestProcessor ->FinalRequestProcessor
經過上面瞭解到調用鏈關係之後,咱們繼續再看firstProcessor.processRequest(si); 會調用到PrepRequestProcessor
1 2 3 |
|
唉,很奇怪,processRequest只是把request添加到submittedRequests中,根據前面的經驗,很天然的想到這裏又是一個異步操做。而subittedRequests又是一個阻塞隊列
LinkedBlockingQueue<Request> submittedRequests = new LinkedBlockingQueue<Request>();
而PrepRequestProcessor這個類又繼承了線程類,所以咱們直接找到當前類中的run方法以下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
|
預處理這塊的代碼太長,就很差貼了。前面的N行代碼都是根據當前的OP類型進行判斷和作相應的處理,在這個方法中的最後一行中,咱們會看到以下代碼
nextProcessor.processRequest(request);
1 |
|
很顯然,nextProcessor對應的應該是SyncRequestProcessor
1 2 3 4 |
|
這個方法的代碼也是同樣,基於異步化的操做,把請求添加到queuedRequets中,那麼咱們繼續在當前類找到run方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 |
|
這個方法就是咱們在課堂上分析到的方法了,FinalRequestProcessor.processRequest方法並根據Request對象中的操做更新內存中Session信息或者znode數據。
這塊代碼有小300多行,就不所有貼出來了,咱們直接定位到關鍵代碼,根據客戶端的OP類型找到以下的代碼
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
|
1 2 3 |
|
一路向下,在下面這個方法中,講ServerCnxn向上轉型爲Watcher了。 由於ServerCnxn實現了Watcher接口
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
|
其大體流程以下
①經過傳入的路徑(節點路徑)從watchTable獲取相應的觀察者集合,進入②
② 判斷①中的觀察者是否爲空,若爲空,則進入③,不然,進入④
③ 新生成觀察者集合,並將路徑路徑和此集合添加至watchTable中,進入④
④將傳輸的觀察者添加至觀察者集合,即完成了路徑和觀察者添加至watchTable的步驟,進入⑤
⑤經過傳入的觀察者從watch2Paths中獲取相應的路徑集合,進入⑥
⑥ 判斷路徑集合是否爲空,若爲空,則進入⑦,不然,進入⑧
⑦ 新生成路徑集合,並將觀察者和路徑添加至watch2Paths中,進入⑧
⑧將傳入的路徑(節點路徑)添加至路徑集合,即完成了路徑和觀察者添加至watch2Paths步驟的
總結
調用關係鏈以下
圖文裏的技術如何學習,有沒有免費資料?
對Java技術,架構技術感興趣的同窗,歡迎加QQ羣619881427,一塊兒學習,相互討論。
羣內已經有小夥伴將知識體系整理好(源碼,筆記,PPT,學習視頻),歡迎加羣免費領取。
分享給喜歡Java的,喜歡編程,有夢想成爲架構師的程序員們,但願可以幫助到大家。
不是Java的程序員也不要緊,幫忙轉發給更多朋友!謝謝。
一個分享小技巧點擊閱讀原文也。能夠輕鬆到電子雜誌學習資料哦!