1. 程式人生 > >OceanBase server處理網路包的回撥邏輯

OceanBase server處理網路包的回撥邏輯

OceanBase處理網路包的邏輯還是蠻繞的,這裡以UPS為例,作為給自己的備忘。

UPS程式碼的main.cpp中呼叫ObUpdateServerMain的start啟動server。start函式會呼叫ObUpdateServerMain的do_work函式,此函式呼叫ObUpdateServer類的start啟動UPS。

ObUpdateServer繼承自如下幾個類:

1)common::ObBaseServer,基礎的server類,要求派生類實現handlePacket和handleBatchPacket方法(後一個UPS不會使用),這兩個是純虛擬函式,同時有個虛擬函式start_service,派生類可以實現此方法用於初始化時做些server相關的邏輯;

2)ObPacketQueueHandler,  要求派生類實現handlePacketQueue介面;

3)common::IBatchPacketQueueHandler,要求派生類實現handleBatchPacketQueue介面;

ObUpdateServer類的start函式實際上呼叫的ObBaseServer的start函式,此函式做如下幾件事:

1)初始化libeasy相關的一系列資料結構, 在特定的網路埠上監聽等;

2)呼叫initialize函式(需要派生類實現);

3)呼叫start_service函式(派生類可自己實現);

ObUpdateServer的initialize函式,做一系列啟動UPS內部所需的引數的初始化,除了必要的引數外,有幾個需要特別注意下:

1)server_handler_,此變數的型別是easy_io_handler_pt,此處註冊一系列回撥,包括收包時的編解碼(server_handler_.encode/server_handler_.decode),收包時的處理邏輯(server_handler_.process),斷開連線時的處理等(server_handler_.on_disconnect)等;編解碼相關等都是使用的所有OB server共用的ObTbnetCallback類的方法,版本升級時包的格式變化只需要統一改此common類的方法即可;包的處理邏輯呼叫的UPS自己的ObUpdateCallback::process方法;

2)client_manager_的初始化,後續server發包都需要用到client_manager_;

3)rpc相關的初始化;

4)一系列worker執行緒的初始化(如read_thread_queue_/write_thread_queue_/lease_thread_queue_等,具體看程式碼,指定不同型別執行緒的執行緒數,將this傳給各個執行緒用作handler回撥等);

ObUpdateServer的start_service函式,呼叫start_threads(此函式呼叫上述一系列worker執行緒的start方法,等候收到任務處理),start_timer_schedule設定一系列ObTimer設定一些定時器相關的處理邏輯。

如上和網路包處理相關的一系列函式說清楚了,然後具體說說網路包收到後是怎麼處理的。

libeasy收到包會呼叫註冊的回撥方法ObUpdateCallback::process,此函式會呼叫ObUpdateServer的handlePacket方法,此函式由各server自己實現,如UPS,會根據packet_code不同,或者進行本地處理(因為libeasy有多個IO poll thread,所以本地可以處理一些耗時少的操作包),或是扔給不同的worker類處理。這裡分別舉個例子:

1)packet_code為OB_SET_OBI_ROLE型別的包,呼叫read_thread_queue_的push方法,交由read_thread_queue_執行緒處理;

2)packet_code為OB_UPS_CLEAR_FATAL_STATUS型別的包,呼叫lease_thread_queue_的push方法,交由lease_thread_queue_執行緒處理;

3)OB_WRITE/OB_MS_MUTATE/OB_FAKE_WRITE_FOR_KEEP_ALIVE/OB_UPS_PHY_PLAN_EXECUTE/OB_START_TRANSACTION/OB_END_TRANSACTION/OB_WRITE_DUMMY_LOG型別的包,直接在IO執行緒中呼叫trans_executor_的handle_packet函式處理;這裡注意下,trans_executor_的handle_packet也會進一步判斷包的型別,確定是直接在此函式中處理(transe_executor_類對不同型別的包實現了一系列的handle函式),還是通過呼叫push_task_交由trans_executor自己的一系列worker執行緒處理。

