我的感受序列化簡單來講就是按必定規則組包。反序列化就是按組包時的規則來接包。正常來講。序列化不會很難。不會很複雜。由於過於複雜的序列化協議會致使較長的解析時間,這可能會使得序列化和反序列化階段成爲整個系統的瓶頸。就像壓縮文件、解壓文件,會佔用大量cpu時間。php
說序列化以前先說下平臺給序列化分配的buf的空間大小前端
oCntlInfo.setOperatorUin(10458); oCntlInfo.setOperatorKey("abcde"); oCntlInfo.setRouteKey(1234); std::string source = "aaaaa"; std::string inReserve; std::string errmsg; std::string outStr; std::string machineKey; for(int i =0;i<500*1024;i++) { machineKey.append("a"); } AoActionInfo oActionInfo; oActionInfo.SetDisShopId(1111); oActionInfo.SetDistributorId(2222); uint32_t dwResult = Stub4App.AddActionSupplier( oCntlInfo, machineKey, source, 1, 1, oActionInfo, inReserve, errmsg, outStr); if(dwResult == 0) { std::cout << "Invoke OK!" << std::endl; std::cout << "Invoke OK!" << std::endl; }
客戶端直接調用函數接口。到服務端請求結果c++
函數的入參都是咱們須要序列化的內容。注意這裏是rpc調用的一個關鍵點。編程
a) 先看下咱們的thritf服務器
若是下圖。發現咱們的函數入參也是打上了tag標誌的。做用跟咱們在結構體中打tag標誌是同樣的。爲了標識一個字段的含義。session
序列化的時候把這些tag序列化進去。 而後反序列化的時候靠這些tag來解析多線程
b ) 先把圖貼出來。按着圖來說更清晰些app
CByteStream(
char
* pStreamBuf = NULL, uint32_t nBufLen = 0,
bool
bStore=
true
,
bool
bRealWrite =
true
);
1)int32_t* pLen = (int32_t*)bs.getRawBufCur(); 2)bs << 0; 3)int32_t iLen=bs.getWrittenLength(); 4)Serialize_w(bs); 5)*pLen = bs.getWrittenLength() - iLen;
f)最後對整個_Cao_action_AddActionSupplier_Req寫了兩個字節的包尾函數
其實咱們能夠看到咱們的這種序列化,很整齊。很規則。比較緊湊。可是並不節省空間。這個裏面有不少數據能夠壓縮的。可是壓縮帶來一個問題就是解壓的時候很消耗cpu的。跟個人業務場景不服和。也不必。ui
其實知道了數據是怎麼寫入的 解析起來就很容易了。其實這種序列化就是兩邊約定規則。知道規則之後就能夠解析了
解析的具體步驟就不詳細說了。這裏說下解析的時候幾個特殊的地方
咱們的這一套就是遠程調用rpc服務。經過咱們的序列化。
其實就能瞭解所謂的RPC服務是什麼樣的。
說白了,遠程調用就是將對象名、函數名、參數等傳遞給遠程服務器,服務器將處理結果返回給客戶端。
爲了能解析出這些信息。在入參的時候作上標識(這裏是打tag).
谷歌的protobuf也用過。跟thrift其實差很少可是序列化和反序列的話的具體實現是有些不一樣的。
谷歌的protobuf更節省空間
之前具體看過序列化的源碼。以爲序列化反序列化以及rpc很神祕。如今看了源碼才發現確實寫的確實好,
可是沒那麼神祕裏。其實就是按必定規則組包。因此仍是要多看源碼啊。
咱們用的thrift就是 facebook的thrift。可是改了些東西。大致是同樣的。