RPC封裝需要注意的一些技術細節

2021-09-12 22:57:28 字數 2064 閱讀 8872

rpc(remote procedure call,即遠端過程呼叫)是建立在socket之上的,在一台機器上執行的主程式,可以呼叫另一台機器上準備好的子程式,就像lpc(本地過程呼叫)。也就是說兩台伺服器a,b,乙個應用部署在a伺服器上,想要呼叫b伺服器上應用提供的函式/方法,由於不在乙個記憶體空間,不能直接呼叫,需要通過網路來表達呼叫的語義和傳達呼叫的資料。對於rpc架構來說,應用越底層,**越複雜、靈活性越高、效率越高;應用越上層,抽象封裝的越好、**越簡單、效率越差。

通過rpc,我們可以充分利用非共享記憶體的多處理器環境(例如通過區域網連線的多台應用伺服器),這樣可以簡便地將你的應用分布在多台應用伺服器上,應用程式就像執行在乙個多處理器的計算機上一樣。我們可以方便的實現過程**共享,提高系統資源的利用率,也可以將以大量數值處理的操作放在處理能力較強的系統上執行,從而減輕前端機的負擔。

rpc方法的基本原則:

以模組呼叫的簡單性忽略通訊的具體細節,以便程式設計師不用關心c/s之間的通訊協議,集中精力實現應用過程。

由於rpc基本原則的影響,決定了 rpc生成的通訊包不可能對每種應用都有最恰當的處理辦法,與socket方法相比,傳輸相同的有效資料,rpc占用更多的網路頻寬。rpc是在socket的基礎上實現的,它比socket需要更多的網路和系統資源。

可以通過**來遠端呼叫。

分為兩種**:

(1)jdk動態**。jdk**的方式是對介面做**,所以必須先定義介面,只需簡單地指定一組介面及目標類物件就能動態的獲得**物件。

(2)位元組碼生成。位元組碼生成方式一般使用的是cglib**,cglib**使用的是asm位元組碼框架,可以直接對類生成**物件。雖然位元組碼生成的方式更加方便和高效,但是由於**維護不易,一般還是採用jdk動態**的方式。

通訊的第一步就是要確認客戶端和伺服器相互通訊的訊息結構。

呼叫編碼:

(1)介面方法:包括介面名、方法名

(2)方法引數:包括引數型別、引數值

(3)呼叫屬性:包括呼叫屬性資訊,例如呼叫附件隱式引數、呼叫超時時間等

返回編碼:

(1)返回結果:介面方法中定義的返回值

(2)返回碼:異常返回碼

(3)返回異常資訊:呼叫異常資訊

序列化型別包括基於文字和基於二進位制方式。在分布式服務通訊框架中,序列化方式應該包含以下特性:

(1)通用性:比如能否支援map等複雜資料結構

(2)效能:包括時間複雜度和空間複雜度,通訊框架被會公司全部服務使用,即使效能提公升一點也會引起質變

(3)可擴充套件性:比如支援自動增加新的業務字段

(4)多語言支援:通過定義idl,生成方式為靜態編譯和動態編譯

通訊框架需要支援同步阻塞io(bio)和非同步非阻塞io(nio)方式,一般底層使用netty。

bio:使用serversocket繫結ip位址和監聽埠,客戶端發起連線,通過三次握手建立連線,用socket來進行通訊,通過輸入輸出流的方式來進行同步阻塞的通訊。每次客戶端發起連線請求,都會啟動乙個執行緒。

nio:使用多路復用器selector來輪詢每個通道channel,當通道中有事件時就通知處理,不會阻塞,使用較複雜。

如果請求是非同步的,對於客戶端來說請求發出後執行緒即可向下執行。服務端處理完成後再以訊息的形式傳送給客戶端。於是這裡會出現以下兩個問題:

(1)如何讓當前執行緒「暫停」,等待到結果後,再向後執行

(2)如果多個執行緒同時進行遠端方法呼叫,這時建立在client server之間的socket連線上會有很多雙方傳送的訊息傳遞,前後順序也可能是隨機的,server處理完結果後將結果傳送給client,client收到很多的訊息,無法知道哪個訊息是原先哪個執行緒所呼叫的。

那麼這時可通過唯一自增的乙個請求id來解決這兩個問題:在呼叫callback的get方法時,在get內部獲取callback的鎖,如果沒有獲取就等待;以請求id為key將callback物件存放在全域性concurrenthashmap中,先通過請求id獲取callback物件,然後再獲取callback的鎖,獲取之後再呼叫notify。

foreach 一些需要注意的地方

通常迴圈訪問陣列都用for迴圈 例如 for i 0 i i 3 i echo arr i 但通過手工 操作乙個大陣列來說,用foreach迴圈的 更少 上面的 可以這樣寫 foreach arr as value echo value 下面來仔細 下foreach使用中的一些問題 1.foreac...

使用namespace需要注意的一些東西

使用c 標準庫的任何識別符號,一般來說有三種選擇,但是using directive有時候會出現問題。首先using namespace std這種用法並不會導致效能上的變化。而是在程式比較大的時候,會出現意外的名稱衝突。例如使用如下的形式 using namespace a using names...

使用SQL SERVER需要注意的一些細節

養成寫注釋的習慣。比如儲存過程,我們不僅在建立儲存過程的時候寫注釋,而且是以後的開發版本中修改了儲存過程,那麼也要寫注釋。儲存過程不要以sp 開頭,因為系統儲存過程都是以sp 開頭的。而且在執行sp 開關的儲存過程時資料庫引擎首先在master資料庫中查詢這個儲存過程,如果找不到,再去其它資料庫查詢...