read_thread_queue_等worker執行緒是common::ObPacketQueueThread型別的(或者其他類似型別)例項,此類型別都是tbsys::CDefaultRunnable的派生類,其內部含有一個阻塞佇列等訊息到來,同時有一個用於回撥的ObPacketQueueHandler型別的handler(注意ObUpdateServer就繼承自ObPacketQueueHandler,實際上此處註冊的handler就是ObUpdateServer類的物件)。此類worker執行緒start後真正呼叫的是ObPacketQueueThread::run函式,此函式即從內部佇列中取訊息,然後呼叫ObUpdateServer的handlePacketQueue函式,handlePacketQueue函式再根據包的型別呼叫ObUpdateServer類實現的各類方法對包進行處理。此處由於是worker執行緒,所有包都是執行緒本地處理的。

至此,整個處理包的邏輯應該被串起來了。其實主要是初看程式碼時handlePacket/handlePacketQueue/handleBatchPacket/handleBatchPacketQueue各由誰呼叫,以及在哪個執行緒空間中被呼叫不太好理解。

相關推薦

OceanBase server處理網路邏輯

OceanBase處理網路包的邏輯還是蠻繞的,這裡以UPS為例,作為給自己的備忘。 UPS程式碼的main.cpp中呼叫ObUpdateServerMain的start啟動server。start函式會呼叫ObUpdateServerMain的do_work函式,此函式呼叫ObUpdateServer類

Activity被回收掉之後的網路請求處理方法詳解

想起寫這麼一篇博文的前提是上週去面試了一家公司,其中有這麼一個問題印象深刻,結合當時在網上看到的解決辦法我就說了一個錯誤答案,結果當場就被面試官給指出了錯誤,所以回來後和我的領導一起討論了這麼一個問題,他提出了一個很好地解決思路,於是乎我便寫了這麼一段程式

當Activity關閉後,網路請求處理

當我們在使用網路請求的時候,一般都是通過回撥來獲取請求到的資料。對於網路請求的回撥需要注意的幾個點 比如我們的回撥在Activity中處理資料,當我們把Activity關閉後,如果獲取到資料時,就算我們的Activity被finish回撥還是會執行,那麼這個時候我們在回

Java程式設計之委託代理、內部類以及匿名內部類(閉)

最近一直在看Java的相關東西,因為我們在iOS開發是,無論是Objective-C還是Swift中,經常會用到委託代理回撥,以及Block回撥或者說是閉包回撥。接下來我們就來看看Java語言中是如何實現委託代理回撥以及閉包回撥的。當然這兩個技術點雖然實現起來並不困難,但是,這回調在封裝一些公用元件時還是特別

JS閉的理解

