c#網絡傳輸

接着前面簡單講的,給大家聊聊服務開發。

網絡傳輸

先說網絡傳輸開發,總體來說,可以看成4中模型

我們把傳輸過程看做網線,那麼在通過傳輸的過程中。2邊就涉及池化問題,也就是我們常見的異步傳輸。

在業務端,有N個線程將數據放到池中(矩形),然後“網線”處有M個線程將數據丟到網絡上。對於2邊都是。

對於最上面的那種模型,M=0,也就是我們常見的一端直接發送,一端接收。也就是一對一的同步應用,直到演化成最後一種。

最後一種,在實現上,大概就是2類,一類是事件回調通知,一類是池中數據控制量,來傳遞數據。

傳輸組件dotnetty

不想多說,網上都有,只簡單提下。以TCP爲例,它在幹什麼。N個線程負責接收連接(簡單理解成收取連接的socket),M個線程來處理這些Socket,檢查是否有數據,當按照註冊的解析Hander,接收完成一包數據,則通過PIP傳遞處理。這樣就簡化了數據接收的過程,可以控制線程。

   我們自己一般寫一對一同步處理時,就是必須線程接收連接,連接以後收取數據(很多時候我們是同步收取,這樣有多少連接就佔用多少線程)。dotnetty這樣做就能控制好線程使用情況。但是數據收取會相對於同步延遲一點點。另外就是這樣實現其實就是異步事件了,好,到此打住,具體使用和遇到問題解決方法,網上有,java的netty不僅僅是個傳輸組件,還養活了很多書籍呢(哈哈哈哈)。有問題就去搜搜,按照java的處理方式都可以的,比較是照搬實現過程的。

    最後說說使用,網上全部是給的官網例子,我就不多說了。我想說的是,作爲傳輸,我們使用時肯定會去封裝的,那麼如何去使用就需要根據業務了,但是無法是2分小類,一個小類是在業務Hander裏面就直接調用我們的業務處理類,另外就是在業務Hander裏面通過事件回調的方式,把數據傳出來,而整個業務hander僅僅是傳輸層的一部分。而我喜歡把傳輸完全隔離處理,業務hander裏面通過事件回調。

  當然,整個dotnetty就是上面模型中的“網線”。至於網線內部又是怎麼實現,又是另外的一個說法了。

同步構造實現

   既然上面的全部是異步的,有還有業務層的交互,所以在業務層上又有很多不同。以我前寫的數據庫查詢服務化爲例。

  我把上面的“網線”轉成了dotnetty,那要實現很好的RPC模式怎麼弄?先看下圖:

逐步說明下。

1.業務層將數據丟下來,也就是我們調函數,返回需要函數返回,這時中間有一個類,來構造一個請求結構,其實簡單理解成保持參數,然後使用AutoResetEvent阻塞起來。這個類暫時叫Adapter。它負責產生一個ID,等待數據返回後匹配AutoResetEvent。

2.Adapter將需要傳遞的數據傳遞給客戶端管理類。客戶端管理類工作有好幾個,第一個就是臨時存儲數據,也就是池數據。

管理類要找到合適的客戶端,爲什麼說合適?這裏考慮了負載均衡和多個連接。

 對於服務,可以有多個部署,這裏加入有N個地址,每一個服務還可以有多個連接啊,假設每個服務有M個連接,這樣客戶端管理類就需要從這N*M個連接中找到比較合適的一個傳遞數據。後面我再說我是如何處理的。

管理類還有一個工作就是驗證客戶端連接情況,爲什麼,我是假動態實現的。當我需要傳遞數據時,會首先初始化一個連接,當這個連接提交的數據量很大時,就開啓新的一個。當所有客戶端都停下來沒有數據提交,則就浪費網絡資源了,所以還得關閉。這裏我是按照5分鐘沒有數據提交就關閉了連接。

  另外一個問題是網絡異常,dotnetty是異步回調,加上前面的功能,是沒法很快知道網絡是異常的,客戶端不能提交還是客戶端自己在關閉,所以需要客戶端管理區驗證網絡異常,不能連接。

  根據前面的內容,客戶端管理類主要體現了四個功能:數據緩存,客戶端選擇,網絡異常檢查,客戶端實時關閉。

   接着前面,假設服務有N個,M個連接,那麼就按照客戶端空閒和數據提交頻率來選擇,首先選擇空閒的,然後選擇客戶端提交頻率最小的。

  當然我實現的更加複雜,還有數據處理,從池中取數據,比如池中數據每超過1000個,就多開啓一個線程去重池中抽取數據網客戶端丟。還有網絡異常時存儲文件等功能就是有這個管理類來操作的。另外這個是單例,我們的功能可能不只一個,比如一個功能是傳文件,一個是發數據消息,其實就是2類服務,所以管理類中還要分門別類往服務端提交。

3.同樣在服務端也就差不多的對等功能。

不知道大家明白沒有,其實上面那幅圖是在流程上的,代碼上的實現關係應該是下面這樣的:

 

這就是異步傳輸組件要構造RPC模型的效果和過程。

例子數據庫查詢服務

我以前寫了一個查詢數據庫服務化,現在重新按照上面的邏輯更新了。可以調試。

當然這裏面有業務邏輯。整個服務傳輸加密了。簡單說下,前面的博文已經介紹了。

服務端產生RSA祕鑰。

 客戶端首先需要登錄驗證,一個字符串的MD5。從服務端獲取RSA的公鑰,同時服務端爲客戶端分配一個sessionid.

客戶端自己參數AES加密的祕鑰。用AES把傳輸的  byte[]加密,然後用RSA的公鑰對自己的AES祕鑰加密,然後構造一個協議傳輸,協議中還必須有前面的sessionid。服務端接到數據請求,先檢查sessionid還有沒有效,如果沒有則返回錯誤信息要求從新登錄一次,再次獲取RSA公鑰。如果有效 則服務端按照協議解析AES祕鑰,然後再用祕鑰解析傳輸的數據部分。

服務端每天清理一次sessionid,所以客戶端每天都必須登錄一次。

客戶端每一個小時更新一次AES祕鑰。

大概這個查詢服務就是這樣的了。

整個就給大家演示了異步編程開發,數據提交處理,異步構造RPC模式的過程,數據加密傳輸的過程,包括一些資源調度和處理,網絡上的負載均衡(不是我們一般說的數據負載均衡,或者說這裏是資源動態調優吧)。

其中NettyTransmission項目就是dotnetty的使用和封裝處理。

代碼在git上,再重複說下地址:

https://github.com/jinyuttt/DBAcessSrv.git

 

 

 

 

 

 

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