服務(wù)器通信

  • 互聯(lián)網(wǎng)應(yīng)用中各個(gè)組成部分的協(xié)作方式
  • 客戶端與服務(wù)端通信方式
  • 服務(wù)器之間通信方式
  • 工程實(shí)踐中的問題和解決方案

服務(wù)器S和客戶端C僅僅是角色

image.png

CS通信

CS的連接方式是使用socket建立連接來進(jìn)行數(shù)據(jù)交互,數(shù)據(jù)交互的過程分為:

  1. Server創(chuàng)建socket,監(jiān)聽(listen)特定端口(ip+port)
  2. Client創(chuàng)建socket,連接到Server監(jiān)聽的端口
  3. Server接收Client連接,創(chuàng)建socket與之進(jìn)行通信
  4. Client和Server進(jìn)行數(shù)據(jù)交互
  5. Client和Server斷開連接回收資源
網(wǎng)頁訪問的數(shù)據(jù)交互

傳輸協(xié)議

  • UDP 可靠性要求不高、小數(shù)據(jù)量、性能更佳
  • TCP 可靠、適合大數(shù)據(jù)量、頻繁交互的

案例分析

PC上QQ的CS交互

  • 一般情況下 UDP
  • 網(wǎng)絡(luò)情況差 TCP
  • 拉去圖片等大文件 TCP

手機(jī)上微信的CS交互(有錢了)

  • 前臺(tái)運(yùn)行時(shí):TCP長連接
  • 后臺(tái)運(yùn)行時(shí):TCP短鏈接
  • 查看文章等:HTTP(TCP短鏈接)

應(yīng)用層協(xié)議

  • 從傳輸層拿到的原始數(shù)據(jù),應(yīng)該如何使用?
  • 字符串
  • 自定義
  • protobuf
  • 序列化和反序列化
數(shù)據(jù)包格式

UDP的分包

假設(shè)每個(gè)分片丟包概率為10%,每個(gè)數(shù)據(jù)包有3次重發(fā)的邏輯。 如果發(fā)送一個(gè)10K數(shù)據(jù)包,成功的概率是多少呢?如果發(fā)送10個(gè)1K的數(shù)據(jù)包,全部成功的概率是多少呢?

UDP的分片MTU為1480,由于還包含8字節(jié)的包頭,實(shí)際上應(yīng)該是1472。

10K的數(shù)據(jù)可以劃分為7個(gè)分片,單次成功概率為90%^7=47.8%。 再經(jīng)過3次重發(fā)修正,最終成功概率為(1-47.8%)^3=86%。

10個(gè)1K的數(shù)據(jù)包相當(dāng)于10個(gè)分片,單包成功概率(1-10%)^3=99.9%。 最終全部成功的概率為99.9%^10=99.9%。

雖然成功的概率相差不大,但是失敗的概率卻相差了14倍。 另外UDP中不要讓單個(gè)包的數(shù)據(jù)量超過1K。

設(shè)計(jì)CS交互時(shí)的問題

case1: 客戶端收到的數(shù)值總是跟服務(wù)器對(duì)不上
可能是字節(jié)序問題,有的不同CPU在不同的OS上字節(jié)序可能不同, 可通過字節(jié)序轉(zhuǎn)換來解決。
在將數(shù)據(jù)發(fā)送到網(wǎng)絡(luò)前,會(huì)對(duì)數(shù)據(jù)包做一次字節(jié)序轉(zhuǎn)換,轉(zhuǎn)換成網(wǎng)絡(luò)字節(jié)序,網(wǎng)絡(luò)字節(jié)序是一個(gè)BIG ENDING的。

case2: 服務(wù)器下發(fā)的小包數(shù)據(jù),客戶端常常延遲一段時(shí)間才收到。

服務(wù)器下發(fā)的小包數(shù)據(jù) 客戶端常常會(huì)延遲一段時(shí)間才收到,一般會(huì)延遲200ms。網(wǎng)絡(luò)良好時(shí)發(fā)送大包時(shí)經(jīng)常隔個(gè)十幾毫秒就收到了。原因是nagle算法延遲導(dǎo)致小包延遲發(fā)送,nagle算法是小包不是立即發(fā)送而是先緩存起來,等其他包過來時(shí)再一起發(fā)送,或者等超時(shí)才發(fā)送。 在一些延遲比較敏感的應(yīng)用中, 可以禁用nagle算法。

case3: 實(shí)時(shí)交互中數(shù)據(jù)量較大或網(wǎng)絡(luò)波動(dòng)較大時(shí)容易發(fā)送失敗

實(shí)時(shí)交互中數(shù)據(jù)量較大或網(wǎng)絡(luò)抖動(dòng)比較厲害, 例如平常單個(gè)玩家在地圖上跑來跑去或打個(gè)怪什么的,這時(shí)數(shù)據(jù)量是很小的。但如果幾百個(gè)玩家聚集在一起,每個(gè)人動(dòng)一下或喊一聲話,那數(shù)據(jù)量會(huì)瞬間變得非常大, 此時(shí)發(fā)送的數(shù)據(jù)超過接收容量, 導(dǎo)致發(fā)送的緩沖區(qū)爆滿,傳輸速度變慢。此時(shí)會(huì)導(dǎo)致客戶端斷掉等各種問題,解決的方案是適當(dāng)?shù)匕l(fā)送緩沖加大一點(diǎn)兒。注意的是適當(dāng)?shù)丶哟?,一般是1M或2M左右。