最近工作很不順心啊,遇到問題解決不了真的好煩啊,好煩啊。 不過看到一個有意思的東西,自己做了些擴充覺得還不錯。分享給大家。 var name = "The Window"; var object = { name : "My Object", getN

es6裡面處理多層的多種方法及其缺點

const fs = require('fs'); //第一種的常用的回撥函式,本身沒有什麼問題,但是問題是出現多個回撥函式的巢狀式時,會形成回撥地獄,既不利於讀也不利於管理 function fn() { fs.readFile('./req.html',(

Swift3.0通過閉傳遞引數 / @escaping

//載入請求資料 func loadData(completion: @escaping (_ result:[String]) -> ()) -> () { DispatchQueue.global().async {

要營運VOS、Astgo等VOIP網路電話系統,必須要自己掌握的基本技術

1、知道什麼是centos,分為64位和32位系統。 2、知道怎麼遠端訪問centos伺服器 (常用工具 Secure Shell Client、WINSCP) 3、知道重啟伺服器的命令是 reb

Dubbo 用服務的處理邏輯

處理方式 以Netty為例,首先在初始化NettyClient或者NettyServer的時候,根據URL中的codec引數選擇具體的codec類,預設使用DubboCountCodec類。 在啟動Netty客戶端或者服務端的時候在Netty的pipeline中添加了編解

Activity被回收掉之後的網路處理

早上來到公司剛開啟電腦,就被叫到會議室,召開緊急會議,線上出現重大bug,根據線上日誌統計,崩潰率上升了0.3個百分點(我們專案是集成了騰訊Bugly統計日誌,有興趣的同學可以去了解下)。 這個可不得了,聽說領導被老闆叫過去訓了好久,領導憋了一肚子火,我們的日

Android RxJava 實戰系列:優雅實現 網路請求巢狀

轉自-----http://blog.csdn.net/carson_ho/article/details/78315696,請為大神打call 前言 Rxjava,由於其基於事件流的鏈式呼叫、邏輯簡潔 & 使用簡單的特點,深受各大 Android

java 的 基本使用場合 和 講解 以及 HttpUtil邏輯封裝

回撥 邏輯圖 HttpCallbackListener 介面,也就是 耗時操作結束後返回給 呼叫方 的通道 public interface HttpCallbackListener { void onFinished(String response); voi

php5.6 微信退款處理(AES-256-ECB+PKCS7Padding)

微信退款的回撥中有個欄位是req_info。該欄位微信官方給的解密方法是: 解密步驟如下:  (1)對加密串A做base64解碼,得到加密串B (2)對商戶key做md5,得到32位小寫key* ( key設定路徑:微信商戶平臺(pay.weixin.qq.com)-->

處理微信支付的非同步

/** * 微信支付非同步回撥(只有非同步回撥對訂單進行處理) */ public function wchatUrlBack() { $postStr = file_get_contents('php://input'); i

Android RxJava操作符的學習---變換操作符---網路請求巢狀

變換操作符的主要開發需求場景 = 巢狀回撥(Callback hell) 下面,我將採用一個實際應用場景例項來講解巢狀回撥(Callback hell) 1. 需求場景 1.1 背景 需要進行巢狀網路請求:即在第1個網路請求成功後,繼續再進行一次網路請求 如

總結-全域性環境&執行流程&錯誤型別&垃圾回收機制&閉&函式&函式

全域性環境&執行流程&錯誤型別&垃圾回收機制&閉包&函式&回撥函式 全域性環境 1.函式中的this表示改函式所屬的物件 2.window物件的成員在呼叫時可以省略window 執行流程 1.編譯程式碼:當前script程式碼段

Qt程式出現(ig9icd64.dll) (XXXXX.exe 中)處有未經處理的異常: 0xC000041D: 使用者期間遇到未經處理的異常。。

我也是被自己逼瘋了,中午還在一邊執行程式,一邊寫部落格。休息了一會,再執行程式,發現好好地程式居然跑不起來(估計也是去休息了),居然出現這個bug。 於是下午進行了各種除錯,註釋程式碼,最終確定了問題在QOpenGLWidget裡面。但是這個我也動不了,於是再次找原因,找啊找,找了一下

一文搞懂:詞法作用域、動態作用域、函式、閉

不管什麼語言,我們總要學習作用域(或生命週期)的概念,比如常見的稱呼:全域性變數、包變數、模組變數、本地變數、區域性變數等等。不管如何稱呼這些作用域的範圍,實現它們的目的都一樣: (1)為了避免名稱衝突; (2)為了限定變數的生命週期(本文以變數名說事,其它的名稱在規則上是一樣的)

JavaScript踩坑筆記09---閉函式

閉包: 簡單點說,閉包就是一個倉庫,它的作用就是將我們要用的區域性變數暫時儲存起來。 舉例說明。 // 定義一個函式fn,其中有一個區域性變數num function fn() { var num = 10; } 以上例子中,我們在函式fn中定義了一個變數num,所以變數的n

php陣列元素的遍歷與處理

/** * 陣列函式__回撥處理 * 1.array_filter($arr, $callback):用回撥過濾陣列 * 2.array_walk(&$arr, $callback($val,$key,$data),$data的值) */   /** * 一、array_f