要點(diǎn)

為什么要使用非阻塞的IO呢?為什么要把socket設(shè)計(jì)成non-blocking呢。因?yàn)橐粋€(gè)服務(wù)器是為好多個(gè)客戶當(dāng)一起去服務(wù)的,如果使用阻塞IO的話,客戶端發(fā)送一個(gè)數(shù)據(jù)過來,那么數(shù)據(jù)庫就會(huì)直接卡在那里了。如果在客戶端沒有上行的數(shù)據(jù)的時(shí)候, 服務(wù)器一直處于等待狀態(tài),后續(xù)操作無法進(jìn)行。而非阻塞IO是如果receive沒有的話服務(wù)器會(huì)馬上返回。

多路復(fù)用主要是檢測(cè)文件與描述符的狀態(tài)變化, 用于提高運(yùn)行效率。不用針對(duì)每個(gè)描述符 ,例如很多個(gè)socket,不用去一個(gè)個(gè)去檢查。 而是可以采取各種方式
(select、poll、epoll)找出里面那些有狀態(tài)變化了,有數(shù)據(jù)來了或者可以繼續(xù)給它追加數(shù)據(jù)了。

服務(wù)器上的通信方式

服務(wù)器上的通信方式

從客戶端client這邊來說,它看到的可能就只有一個(gè)接入服務(wù)器,它并不知道后面有一個(gè)很龐大的服務(wù)器組。
在簡(jiǎn)化的游戲服務(wù)器架構(gòu)中,有一個(gè)連接服務(wù)器、一個(gè)世界服務(wù)器以及很多個(gè)scene,以及其他的logicsvr等。這些服務(wù)器之間有什么特點(diǎn)呢?有的服務(wù)器是在同一個(gè)物理機(jī)上的,也有可能在不同物理機(jī)上 ,所以它們的交互方式會(huì)更為多樣一點(diǎn)兒。

服務(wù)器之間SS的連接方式

  • TCP:最為常用
  • UDP:非關(guān)鍵數(shù)據(jù)上報(bào)(如在線)、日志服務(wù)
  • 非socket通信
    進(jìn)程間通信除了socket之外還有管道pipe、signal、shm、message queue、file。

UDP協(xié)議使用時(shí)數(shù)據(jù)包不要定太大一般不要超過1K,而在進(jìn)程間通信一般在內(nèi)網(wǎng)環(huán)境中,是可以超過這個(gè)MTU設(shè)定值的。這樣的話,不用在協(xié)議層去做分包邏輯。UDP本身包的最大限制是64KB,還需要剪掉一個(gè)IP包頭,再減去一個(gè)UDP包頭,減下來也就不到64KB了。

用戶登錄老是登錄不上,或者登陸上去后,玩一下就會(huì)斷掉,會(huì)是什么原因呢?

  • 最有可能是網(wǎng)路狀況不佳
  • 連接錯(cuò)了接入服務(wù)器
    國內(nèi)的網(wǎng)絡(luò)環(huán)境比較特殊,存在多個(gè)網(wǎng)絡(luò)運(yùn)營商,而且運(yùn)營商之間的交互式比較差的,有可能是一個(gè)電信的用戶連入了聯(lián)通的一個(gè)接入點(diǎn),就會(huì)出現(xiàn)經(jīng)常卡頓或斷線等各種問題。
  • 服務(wù)器的網(wǎng)路故障
    如網(wǎng)卡燒掉了或網(wǎng)線弄斷了
  • 數(shù)據(jù)同步量太大
  • 服務(wù)器卡頓
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 1、TCP為什么需要3次握手,4次斷開? “三次握手”的目的是“為了防止已失效的連接請(qǐng)求報(bào)文段突然又傳送到了服務(wù)端...
    杰倫哎呦哎呦閱讀 3,656評(píng)論 0 6
  • 運(yùn)輸層協(xié)議概述 從通信和信息處理的角度看,運(yùn)輸層向它上面的應(yīng)用層提供通信服務(wù),它屬于面向通信部分的最高層,同時(shí)也是...
    srtianxia閱讀 2,762評(píng)論 0 2
  • 個(gè)人認(rèn)為,Goodboy1881先生的TCP /IP 協(xié)議詳解學(xué)習(xí)博客系列博客是一部非常精彩的學(xué)習(xí)筆記,這雖然只是...
    貳零壹柒_fc10閱讀 5,195評(píng)論 0 8
  • 網(wǎng)絡(luò)編程 一.楔子 你現(xiàn)在已經(jīng)學(xué)會(huì)了寫python代碼,假如你寫了兩個(gè)python文件a.py和b.py,分別去運(yùn)...
    go以恒閱讀 2,246評(píng)論 0 6
  • 何為 socket ? 網(wǎng)絡(luò)上的兩個(gè)程序通過一個(gè)雙向的通信連接實(shí)現(xiàn)數(shù)據(jù)的交換,這個(gè)連接的一端稱為一個(gè)socket。...
    大王叫我來巡山_Cong閱讀 4,998評(píng)論 3 14

友情鏈接更多精彩內(nèi)容