Java IO知識(shí)圖譜
1 OSI七層網(wǎng)絡(luò)模型
上下層之間遵循的約定叫做"接口"脉课,同層之間遵循的約定叫做"協(xié)議".
- 物理層
- 定義物理設(shè)備標(biāo)準(zhǔn)目养,模數(shù)轉(zhuǎn)換與數(shù)模轉(zhuǎn)換俩由,這一層數(shù)據(jù)叫做比特。
- 數(shù)據(jù)鏈路層
- MAC地址封裝與解封癌蚁,這一層數(shù)據(jù)叫做幀幻梯,數(shù)據(jù)通過交換機(jī)傳輸兜畸。
- 網(wǎng)絡(luò)層
- IP地址封裝與解封,這一層數(shù)據(jù)叫做數(shù)據(jù)包碘梢,這一層設(shè)備是路由器咬摇。
- 傳輸層
- 定義了傳輸協(xié)議和端口號(hào),這一層數(shù)據(jù)叫做段煞躬,TCP肛鹏、UDP
- 會(huì)話層
- 數(shù)據(jù)傳輸通道
- 表示層
- 對(duì)接收數(shù)據(jù)進(jìn)行解釋、加解密恩沛、解壓縮等
- 應(yīng)用層
- 終端應(yīng)用
2 TCP/IP四層模型
- 網(wǎng)絡(luò)接口層/數(shù)據(jù)鏈路層
- 網(wǎng)絡(luò)層
- IP
- 傳輸層f
- TCP在扰、UDP
- 應(yīng)用層
- HTTP、DNS雷客、FTP健田、TELNET、SMTP
3 HTTP報(bào)文結(jié)構(gòu)&TCP數(shù)據(jù)包
HTTP報(bào)文結(jié)構(gòu)
- 報(bào)文首部
- 請(qǐng)求行
- 響應(yīng)行
- 首部字段
- 請(qǐng)求首部字段
- 響應(yīng)首部字段
- 通用首部字段
- 實(shí)體首部字段
- 其它
- 報(bào)文主體
TCP數(shù)據(jù)包結(jié)構(gòu)
- 源端口號(hào)( 16 位):它(連同源主機(jī) IP 地址)標(biāo)識(shí)源主機(jī)的一個(gè)應(yīng)用進(jìn)程佛纫。
- 目的端口號(hào)( 16 位):它(連同目的主機(jī) IP 地址)標(biāo)識(shí)目的主機(jī)的一個(gè)應(yīng)用進(jìn)程妓局。這兩個(gè)值加上 IP 報(bào)頭中的源主機(jī) IP 地址和目的主機(jī) IP 地址唯一確定一個(gè) TCP 連接。
- 順序號(hào)seq( 32 位):用來標(biāo)識(shí)從 TCP 源端向 TCP 目的端發(fā)送的數(shù)據(jù)字節(jié)流呈宇,它表示在這個(gè)報(bào)文段中的第一個(gè)數(shù)據(jù)字節(jié)的順序號(hào)好爬。如果將字節(jié)流看作在兩個(gè)應(yīng)用程序間的單向流動(dòng),則 TCP 用順序號(hào)對(duì)每個(gè)字節(jié)進(jìn)行計(jì)數(shù)甥啄。序號(hào)是 32bit 的無符號(hào)數(shù)存炮,序號(hào)到達(dá) 2 的32次方 - 1 后又從 0 開始。當(dāng)建立一個(gè)新的連接時(shí)蜈漓, SYN 標(biāo)志變 1 穆桂,順序號(hào)字段包含由這個(gè)主機(jī)選擇的該連接的初始順序號(hào) ISN ( Initial Sequence Number )。
- 確認(rèn)號(hào)ack( 32 位):包含發(fā)送確認(rèn)的一端所期望收到的下一個(gè)順序號(hào)融虽。因此享完,確認(rèn)序號(hào)應(yīng)當(dāng)是上次已成功收到數(shù)據(jù)字節(jié)順序號(hào)加 1 。只有 ACK 標(biāo)志為 1 時(shí)確認(rèn)序號(hào)字段才有效有额。 TCP 為應(yīng)用層提供全雙工服務(wù)般又,這意味數(shù)據(jù)能在兩個(gè)方向上獨(dú)立地進(jìn)行傳輸。因此巍佑,連接的每一端必須保持每個(gè)方向上的傳輸數(shù)據(jù)順序號(hào)茴迁。
- TCP 報(bào)頭長度( 4 位):給出報(bào)頭中 32bit 字的數(shù)目,它實(shí)際上指明數(shù)據(jù)從哪里開始萤衰。需要這個(gè)值是因?yàn)槿芜x字段的長度是可變的堕义。這個(gè)字段占 4bit ,因此 TCP 最多有 60 字節(jié)的首部脆栋。然而倦卖,沒有任選字段洒擦,正常的長度是 20 字節(jié)。
- 保留位( 6 位):保留給將來使用糖耸,目前必須置為 0 秘遏。
- 控制位( control flags 拷沸, 6 位):在 TCP 報(bào)頭中有 6 個(gè)標(biāo)志比特限匣,它們中的多個(gè)可同時(shí)被設(shè)置為 1 。依次為:
? URG :為 1 表示緊急指針有效毡熏,為 0 則忽略緊急指針值舍扰。
? ACK :為 1 表示確認(rèn)號(hào)有效倦蚪,為 0 表示報(bào)文中不包含確認(rèn)信息,忽略確認(rèn)號(hào)字段边苹。
? PSH :為 1 表示是帶有 PUSH 標(biāo)志的數(shù)據(jù)陵且,指示接收方應(yīng)該盡快將這個(gè)報(bào)文段交給應(yīng)用層而不用等待緩沖區(qū)裝滿。
? RST :用于復(fù)位由于主機(jī)崩潰或其他原因而出現(xiàn)錯(cuò)誤的連接个束。它還可以用于拒絕非法的報(bào)文段和拒絕連接請(qǐng)求慕购。一般情況下,如果收到一個(gè) RST 為 1 的報(bào)文茬底,那么一定發(fā)生了某些問題沪悲。
? SYN :同步序號(hào),為 1 表示連接請(qǐng)求阱表,用于建立連接和使順序號(hào)同步( synchronize )殿如。
? FIN :用于釋放連接,為 1 表示發(fā)送方已經(jīng)沒有數(shù)據(jù)發(fā)送了最爬,即關(guān)閉本方數(shù)據(jù)流涉馁。 - 窗口大小( 16 位):數(shù)據(jù)字節(jié)數(shù)爱致,表示從確認(rèn)號(hào)開始烤送,本報(bào)文的源方可以接收的字節(jié)數(shù),即源方接收窗口大小蒜鸡。窗口大小是一個(gè) 16bit 字段胯努,因而窗口大小最大為 65535字節(jié)。
- 校驗(yàn)和( 16 位):此校驗(yàn)和是對(duì)整個(gè)的 TCP 報(bào)文段逢防,包括 TCP 頭部和 TCP 數(shù)據(jù),以 16 位字進(jìn)行計(jì)算所得蒲讯。這是一個(gè)強(qiáng)制性的字段忘朝,一定是由發(fā)送端計(jì)算和存儲(chǔ),并由接收端進(jìn)行驗(yàn)證判帮。
- 緊急指針( 16 位):只有當(dāng) URG 標(biāo)志置 1 時(shí)緊急指針才有效局嘁。TCP 的緊急方式是發(fā)送端向另一端發(fā)送緊急數(shù)據(jù)的一種方式溉箕。
13/04/2018 Page 162 of 283 - 選項(xiàng):最常見的可選字段是最長報(bào)文大小,又稱為 MSS(Maximum Segment Size) 悦昵。每個(gè)連接方通常都在通信的第一個(gè)報(bào)文段(為建立連接而設(shè)置 SYN 標(biāo)志的那個(gè)段)中指明這個(gè)選項(xiàng)肴茄,它指明本端所能接收的最大長度的報(bào)文段。選項(xiàng)長度不一定是 32 位字的整數(shù)倍但指,所以要加填充位寡痰,使得報(bào)頭長度成為整字?jǐn)?shù)。
- 數(shù)據(jù): TCP 報(bào)文段中的數(shù)據(jù)部分是可選的棋凳。在一個(gè)連接建立和一個(gè)連接終止時(shí)拦坠,雙方交換的報(bào)文段僅有 TCP 首部。如果一方?jīng)]有數(shù)據(jù)要發(fā)送剩岳,也使用沒有任何數(shù)據(jù)的首部來確認(rèn)收到的數(shù)據(jù)贞滨。在處理超時(shí)的許多情況中,也會(huì)發(fā)送不帶任何數(shù)據(jù)的報(bào)文段拍棕。
4 TCP三次握手~建立連接
- 客戶端:SYN=1晓铆,seq=x
- 服務(wù)端:SYN=1,ACK=1绰播,ack=x+1骄噪,seq=y
- 客戶端:ACK=1,ack=y+1幅垮,seq=x+1
5 TCP四次揮手~關(guān)閉連接
TCP連接是全雙工腰池,數(shù)據(jù)可在兩個(gè)方向上同時(shí)傳遞。單方向的關(guān)閉叫做半關(guān)閉忙芒。
- 客戶端:FIN=1示弓,seq=x,客戶端進(jìn)入FIN-WAIT
- 服務(wù)端:ACK=1呵萨,ack=x+1奏属,seq=y,服務(wù)端進(jìn)入CLOSE-WAIT
- 服務(wù)端:FIN=1潮峦,ACK=1囱皿,ack=y+1,seq=z忱嘹,服務(wù)端進(jìn)入LAST-ACK
- 客戶端:ACK=1添诉,ack=z+1捎稚,seq=x+1宠默,客戶端進(jìn)入TIME-WAIT逝薪,服務(wù)端進(jìn)入CLOSED(被動(dòng)關(guān)閉)
- 客戶端:TIME-WAIT缘琅,等待計(jì)時(shí)器設(shè)置的2MSL(Maximum Segment Lifetime,報(bào)文最大生存時(shí)間)后藤肢,客戶端進(jìn)入CLOSED(主動(dòng)關(guān)閉)
6 客戶端第三次握手發(fā)送ACK后為什么要等待2MSL才關(guān)閉太闺?
- RFC 793 [Postel 1981c] 指出MSL為2分鐘。但在Berkeley的實(shí)現(xiàn)上使用的值為30s嘁圈,實(shí)現(xiàn)中的常用值也有1分鐘省骂,或2分鐘。
- 防止服務(wù)端沒有收到最后一次ACK數(shù)據(jù)包的情況下最住,可以重發(fā)第三次握手的FIN包钞澳;
- 清空鏈路中當(dāng)前客戶端的全部報(bào)文,防止對(duì)后續(xù)產(chǎn)生影響涨缚。
- 可以通過設(shè)置SO_REUSEADDR選項(xiàng)達(dá)到不必等待2MSL時(shí)間結(jié)束再使用此端口轧粟。
7 HTTP/TCP長短鏈接
持久連接
- http是無狀態(tài)的應(yīng)用層協(xié)議,TCP是傳輸層的協(xié)議,說http的長短鏈接其實(shí)指的是TCP的長短鏈接兰吟。
- HTTP1.0不支持長連接通惫,HTTP1.1加入了keep-alive支持長連接(Connection:keep-alive),現(xiàn)在的http協(xié)議都是1.1混蔼,都默認(rèn)支持長連接履腋。設(shè)置Connection: Close可以斷開長連接。
- 一個(gè)TCP連接是否為長連接惭嚣,是通過設(shè)置HTTP的Connection Header來決定的遵湖,而且是需要兩邊都設(shè)置才有效。
- header頭超時(shí)設(shè)置Keep-Alive:timeout=20晚吞,代表20秒超時(shí)延旧。
- 持久連接使得請(qǐng)求以管線化(pipelining)方式發(fā)送成為可能,不用等待響應(yīng)可以直接發(fā)送下一個(gè)請(qǐng)求槽地。
長連接優(yōu)劣
- 長連接優(yōu)點(diǎn):
- 可以省去較多的TCP建立和關(guān)閉的操作迁沫,減少浪費(fèi),節(jié)約時(shí)間闷盔。
- 長連接缺點(diǎn):
- 服務(wù)器端有很多TCP連接時(shí)弯洗,會(huì)降低服務(wù)器的性能。
- 需要管理所有的TCP連接逢勾,檢測是否是無用的連接(長時(shí)間沒有讀寫事件)牡整,并進(jìn)行關(guān)閉等操作。
- 長連接多適用于讀寫操作頻繁溺拱,點(diǎn)對(duì)點(diǎn)的通訊逃贝,而且連接數(shù)不能太多情況。例如:數(shù)據(jù)庫的連接用長連接迫摔, 如果用短連接頻繁的通信會(huì)造成socket錯(cuò)誤沐扳,而且頻繁的socket 創(chuàng)建也是對(duì)資源的浪費(fèi)。
短連接優(yōu)劣
- 短連接優(yōu)點(diǎn):
- 對(duì)于服務(wù)器來說管理較為簡單句占,存在的連接都是有用的連接沪摄,不需要額外的控制手段。
- 短連接缺點(diǎn):
- 但如果客戶請(qǐng)求頻繁纱烘,將在TCP的建立和關(guān)閉操作上浪費(fèi)較多時(shí)間和帶寬杨拐。
- 短連接適用場景:
- 短連接用于并發(fā)量大,且每個(gè)用戶無需頻繁向服務(wù)器發(fā)數(shù)據(jù)包擂啥。 而像WEB網(wǎng)站的http服務(wù)一般都用短鏈接哄陶。因?yàn)殚L連接對(duì)于服務(wù)端來說會(huì)耗費(fèi)一定的資源像,WEB網(wǎng)站這么頻繁的成千上萬甚至上億客戶端的連接用短連接會(huì)更省一些資源哺壶。
8 http請(qǐng)求響應(yīng)流程
- URL地址解析(DNS域名解析)
- 封裝http數(shù)據(jù)包
- 封裝TCP包并建立傳輸連接
- 客戶端發(fā)送請(qǐng)求命令
- 服務(wù)端處理請(qǐng)求
- 客戶端接收服務(wù)端響應(yīng)
- 渲染頁面
- 服務(wù)端關(guān)閉連接
9 http協(xié)議方法和狀態(tài)碼
HTTP1.1使用的方法
- GET
- POST
- PUT
- DELETE
- HEAD
- OPTIONS
- TRACE
- CONNECT
HTTP狀態(tài)碼
- 1**:請(qǐng)求正在處理
- 2**:請(qǐng)求正常處理完畢
- 200:OK
- 204:No content
- 206:范圍請(qǐng)求
- 3**:重定向
- 301
- 302
- 303
- 304
- 307
- 4**:客戶端錯(cuò)誤
- 400:Bad Request
- 401:Unauthorized
- 403:Forbidden
- 404:not found
- 5**:服務(wù)器錯(cuò)誤
- 500:Internal Server Error
- 502:Bad Gateway
- 503:Service Unavailable
- 504:Gateway timeout
10 HTTPS請(qǐng)求過程
HTTPS=HTTP + SSL
- 建立連接獲取證書
- 證書驗(yàn)證
- 數(shù)據(jù)加密與傳輸
11 CDN原理
- DNS智能解析
- DNS解析找到最近的CDN節(jié)點(diǎn)屋吨,將請(qǐng)求轉(zhuǎn)發(fā)到此節(jié)點(diǎn)蜒谤,如果有數(shù)據(jù)直接返回
- 緩存技術(shù)
- 最近CDN節(jié)點(diǎn)無數(shù)據(jù),緩存服務(wù)器就會(huì)去源服務(wù)器查找內(nèi)容至扰,找到了就返回客戶端鳍徽,同時(shí)將數(shù)據(jù)緩存到本地,為后續(xù)訪問提供方便渊胸。
- 分發(fā)服務(wù)系統(tǒng)
- 負(fù)載均衡系統(tǒng)
- 管理系統(tǒng)
12 URI(統(tǒng)一資源標(biāo)識(shí)符) & URL(統(tǒng)一資源定位符) & URN
- URL是URI的子集旬盯,定義web資源訪問方式,不包括資源名
- URN是URI的子集翎猛,用特定命名空間的名稱標(biāo)識(shí)資源,不包括訪問方式
- 比如說URI是http://bitpoetry.io/posts/hello.html#intro
- URL就是http://bitpoetry.io/posts/hello.html
- URN就是bitpoetry.io/posts/hello.html#intro
13 WebSocket底層原理及實(shí)現(xiàn)接剩?
- websocket是第七層即應(yīng)用層上的一個(gè)應(yīng)用層協(xié)議切厘,基于HTML5技術(shù)。
- 握手階段:依賴http協(xié)議進(jìn)行一次握手
- 數(shù)據(jù)傳輸階段:雙工的TCP連接
- 分片傳輸
- 邊生成數(shù)據(jù)邊傳遞消息
- 真正意義的長連接
14 websocket單機(jī)最大可以支撐多少連接懊缺?
- IE:6
- Google chrome:256
- Firefox:200
- Mac safari:1273
- Tomcat的websocket最大連接數(shù):200
15 一個(gè)TCP連接可以對(duì)應(yīng)幾個(gè)http請(qǐng)求疫稿?幾個(gè)http請(qǐng)求可以一起發(fā)送嗎?
- 一個(gè)TCP連接對(duì)應(yīng)多個(gè)http請(qǐng)求
- 幾個(gè)http請(qǐng)求在http1.1不能一起發(fā)送
- RFC 2616認(rèn)為無法根據(jù)多個(gè)結(jié)果判斷請(qǐng)求是哪個(gè)發(fā)的
- HTTP pipelining想解決此問題鹃两,但是瀏覽器默認(rèn)也是關(guān)閉的遗座,因?yàn)橛行┐矸?wù)器不能很好處理pipelining,而且維護(hù)請(qǐng)求順序需要花費(fèi)很多開銷俊扳。
- 多http請(qǐng)求在http2.0可以一起發(fā)送
- HTTP2.0提供了Multiplexing多路傳輸特性
16 瀏覽器對(duì)同一host最多建立多少TCP連接途蒋?
- 受瀏覽器限制,Chrome允許對(duì)同一host最多建立6個(gè)TCP連接馋记。
17 單機(jī)最大TCP連接數(shù)
- 做服務(wù)器端:
- 監(jiān)聽在某些端口号坡,外部來的長連接數(shù)的上限取決于它的CPU,內(nèi)存資源梯醒;
- 做客戶端:
- 端口號(hào)在TCP協(xié)議字段里宽堆,一共兩個(gè)字節(jié),二進(jìn)制的16位茸习,意味著有2^16= 65536個(gè)端口號(hào)可用畜隶,但0-1023系統(tǒng)通常保留為知名服務(wù)端口,所以最多有64512個(gè)端口做為端口池資源号胚。
18 計(jì)算機(jī)網(wǎng)絡(luò)發(fā)展的七個(gè)階段籽慢?
19 各種網(wǎng)絡(luò)體系結(jié)構(gòu)及其協(xié)議?
20 數(shù)據(jù)傳輸方式分類涕刚?
- 面向有連接型與面向無連接型
- 有連接型:發(fā)送方要確認(rèn)接收方打開了連接才能發(fā)送數(shù)據(jù)
- 無連接型:發(fā)送方無需確認(rèn)接收方是否存在嗡综,可以隨時(shí)發(fā)送數(shù)據(jù)
- 電路交換與分組交換
- 電路交換:歷史久遠(yuǎn),比如電話網(wǎng)
- 分組交換/蓄積交換:TCP/IP
- 根據(jù)接收端數(shù)量分類
- 單播:1對(duì)1
- 廣播:1對(duì)N杜漠,比如電視播放
- 多播:1對(duì)N极景,限定接收端是誰察净,比如電視會(huì)議
- 任播:選一臺(tái)作為接收端
21 MAC尋址(地址轉(zhuǎn)發(fā)表)與IP尋址(路由控制表)?
22 網(wǎng)絡(luò)構(gòu)成要素及搭建網(wǎng)絡(luò)的設(shè)備盼樟?
23 TCP/IP的發(fā)展歷史
24 協(xié)議標(biāo)準(zhǔn)化流程
25 TCP/IP協(xié)議族組成氢卡?
26 TCP與UDP異同?
- TCP(Transmission Control Protocol)是面向有連接的可靠傳輸層協(xié)議
- 建立連接要3次握手晨缴、斷開連接要4次揮手译秦;
- 不適用于視頻會(huì)議等多媒體領(lǐng)域場景;
- 可以控制丟包重發(fā)击碗、亂序控制等筑悴;
- 重發(fā)超時(shí)一般設(shè)置為0.5秒的整數(shù)倍,一般設(shè)置為6秒左右稍途;
- TCP提供了滑動(dòng)窗口機(jī)制并行處理提高了網(wǎng)絡(luò)通信的效率阁吝;
- TCP可以通過窗口大小進(jìn)行流控制;
- TCP提高網(wǎng)絡(luò)利用率的手段:
- 使用Nagle算法:發(fā)送端剩余發(fā)送數(shù)據(jù)較少械拍,采用延遲發(fā)送處理機(jī)制
- 延遲確認(rèn)應(yīng)答
- 捎帶應(yīng)答
- UDP(User Datagram Protocol)是利用IP提供面向無連接的非可靠傳輸層協(xié)議
- UDP協(xié)議主要作用是將網(wǎng)絡(luò)數(shù)據(jù)流量壓縮成數(shù)據(jù)包的形式突勇;
- UDP最好在局域網(wǎng)內(nèi)使用,大大減少丟包概率坷虑;
- 可以確保發(fā)送消息的大小甲馋,不關(guān)注對(duì)方是否收到了數(shù)據(jù);
- UDP簡單高效迄损,適用于包總量數(shù)據(jù)較少定躏、多播、廣播以及視頻等即時(shí)多媒體領(lǐng)域場景海蔽,聊天用的ICQ和QQ也是使用UDP協(xié)議共屈;
- UDP不提供復(fù)雜的控制機(jī)制,細(xì)節(jié)的處理會(huì)交給上層應(yīng)用去完成党窜。
27 網(wǎng)絡(luò)拓?fù)?/h1>
- 總線型
- 環(huán)型
- 星型
- 網(wǎng)狀型
28 數(shù)據(jù)鏈路層
29 公共網(wǎng)絡(luò)分類
- 模擬電話線路
- ADSL
- 移動(dòng)通信服務(wù)
- FTTH
- 有線電視
- 專線
- VPN
- 公共無線LAN
- X. 25
- 幀中繼
- ISDN
30 IP地址
- IP尋址
- 路由控制
- IP分包與組包
31 IP為什么要設(shè)計(jì)為面向無連接拗引?
- 簡單化,面向有連接比面向無連接復(fù)雜
- 高速化幌衣,管理連接繁瑣費(fèi)時(shí)矾削,IP要提高速度,需要連接時(shí)委托上層TCP處理豁护。
32 IPv4與IPv6
- IPv4
- 32位正整數(shù)哼凯,分4組,以.分割楚里,最多允許2^32(約43億)臺(tái)機(jī)器聯(lián)網(wǎng)
- 網(wǎng)絡(luò)標(biāo)識(shí) + 主機(jī)標(biāo)識(shí)
- 分配IP地址要去掉全部為0(IP地址無法獲知)和全部為1(廣播地址)的情況
- IP地址分為4類:
- A類:0開頭断部,0.0.0.0~127.0.0.0,后24位為主機(jī)標(biāo)識(shí)班缎,主機(jī)地址上限為16777214
- B類:10開頭蝴光,128.0.0.1~191.255.0.0她渴,后16位為主機(jī)標(biāo)識(shí),主機(jī)地址上限為65534
- C類:110開頭蔑祟,192.168.0.0~239.255.255.0趁耗,后8位為主機(jī)標(biāo)識(shí),主機(jī)地址上限為254(2^8-2)
- D類:1110開頭疆虚,224.0.0.0~239.255.255.255苛败,沒有主機(jī)標(biāo)識(shí),常用于多播
- 廣播地址:主機(jī)地址都是1
- 本地廣播:本地網(wǎng)絡(luò)內(nèi)的廣播
- 直接廣播:不同網(wǎng)絡(luò)之間的廣播
- IPv6
- IPv6是為了解決IPv4地址耗盡的問題径簿,IPv4是32位罢屈,IPv6是128位,最多支持2^128
33 IPv4首部&IPv6首部
34 DNS作用
- 域名解析牍帚,支持IPv4和IPv6
35 ARP原理(Address Resolution Protocol)
- ARP通過IP地址查找到MAC地址儡遮,只支持IPv4,IPv6可以用ICMPv6.
- IP地址和MAC地址缺一不可
36 RARP(Reverse Address Resolution Protocol)
- RARP暗赶,反地址解析協(xié)議,通過MAC地址定位IP地址肃叶。
37 ICMP原理
- 驗(yàn)證網(wǎng)絡(luò)設(shè)置是否正確蹂随、IP包是否成功送達(dá)等,便于網(wǎng)絡(luò)問題診斷因惭。
38 DHCP原理
- DHCP岳锁,Dynamic Host Configuration Protocol,自動(dòng)配置管理IP地址蹦魔,即插即用滨攻。
39 NAT原理
40 提升HTTP傳輸速率的方法沮趣?
- 壓縮傳輸?shù)膬?nèi)容編碼
- gzip(GNU zip)
- compress(UNIX系統(tǒng)的標(biāo)準(zhǔn)壓縮)
- deflate(zlib)
- identity(不進(jìn)行編碼)
- 分塊傳輸編碼
41 內(nèi)容協(xié)商機(jī)制?
內(nèi)容協(xié)商機(jī)制指的是客戶端和服務(wù)器端就響應(yīng)的資源內(nèi)容進(jìn)行交涉,然后提供給客戶端最合適的資源愕鼓。
- 服務(wù)器驅(qū)動(dòng)協(xié)商
- 客戶端驅(qū)動(dòng)協(xié)商
- 透明協(xié)商
42 端到端首部&逐跳首部
- 逐跳首部(Hop-by-hop Header):只對(duì)單次轉(zhuǎn)發(fā)有效,需提供Connection首部字段堪旧。
- Connection
- Keep-Alive
- Proxy-Authenticate
- Proxy-Authorization
- Trailer
- TE
- Transfer-Encoding
- Upgrade
- 端到端首部(End-to-end Header):必須保存在由緩存生成的響應(yīng)中涩禀,必須被轉(zhuǎn)發(fā)。
43 HTTP缺陷&HTTPS優(yōu)勢
HTTP缺陷
- 明文傳輸
- 缺乏身份驗(yàn)證
- 報(bào)文完整性問題咆繁,可能被篡改
https好處
- 加密
- 對(duì)稱加密
- AES讳推,Advanced Encryption Standard
- DES,Data Encryption Standard
- 非對(duì)稱加密
- RSA
- DH(Diffie-Hellman)
- 橢圓曲線
- 身份認(rèn)證
- 證書
- 完整性保護(hù)
- MD5
- SHA
44 HTTP身份認(rèn)證手段
- BASIC基本認(rèn)證
- 安全等級(jí)最低
- DIGEST摘要認(rèn)證
- 安全等級(jí)次低
- SSL客戶端認(rèn)證
- 安全等級(jí)高玩般,證書需要費(fèi)用
- 基于表單認(rèn)證
- Cookie
- Session
- token
45 HTTP增強(qiáng)協(xié)議
- SPDY
- Google開發(fā)的基于TCP協(xié)議的應(yīng)用層協(xié)議银觅,目的是優(yōu)化http協(xié)議的性能,核心思想是減少TCP連接數(shù)坏为。
- WebSocket
- 全雙工通信標(biāo)準(zhǔn)究驴,長連接
- websocket協(xié)議由IETF定位標(biāo)準(zhǔn)镊绪,websocket API由W3C定為標(biāo)準(zhǔn)
- WebDAV
- 基于萬維網(wǎng)的分布式文件系統(tǒng)
- HTTP2.0
- 二進(jìn)制傳輸
- 多路復(fù)用(Multiplexing):單一連接發(fā)起多重的請(qǐng)求/響應(yīng)
- 頭部壓縮
- 請(qǐng)求/響應(yīng)管線化pipeline
- 對(duì)請(qǐng)求劃分優(yōu)先級(jí)
- WebSocket
- TLS義務(wù)化
- 協(xié)商
- 流量控制
- 服務(wù)端push技術(shù)(Server Push)
- 更安全,對(duì)TLS進(jìn)行升級(jí)纳胧,網(wǎng)絡(luò)訪問用HTTPS
- 改善HTTP1.x的缺點(diǎn)
- HTTP1.0是短連接镰吆,一次只允許在一個(gè)TCP連接上發(fā)起一個(gè)請(qǐng)求,HTTP1.1的pipeline不成熟跑慕,只能部分處理請(qǐng)求并發(fā)万皿,瀏覽器也默認(rèn)不支持。
- 單向請(qǐng)求核行,只能由client發(fā)起請(qǐng)求牢硅。
- 請(qǐng)求與響應(yīng)報(bào)文首部冗余量大
- 文本傳輸,數(shù)據(jù)未壓縮芝雪,導(dǎo)致數(shù)據(jù)傳輸量大
46 構(gòu)建web內(nèi)容的技術(shù)
- 展示
- HTML/HTML5
- CSS/CSS3
- JavaScript
- 數(shù)據(jù)
- XML
- JSON
47 web攻擊技術(shù)
- 主動(dòng)攻擊
- SQL注入
- OS命令注入
- 被動(dòng)攻擊
- 跨站腳本攻擊(XSS减余,Cross-Site Scripting)
- 跨站點(diǎn)請(qǐng)求偽造(CSRF,Cross-Site Request Forgeries)
- HTTP首部注入攻擊:向首部添加內(nèi)容
- HTTP響應(yīng)截?cái)喙簦合蛑黧w添加內(nèi)容
- 郵件首部注入攻擊
- 目錄遍歷攻擊
- 遠(yuǎn)程文件包含漏洞
- 強(qiáng)制瀏覽
- 不正確的錯(cuò)誤消息處理
- 開放重定向
- 會(huì)話劫持
- 會(huì)話固定攻擊
- DNS劫持 / 域名劫持:把域名解析到錯(cuò)誤的IP地址或者惡意讓用戶訪問指定IP地址
- 其他安全漏洞
- 密碼破解
- 窮舉法 / 暴力破解法
- 字典攻擊
- 點(diǎn)擊劫持 / 界面?zhèn)窝b
- DoS攻擊 /拒絕服務(wù)攻擊
- DDoS攻擊惩系,多臺(tái)機(jī)器發(fā)起的DoS攻擊
- 后門程序
HTTPS攻擊
HTTPS攻擊多存在于中間人攻擊的環(huán)境中位岔,主要是針對(duì)HTTPS使用的壓縮算法和加密算法等進(jìn)行攻擊。
- 0x01 CRIME(Compression Ratio Info-leak Made Easy)
- 0x02 TIME(Timing Info-leak Made Easy)
- 0X03 BEAST(Browser Exploit Against SSL/TLS)
- 0x04 POODLE
中間人攻擊防御手段:
- 針對(duì)安全性要求比較高的 app堡牡,可采取客戶端預(yù)埋證書的方式鎖死證書抒抬,只有當(dāng)客戶端證書和服務(wù)端的證書完全一致的情況下才允許通信,如一些銀行類的app晤柄,但這種方式面臨一個(gè)問題擦剑,證書過期的問題,因證書有一定的有效期芥颈,當(dāng)預(yù)埋證書過期了惠勒,只有通過強(qiáng)制更新或者要求用戶下載證書來解決。
- 針對(duì)安全性要求一般的app爬坑,可采用通過校驗(yàn)域名纠屋,證書有效性、證書關(guān)鍵信息及證書鏈的方式妇垢。
48 應(yīng)用層協(xié)議
遠(yuǎn)程登錄
- Telnet
- SSH
文件傳輸
- FTP
- SFTP
電子郵件
- SMTP
- POP
- IMAP
網(wǎng)絡(luò)管理
- SNMP巾遭,Simple Network Management Protocol
- MIB,Management Information Base
- RMON闯估,Remote Monitoring
多媒體通信實(shí)現(xiàn)技術(shù)
- H. 323
- SIP
- RTP灼舍,Real-Time Protocol
- 數(shù)字壓縮技術(shù)
49 路由協(xié)議
路由控制類型
- 靜態(tài)路由:路由映射關(guān)系固定,通常手工處理涨薪。
- 動(dòng)態(tài)路由:自動(dòng)失效轉(zhuǎn)移
路由協(xié)議
路由控制范圍跟路由協(xié)議有關(guān)骑素,通常使用兩種路由協(xié)議。
- IGP刚夺,Interior Gateway Protocol献丑,內(nèi)部網(wǎng)關(guān)協(xié)議
- RIP末捣,Routing Information Protocol,路由信息協(xié)議
- RIP2
- OSPF创橄,Open Shortest Path First箩做,開放式最短路徑優(yōu)先
- EGP,Exterior Gateway Protocol妥畏,外部網(wǎng)關(guān)協(xié)議
- BGP邦邦,Border Gateway Protocol,邊界網(wǎng)關(guān)協(xié)議
路由算法
- 距離向量算法(Distance-Vector)
- 鏈路狀態(tài)算法(Link-State)
主要路由協(xié)議
50 SSO單點(diǎn)登錄原理及實(shí)現(xiàn)方案醉蚁?
單點(diǎn)登錄SSO(Single Sign On)燃辖,用戶在多系統(tǒng)環(huán)境只需要登錄一次,就可以得到其關(guān)聯(lián)系統(tǒng)的信任不用重新登錄网棍。SSO就是要解決兩個(gè)問題:
用戶憑證信息的存儲(chǔ)和驗(yàn)證黔龟。
基于Cookie作為憑證媒介
Cookie存儲(chǔ)在客戶端,客戶端登錄后服務(wù)端返回加密的cookie滥玷,用戶攜帶此cookie訪問其他子系統(tǒng)氏身,子系統(tǒng)服務(wù)端校驗(yàn)cookie,通過則允許登錄惑畴。
- cookie不安全
- 通過加密解決
- 不能跨域
- 通過JSONP解決跨域
基于Session
用redis存儲(chǔ)session實(shí)現(xiàn)sso
基于Token(JWT观谦,Jason Web Token)
JWT方案服務(wù)端不存儲(chǔ)session,服務(wù)端是無狀態(tài)的桨菜,便于擴(kuò)展。JWT的數(shù)據(jù)結(jié)構(gòu)主要分為三個(gè)部分捉偏,Header和Payload等JSON 對(duì)象也要使用 Base64URL 算法轉(zhuǎn)成字符串倒得。
- Header
Header 部分是一個(gè) JSON 對(duì)象,描述 JWT 的元數(shù)據(jù)夭禽。
- Payload
Payload部分也是一個(gè) JSON 對(duì)象霞掺,用來存放實(shí)際需要傳遞的數(shù)據(jù)。JWT 規(guī)定了7個(gè)官方字段讹躯,除了官方字段菩彬,你還可以在這個(gè)部分定義私有字段。
- iss (issuer):簽發(fā)人
- exp (expiration time):過期時(shí)間
- sub (subject):主題
- aud (audience):受眾
- nbf (Not Before):生效時(shí)間
- iat (Issued At):簽發(fā)時(shí)間
- jti (JWT ID):編號(hào)
- Signature
Signature部分是對(duì)前兩部分的簽名潮梯,防止數(shù)據(jù)篡改骗灶。
JWT的特點(diǎn):
(1)JWT 默認(rèn)是不加密,但也是可以加密的秉馏。生成原始 Token 以后耙旦,可以用密鑰再加密一次。
(2)JWT 不加密的情況下萝究,不能將秘密數(shù)據(jù)寫入 JWT免都。
(3)JWT 不僅可以用于認(rèn)證锉罐,也可以用于交換信息。有效使用 JWT绕娘,可以降低服務(wù)器查詢數(shù)據(jù)庫的次數(shù)脓规。
(4)JWT 的最大缺點(diǎn)是,由于服務(wù)器不保存 session 狀態(tài)险领,因此無法在使用過程中廢止某個(gè) token侨舆,或者更改 token 的權(quán)限。也就是說舷暮,一旦 JWT 簽發(fā)了态罪,在到期之前就會(huì)始終有效,除非服務(wù)器部署額外的邏輯下面。
(5)JWT 本身包含了認(rèn)證信息复颈,一旦泄露沥割,任何人都可以獲得該令牌的所有權(quán)限。為了減少盜用在验,JWT 的有效期應(yīng)該設(shè)置得比較短。對(duì)于一些比較重要的權(quán)限渗蟹,使用時(shí)應(yīng)該再次對(duì)用戶進(jìn)行認(rèn)證块饺。
(6)為了減少盜用,JWT 不應(yīng)該使用 HTTP 協(xié)議明碼傳輸雌芽,要使用 HTTPS 協(xié)議傳輸授艰。
JWT適用場景:
一次性的身份認(rèn)證、api的鑒權(quán)等膘怕,這些場景能充分發(fā)揮jwt無狀態(tài)以及分布式驗(yàn)證的優(yōu)勢想诅。
JWT不適用的場景:
不要試圖用jwt去代替session。這種模式下其實(shí)傳統(tǒng)的session+cookie機(jī)制工作的更好,jwt因?yàn)槠錈o狀態(tài)和分布式来破,事實(shí)上只要在有效期內(nèi)篮灼,是無法作廢的,用戶的簽退更多是一個(gè)客戶端的簽退徘禁,服務(wù)端token仍然有效诅诱,你只要使用這個(gè)token,仍然可以登陸系統(tǒng)送朱。另外一個(gè)問題是續(xù)簽問題娘荡,使用token,無疑令續(xù)簽變得十分麻煩驶沼,當(dāng)然你也可以通過redis去記錄token狀態(tài)炮沐,并在用戶訪問后更新這個(gè)狀態(tài),但這就是硬生生把jwt的無狀態(tài)搞成有狀態(tài)了回怜,而這些在傳統(tǒng)的session+cookie機(jī)制中都是不需要去考慮的大年。
CAS
CAS是開源的單點(diǎn)登錄系統(tǒng),主要分為CAS client和CAS server玉雾,CAS只是說明了原理翔试,具體實(shí)現(xiàn)要自己考慮。
基于 SAML
SAML(Security Assertion Markup Language 复旬,安全斷言標(biāo)記語言)的出現(xiàn)大大簡化了 SSO 垦缅,并被 OASIS 批準(zhǔn)為 SSO 的執(zhí)行標(biāo)準(zhǔn) 。開源組織 OpenSAML 實(shí)現(xiàn)了 SAML 規(guī)范驹碍。
基于網(wǎng)關(guān)
基于OAuth2.0
51 cookie壁涎、session、token區(qū)別志秃?
51.1 cookie
cookie生成規(guī)則
- cookie是服務(wù)端生成的粹庞,在客戶端以key-value形式保存用戶信息的
- 瀏覽器F12》Storage》Cookies可以看到cookie的組成:
- Name,相當(dāng)于key
- Value洽损,當(dāng)前用戶信息
- Domain,域名
- Path革半,路徑
- Expires/Max-Age碑定,過期時(shí)間
- Size,大小
cookie使用規(guī)則
- 服務(wù)器端響應(yīng)頭中設(shè)置set-cookie
- 客戶端保存cookie信息又官,并在發(fā)送請(qǐng)求時(shí)候在請(qǐng)求頭中帶上cookies
cookie有效期
- 如果設(shè)置了cookie的有效期延刘,則在有效期內(nèi)有效,即使瀏覽器關(guān)閉了六敬,cookie也存在碘赖;
- 如果沒有設(shè)置cookie的有效期,則瀏覽器關(guān)閉cookie失效。
cookie優(yōu)缺點(diǎn)
- 優(yōu)點(diǎn)
- 可以保存用戶信息和狀態(tài)普泡,配合無狀態(tài)的http完成用戶身份驗(yàn)證
- 缺點(diǎn)
- 瀏覽器保存的cookie數(shù)量和大小有限制
- cookie信息通過header或者URL明文傳輸容易泄露或被人劫持
- cookie在客戶端保存播掷,客戶端可以關(guān)閉cookie
- 不支持跨域訪問
51.2 session
session生成規(guī)則
- session在服務(wù)端生成,以hash表的key-value形式保存在服務(wù)端的內(nèi)存中
- 一個(gè)用戶一個(gè)session撼班,一個(gè)session對(duì)應(yīng)一個(gè)sessionid歧匈,key就是sessionid,value就是session中存儲(chǔ)的用戶信息砰嘁。
session使用規(guī)則
- 客戶端請(qǐng)求服務(wù)端分配sessionid件炉,sessionid隨響應(yīng)頭set-cookie保存在客戶端的cookie中;
- 客戶端發(fā)請(qǐng)求時(shí)候帶上cookies矮湘,服務(wù)端從cookies中取出sessionid斟冕,根據(jù)sessionid找到對(duì)應(yīng)的用戶信息。
session有效期
- session默認(rèn)有效期是30分鐘缅阳,如果30分鐘內(nèi)session沒有被訪問過磕蛇,則session失效。
session優(yōu)缺點(diǎn)
- 優(yōu)點(diǎn)
- 保存在服務(wù)端中券时,比保存在客戶端要安全
- 缺點(diǎn)
- 保存在服務(wù)端內(nèi)存中孤里,當(dāng)訪問用戶很多時(shí)候內(nèi)存占用很大,性能會(huì)收到影響橘洞。
- 可擴(kuò)展性差捌袜,增加了新節(jié)點(diǎn)沒有用戶的session信息
- CORS(跨域資源共享):當(dāng)我們需要讓數(shù)據(jù)跨多臺(tái)移動(dòng)設(shè)備上使用時(shí),跨域資源的共享會(huì)是一個(gè)讓人頭疼的問題炸枣。在使用Ajax抓取另一個(gè)域的資源虏等,就可以會(huì)出現(xiàn)禁止請(qǐng)求的情況。
- CSRF(跨站請(qǐng)求偽造):用戶在訪問銀行網(wǎng)站時(shí)适肠,他們很容易受到跨站請(qǐng)求偽造的攻擊霍衫,并且能夠被利用其訪問其他的網(wǎng)站
51.3 token
token生成規(guī)則
token一般是登錄時(shí)候由服務(wù)端生成,組成規(guī)則如下:
- UUID侯养,用戶唯一身份標(biāo)識(shí)
- time敦跌,時(shí)間戳
- sign,簽名逛揩,一般是UUID+time+salt(根據(jù)hash算法生成的字符串)
- 常用固定參數(shù)柠傍,可選
token使用規(guī)則
- 用戶通過用戶名和密碼發(fā)送請(qǐng)求后,服務(wù)端生成token辩稽,隨http響應(yīng)保存在客戶端的cookies或local storage中惧笛;
- 用戶請(qǐng)求時(shí)候帶上token,服務(wù)端獲取token用于驗(yàn)證用戶身份逞泄。
token有效期
- 根據(jù)token中的時(shí)間戳跟當(dāng)前時(shí)間對(duì)比計(jì)算患整,判斷過期與否拜效,默認(rèn)有效期是7天。
token優(yōu)缺點(diǎn)
- 優(yōu)點(diǎn)
- 支持跨域訪問
- 可以在多個(gè)服務(wù)間共享各谚,不占用服務(wù)端內(nèi)存紧憾,用CPU計(jì)算時(shí)間替代session存儲(chǔ)空間,服務(wù)端可以無狀態(tài)擴(kuò)展
- 支持移動(dòng)設(shè)備
- 安全
- 缺點(diǎn)
- 需要額外的時(shí)間開銷嘲碧,CPU需要每次校驗(yàn)傳過來的token是否有效稻励。
52 OAuth2.0原理
52.1 OAuth2.0 & JWT & SSO & Shiro區(qū)別
- SSO,單點(diǎn)登錄愈涩,OAuth2.0可以用來實(shí)現(xiàn)SSO望抽。
- OAuth2.0是授權(quán)的協(xié)議、框架履婉、標(biāo)準(zhǔn)煤篙,跟OAuth1.0不兼容,核心思想是頒發(fā)令牌(token)毁腿,使得第三方應(yīng)用使用該token在特定時(shí)間辑奈、特定范圍內(nèi)訪問指定資源。
- JWT已烤,Json Web Token鸠窗,一個(gè)開放的用戶認(rèn)證標(biāo)準(zhǔn),通過Header胯究、Payload稍计、Signature生成token。
- Shiro裕循,基于java語言的安全框架臣嚣,也可以實(shí)現(xiàn)授權(quán)。
52.2 OAuth2.0四種角色
- 資源所有者(resources owner):擁有被訪問資源的用戶
- 客戶端/第三方應(yīng)用(client):第三方應(yīng)用剥哑,獲取資源服務(wù)器提供的資源
- 授權(quán)服務(wù)器(authorization server):認(rèn)證服務(wù)器硅则,提供授權(quán)許可code、令牌token等
- 資源服務(wù)器(resource server):資源服務(wù)器株婴,擁有被訪問資源的服務(wù)器怎虫,需要通過token來確定是否有權(quán)限訪問。
52.3 OAuth2.0四種授權(quán)模式
授權(quán)碼模式(authorization code)
功能最完整困介、流程最嚴(yán)密揪垄、最安全的授權(quán)模式,code保證了token的安全性逻翁,即使code被攔截,由于沒有app_secret捡鱼,也是無法通過code獲得token的八回。
應(yīng)用場景:
各大應(yīng)用內(nèi)的qq,微信,微博登錄等缠诅。比如某應(yīng)用內(nèi)的qq登錄溶浴,過程如下:
a.用戶點(diǎn)擊qq登錄,會(huì)先跳轉(zhuǎn)到qq登錄頁面管引,這時(shí)請(qǐng)求已經(jīng)跳轉(zhuǎn)到qq服務(wù)器了士败,然后用戶輸入賬號(hào)或者掃碼登錄,這時(shí)所有請(qǐng)求都在qq服務(wù)器完成褥伴。
b.用戶正確登錄后谅将,qq服務(wù)器返回用戶的code給第三方應(yīng)用,然后第三方應(yīng)用再使用code去授權(quán)服務(wù)器請(qǐng)求獲取token重慢。(這一步用戶不可見)
c.第三方應(yīng)用獲取到token后饥臂,再使用token獲取用戶的qq名稱,頭像等信息似踱。
-
優(yōu)缺點(diǎn):
- 優(yōu)點(diǎn):用戶可以控制自身的一些權(quán)限是否給第三方隅熙,第三方只能獲取到用戶臨時(shí)產(chǎn)生的一個(gè)訪問的code,安全性核芽。
- 缺點(diǎn):認(rèn)證過程繁瑣囚戚。
隱式授權(quán)碼模式/簡單模式(implicit)
和授權(quán)碼模式類似,只不過少了獲取code的步驟轧简,是直接獲取令牌token的东揣,適用于公開的瀏覽器單頁應(yīng)用,令牌直接從授權(quán)服務(wù)器返回拙寡,不支持刷新令牌鼻疮,且沒有code安全保證,令牌容易因?yàn)楸粩r截竊聽而泄露借嗽。
不支持refresh token态鳖。
密碼模式(resource owner password credentials)
這種模式是最不推薦的,因?yàn)閏lient可能存了用戶密碼恶导。這種模式主要用來做遺留項(xiàng)目升級(jí)為oauth2的適配方案浆竭,當(dāng)然如果client是自家的應(yīng)用,也是可以的惨寿。支持refresh token邦泄。
客戶端憑證模式(client credentials)
這種模式直接根據(jù)client的id和密鑰即可獲取token,無需用戶參與裂垦。這種模式比較合適消費(fèi)api的后端服務(wù)顺囊,比如拉取一組用戶信息等,不支持refresh token蕉拢,主要是沒有必要特碳。
53 IO模型(AIO & NIO & BIO(同步阻塞) & 多路復(fù)用IO)
- 阻塞IO模型(BIO(Blocking IO)诚亚,同步阻塞IO,即傳統(tǒng)的IO)
用戶線程發(fā)出IO請(qǐng)求后午乓,如果數(shù)據(jù)沒有就緒就會(huì)一直阻塞等待站宗,用戶線程交出CPU,待數(shù)據(jù)就緒后益愈,內(nèi)核返回結(jié)果給用戶線程梢灭,用戶線程才會(huì)解除block狀態(tài)。
- 非阻塞IO模型(NIO(Non-blocking IO)蒸其,同步非阻塞IO敏释,不同于Java的NIO(New IO))
用戶線程會(huì)一直占用CPU輪詢內(nèi)核數(shù)據(jù)是否準(zhǔn)備就緒
- 多路復(fù)用IO模型(多路復(fù)用IO(IO Multiplexing),異步阻塞IO枣接,Reactor設(shè)計(jì)模式)
- 通過一個(gè)線程管理多個(gè)socket颂暇,只有當(dāng)socket真正有讀寫事件發(fā)生時(shí)才會(huì)占用資源進(jìn)行實(shí)際的讀寫操作,適合連接數(shù)比較多的情況但惶。
- 多路復(fù)用IO模型是通過輪詢的方式檢測是否有事件到達(dá)耳鸯,一旦事件響應(yīng)體很大,輪詢事件就會(huì)很長膀曾,導(dǎo)致后續(xù)事件遲遲得不到處理县爬,影響新的事件輪詢。
- 信號(hào)驅(qū)動(dòng)IO模型
用戶線程發(fā)起一個(gè)IO請(qǐng)求添谊,會(huì)給對(duì)應(yīng)的socket注冊(cè)一個(gè)信號(hào)函數(shù)然后繼續(xù)執(zhí)行财喳,待內(nèi)核數(shù)據(jù)準(zhǔn)備好后會(huì)發(fā)送一個(gè)信號(hào)給用戶線程,用戶線程收到信號(hào)后斩狱,便在信號(hào)函數(shù)中調(diào)用IO讀寫操作完成真實(shí)的IO請(qǐng)求操作耳高。
- 異步IO模型(AIO(Asynchronous IO),NIO2.0所踊,JDK7開始支持泌枪,異步非阻塞IO,Proactor設(shè)計(jì)模式)
異步IO是最理想的IO模型秕岛,跟信號(hào)驅(qū)動(dòng)IO不同的是碌燕,當(dāng)用戶線程收到內(nèi)核返回的信號(hào)時(shí)表示IO操作已完成,不用再去顯示調(diào)用IO操作继薛。
54 Java傳統(tǒng)IO
54.1 Java IO包
54.2 Java IO分類
54.3 Java IO & NIO
- NIO三大核心部分:Channel通道修壕、Buffer緩沖區(qū)、Selector選擇器遏考。
- IO是面向流的慈鸠,NIO是面向緩沖區(qū)的。
54.4 Java NIO比傳統(tǒng)IO的優(yōu)勢
- 傳統(tǒng)IO是BIO(Blocking IO)灌具,Java NIO是異步非阻塞IO
- Java NIO有緩沖機(jī)制:buffer和channel機(jī)制
- NIO有零拷貝(零拷貝的前提是數(shù)據(jù)不需要加工)
- NIO提供MappedByteBuffer青团,將文件直接映射到虛擬內(nèi)存像棘,提高IO吞吐能力
- NIO的IO多路復(fù)用模型、事件驅(qū)動(dòng)模型壶冒、非阻塞模型
55 Java NIO
55.1 Java NIO包
55.2 Channel
- NIO的Channel類似于IO的Stream,Stream是單向的截歉,Channel是雙向的胖腾。
- NIO的Channel有4種實(shí)現(xiàn):
- FileChannel:文件IO
- DatagramChannel:UDP
- SocketChannel:TCP Client
- ServerSocketChannel:TCP Server
55.3 Buffer
- Buffer,緩沖區(qū)瘪松,實(shí)際上是一個(gè)容器咸作,是一個(gè)連續(xù)數(shù)組,Channel提供從網(wǎng)絡(luò)或文件讀取數(shù)據(jù)的通道宵睦,但是讀寫數(shù)據(jù)都必須經(jīng)過Buffer记罚。
- 在NIO中,Buffer是頂層父類壳嚎,是抽象類桐智,常用的Buffer子類有:
- ByteBuffer
- ShortBuffer
- IntBuffer
- LongBuffer
- FloatBuffer
- DoubleBuffer
- CharBuffer
- 客戶端發(fā)送數(shù)據(jù),服務(wù)端接受數(shù)據(jù)的過程:
55.4 Selector
- Selector檢測多個(gè)Channel是否有事件發(fā)生烟馅,如果有事件發(fā)生说庭,就獲取事件針對(duì)每個(gè)事件做相應(yīng)的處理。
- 只用一個(gè)單線程就可以管理多個(gè)Channel郑趁,不用維護(hù)多個(gè)線程刊驴,避免多線程上下文切換帶來的的開銷。
56 Netty原理
- 基于Java NIO實(shí)現(xiàn)的異步事件驅(qū)動(dòng)NIO框架寡润。
- Netty的所有IO操作都是異步非阻塞的捆憎。
- 通過Future-Listener機(jī)制,用戶可以方便的主動(dòng)獲取或者通過通知機(jī)制獲得IO操作結(jié)果梭纹。
57 Netty為什么是高性能的躲惰?
- IO多路復(fù)用
- 事件驅(qū)動(dòng)
- 異步非阻塞NIO,優(yōu)于同步阻塞IO
- 高效傳輸
- 零拷貝技術(shù):transferTo
- 堆外直接內(nèi)存
- ByteBuffer采用堆外直接內(nèi)存進(jìn)行Socket讀寫栗柒,避免字節(jié)緩沖區(qū)二次拷貝礁扮;
- 多個(gè)小的Buffer可以合并成大的Buffer批量傳輸
- 內(nèi)存池
- 直接內(nèi)存分配和回收比較麻煩,為了重用緩沖區(qū)瞬沦,Netty提供了基于內(nèi)存池的緩沖區(qū)重用機(jī)制
- 高效的Reactor線程模型
- Reactor單線程模型
- 一個(gè)NIO線程處理所有IO操作
- Reactor多線程模型
- 一組NIO線程處理所有IO操作
- Acceptor線程監(jiān)聽服務(wù)端太伊,接收客戶端的TCP連接請(qǐng)求
- NIO線程池負(fù)責(zé)網(wǎng)絡(luò)IO讀寫操作
- 主從Reactor多線程模型
- 接收請(qǐng)求的是Acceptor線程池
- 無鎖設(shè)計(jì)
- Netty的IO線程采用串行無鎖設(shè)計(jì),避免多線程競爭導(dǎo)致性能下降
- 高性能序列化框架protobuf
- SO_RCVBUF和SO_SNDBUF:通常建議值為128K或者256K逛钻。
- 小包封大包僚焦,防止網(wǎng)絡(luò)阻塞
- 軟中斷Hash值和CPU綁定
58 Netty為什么不支持AIO而用NIO?
- Linux系統(tǒng)AIO的實(shí)現(xiàn)底層仍然是epoll曙痘,與NIO相比芳悲,性能沒有明顯優(yōu)勢立肘;
- Windows系統(tǒng)AIO底層實(shí)現(xiàn)良好,但是Netty不看重Windows市場名扛。
59 Netty服務(wù)端通信流程
60 Netty客戶端通信流程
61 高效序列化機(jī)制
- Google protobuf > Google thrift > kryo / FST / Apache Avro / fastjson > Google Gson / Jackson > JDK
61.1 Google protobuf
-
Protocol Buffer的序列化 & 反序列化簡單 & 速度快的原因是:
- 編碼 / 解碼 方式簡單(只需要簡單的數(shù)學(xué)運(yùn)算 = 位移等等)
- 采用 Protocol Buffer 自身的框架代碼 和 編譯器 共同完成
-
Protocol Buffer的數(shù)據(jù)壓縮效果好(即序列化后的數(shù)據(jù)量體積辛履辍)的原因:
- 采用了獨(dú)特的編碼方式,如Varint肮韧、Zigzag編碼方式等等
- 采用T - L - V 的數(shù)據(jù)存儲(chǔ)方式:減少了分隔符的使用 & 數(shù)據(jù)存儲(chǔ)得緊湊
-
Google protobuf優(yōu)點(diǎn)
- 二進(jìn)制消息融蹂,性能好/效率高(空間和時(shí)間效率都很不錯(cuò))
- proto文件生成目標(biāo)代碼,簡單易用
- 序列化反序列化直接對(duì)應(yīng)程序中的數(shù)據(jù)類弄企,不需要解析后在進(jìn)行映射(XML,JSON都是這種方式)
- 支持向前兼容(新加字段采用默認(rèn)值)和向后兼容(忽略新加字段)超燃,簡化升級(jí)
- 支持多種語言(可以把proto文件看做IDL文件)
- Netty等一些框架集成
-
Google protobuf缺點(diǎn)
- 官方只支持C++,JAVA和Python語言綁定
- 二進(jìn)制可讀性差(貌似提供了Text_Fromat功能)
- 二進(jìn)制不具有自描述特性
- 默認(rèn)不具備動(dòng)態(tài)特性(可以通過動(dòng)態(tài)定義生成消息類型或者動(dòng)態(tài)編譯支持)
- 只涉及序列化和反序列化技術(shù),不涉及RPC功能(類似XML或者JSON的解析器)
61.2 Facebook thrift
-
Facebook thrift優(yōu)點(diǎn)
- 支持非常多的語言綁定
- 性能高效
- thrift文件生成目標(biāo)代碼拘领,簡單易用
- 消息定義文件支持注釋
- 數(shù)據(jù)結(jié)構(gòu)與傳輸表現(xiàn)的分離意乓,支持多種消息格式
- 包含完整的客戶端/服務(wù)端堆棧,可快速實(shí)現(xiàn)RPC
- 支持同步和異步通信
- 應(yīng)用在Facebook開源日志收集系統(tǒng)约素、淘寶實(shí)時(shí)數(shù)據(jù)傳輸平臺(tái)届良、Evernote開放接口、Quora业汰、HBase等
-
Facebook thrift缺點(diǎn)
- 和protobuf一樣不支持動(dòng)態(tài)特性
61.3 Apache Avro
-
Apache Avro優(yōu)點(diǎn)
- 二進(jìn)制消息伙窃,性能好/效率高
- 使用JSON描述模式
- 模式和數(shù)據(jù)統(tǒng)一存儲(chǔ),消息自描述样漆,不需要生成stub代碼(支持生成IDL)
- RPC調(diào)用在握手階段交換模式定義
- 包含完整的客戶端/服務(wù)端堆棧为障,可快速實(shí)現(xiàn)RPC
- 支持同步和異步通信
- 支持動(dòng)態(tài)消息
- 模式定義允許定義數(shù)據(jù)的排序(序列化時(shí)會(huì)遵循這個(gè)順序)
- 提供了基于Jetty內(nèi)核的服務(wù)基于Netty的服務(wù)
- Hadoop和Redis默認(rèn)的序列化框架
-
Apache Avro缺點(diǎn)
- 只支持Avro自己的序列化格式
- 語言綁定不如Thrift豐富
61.4 kryo
- 速度快,序列化后體積小
- 跨語言支持較復(fù)雜
- dubbox默認(rèn)的就是kryo+FST
61.5 FST
fst是完全兼容JDK序列化協(xié)議的系列化框架放祟,序列化速度大概是JDK的4-10倍鳍怨,大小是JDK大小的1/3左右。
61.6 hessian
- 默認(rèn)支持跨語言
- 較慢
61.7 json
開源的Jackson
- 相比json-lib框架跪妥,Jackson所依賴的jar包較少鞋喇,簡單易用并且性能也要相對(duì)高些。
- Jackson社區(qū)相對(duì)比較活躍眉撵,更新速度也比較快侦香。
- Jackson對(duì)于復(fù)雜類型的json轉(zhuǎn)換bean會(huì)出現(xiàn)問題,一些集合Map纽疟,List的轉(zhuǎn)換出現(xiàn)問題罐韩。
- Jackson對(duì)于復(fù)雜類型的bean轉(zhuǎn)換Json,轉(zhuǎn)換的json格式不是標(biāo)準(zhǔn)的Json格式污朽。
阿里巴巴Fastjson
- Fastjson是一個(gè)Java語言編寫的高性能的JSON處理器,由阿里巴巴公司開發(fā)散吵。
- 無依賴,不需要例外額外的jar,能夠直接跑在JDK上矾睦。
- FastJson在復(fù)雜類型的Bean轉(zhuǎn)換Json上會(huì)出現(xiàn)一些問題晦款,可能會(huì)出現(xiàn)引用的類型,導(dǎo)致Json轉(zhuǎn)換出錯(cuò)枚冗,需要制定引用缓溅。
- FastJson采用獨(dú)創(chuàng)的算法,將parse的速度提升到極致赁温,超過所有json庫肛宋。
Google的Gson
- Gson是目前功能最全的Json解析神器,Gson當(dāng)初是為因應(yīng)Google公司內(nèi)部需求而由Google自行研發(fā)而來束世,但自從在2008年五月公開發(fā)布第一版后已被許多公司或用戶應(yīng)用。
- Gson的應(yīng)用主要為toJson與fromJson兩個(gè)轉(zhuǎn)換函數(shù)床玻,無依賴毁涉,不需要例外額外的jar,能夠直接跑在JDK上锈死。
- 使用這種對(duì)象轉(zhuǎn)換之前需先創(chuàng)建好對(duì)象的類型以及其成員才能成功的將JSON字符串成功轉(zhuǎn)換成相對(duì)應(yīng)的對(duì)象贫堰。
- 類里面只要有g(shù)et和set方法,Gson完全可以將復(fù)雜類型的json到bean或bean到j(luò)son的轉(zhuǎn)換待牵,是JSON解析的神器其屏。
- Gson在功能上面無可挑剔,但是性能上面比FastJson有所差距缨该。
61.8 JDK序列化
- 無法跨語言偎行。這應(yīng)該是java序列化最致命的問題了。由于java序列化是java內(nèi)部私有的協(xié)議贰拿,其他語言不支持蛤袒,導(dǎo)致別的語言無法反序列化,這嚴(yán)重阻礙了它的應(yīng)用膨更。
- 序列后的碼流太大妙真。java序列化的大小是二進(jìn)制編碼的5倍多!
- 序列化性能太低荚守。java序列化的性能只有二進(jìn)制編碼的6.17倍珍德,可見java序列化性能實(shí)在太差了。
62 Netty Channel原理
62.1 Channel類圖
62.2 Netty傳輸方式/協(xié)議
- NIO矗漾,Non-blocking IO锈候,io.netty.channel.socket.nio,基于java.nio.channels的工具包缩功,使用選擇器作為基礎(chǔ)的方法晴及,在高連接數(shù)時(shí)使用;
- OIO,Old blocking IO虑稼,io.netty.channel.socket.oio琳钉,基于java.net的工具包,使用阻塞流蛛倦,適用于低連接數(shù)歌懒、需要低延時(shí)、阻塞時(shí)使用溯壶;
- Local及皂,io.netty.channel.local,用來在虛擬機(jī)之間本地通信且改,在同一個(gè)JVM內(nèi)通信時(shí)使用验烧;
- Embedded,io.netty.channel.embedded又跛,嵌入傳輸碍拆,它允許在沒有真正網(wǎng)絡(luò)的運(yùn)輸中使用ChannelHandler,可以非常有用的來測試ChannelHandler的實(shí)現(xiàn)慨蓝。測試ChannelHandler時(shí)使用感混。
63 Netty Buffer原理
63.1 Buffer API
ByteBuf的作用是在Netty中通過Channel傳輸數(shù)據(jù),Netty的ByteBuf相當(dāng)于JDK的ByteBuffer礼烈,只是比JDK做了很多優(yōu)化弧满。Netty的Buffer API主要有兩個(gè)接口:
- ByteBuf:字節(jié)數(shù)據(jù)容器
- ByteBuf分為讀和寫兩部分,所有數(shù)據(jù)操作都要維護(hù)數(shù)據(jù)索引此熬,根據(jù)數(shù)據(jù)索引可以順序讀或者跳讀庭呜。
- ByteBuf類型字節(jié)數(shù)組,讀和寫的開始索引都為0犀忱,讀寫索引位置相同時(shí)候再讀取會(huì)拋出異常IndexOutOfBoundsException
- ByteBuf默認(rèn)最大容量限制是Integer.MAX_VALUE
- ByteBufHolder:輔助接口疟赊,提供的方法很少,主要用于釋放資源等輔助操作
- ByteBufAllocator:類似線程池峡碉,負(fù)責(zé)分配ByteBuf實(shí)例
- Unpooled:創(chuàng)建緩沖區(qū)的工具類
- ByteBufUtil:靜態(tài)工具類
63.2 Buffer分類
- Heap Buffer(堆緩沖區(qū))
- 最常用的緩沖區(qū)近哟,數(shù)據(jù)存儲(chǔ)在JVM的堆空間,訪問非堆緩沖區(qū)的數(shù)組會(huì)導(dǎo)致UnsupportedOperationException
- 提供了直接訪問數(shù)組的方法鲫寄,通過ByteBuf.array()來獲取Byte[]數(shù)據(jù)吉执。
- Direct Buffer(直接緩沖區(qū))
- 直接緩沖區(qū)在堆外直接分配內(nèi)存,缺點(diǎn)就是內(nèi)存的分配和釋放比堆緩沖區(qū)復(fù)雜地来,Netty使用內(nèi)存池來解決戳玫。
- 直接緩沖區(qū)不支持?jǐn)?shù)組訪問數(shù)據(jù)
- Composite Buffer(復(fù)合緩沖區(qū))
- JDK的ByteBuffer沒有復(fù)合緩沖區(qū)的功能
64 Netty ChannelHandler
64.1 ChannelHandler類圖
64.2 ChannelPipeline
ChannelPipeline是ChannelHandler實(shí)例的列表,用于處理或截獲通道的接收和發(fā)送數(shù)據(jù)未斑。
64.3 ChannelHandlerContext
ChannelHandler的上下文
64.4 Channel生命周期狀態(tài)模型
- channelUnregistered
- channelRegistered
- channelActive
- channelInactive
65 Netty編解碼器codec
65.1 編碼器Encoder
- MessageToByteEncoder咕宿,消息對(duì)象到字節(jié)對(duì)象
- MessageToMessageEncoder,消息對(duì)象到消息對(duì)象
65.2 解碼器Decoder
- ByteToMessageDecoder,解碼字節(jié)到消息
- ReplayingDecoder府阀,解碼消息到字節(jié)
- MessageToMessageDecoder缆镣,解碼消息到消息
65.3 編解碼器codec
- byte-to-byte
- ByteToMessageCodec
- MessageToMessageCodec
65.4 HTTP編解碼器
- HttpRequestEncoder,將HttpRequest或HttpContent編碼成ByteBuf
- HttpRequestDecoder试浙,將ByteBuf解碼成HttpRequest和HttpContent
- HttpResponseEncoder董瞻,將HttpResponse或HttpContent編碼成ByteBuf
- HttpResponseDecoder,將ByteBuf解碼成HttpResponse和HttpContent
66 Netty對(duì)HTTP的優(yōu)化
66.1 HTTP
- 使用HTTP時(shí)候通過數(shù)據(jù)壓縮可以減少傳輸流量田巴,但是壓縮數(shù)據(jù)會(huì)增加CPU負(fù)載钠糊,Netty支持兩種數(shù)據(jù)壓縮方式:gzip和deflate
66.2 HTTPS
- 網(wǎng)絡(luò)傳輸?shù)闹匾獢?shù)據(jù)要加密,Netty提供了SSLHandler可以實(shí)現(xiàn)加密壹哺。
66.3 WebSocket
- WebSocket是全雙工傳輸數(shù)據(jù)抄伍,不需要請(qǐng)求-響應(yīng)模式,早期的WebSocket只能傳輸文本數(shù)據(jù)管宵,現(xiàn)在也能傳輸二進(jìn)制數(shù)據(jù)逝慧。
- Netty中的WebSocket類型有:
- BinaryWebSocketFrame,包含二進(jìn)制數(shù)據(jù)
- TextWebSocketFrame啄糙,包含文本數(shù)據(jù)
- ContinuationWebSocketFrame,包含二進(jìn)制數(shù)據(jù)或文本數(shù)據(jù)云稚,BinaryWebSocketFrame和
- TextWebSocketFrame的結(jié)合體
- CloseWebSocketFrame隧饼,WebSocketFrame代表一個(gè)關(guān)閉請(qǐng)求,包含關(guān)閉狀態(tài)碼和短語
- PingWebSocketFrame静陈,WebSocketFrame要求PongWebSocketFrame發(fā)送數(shù)據(jù)
- PongWebSocketFrame燕雁,WebSocketFrame要求PingWebSocketFrame響應(yīng)
66.4 SPDY
- Google開發(fā)的基于TCP的應(yīng)用層協(xié)議,對(duì)HTTP協(xié)議的增加鲸拥,采用多路復(fù)用拐格、請(qǐng)求優(yōu)先級(jí)、HTTP報(bào)文頭壓縮刑赶、強(qiáng)制使用SSL加密等手段提高網(wǎng)絡(luò)速度捏浊。
66.5 Netty處理空閑連接和超時(shí)
- IdleStateHandler,當(dāng)一個(gè)通道沒有進(jìn)行讀寫或運(yùn)行了一段時(shí)間后出發(fā)IdleStateEvent
- ReadTimeoutHandler撞叨,在指定時(shí)間內(nèi)沒有接收到任何數(shù)據(jù)將拋出ReadTimeoutException
- WriteTimeoutHandler金踪,在指定時(shí)間內(nèi)有寫入數(shù)據(jù)將拋出WriteTimeoutException
66.6 Netty序列化機(jī)制
- JDK序列化
CompatibleObjectEncoder
CompactObjectInputStream
CompactObjectOutputStream
ObjectEncoder
ObjectDecoder
ObjectEncoderOutputStream
ObjectDecoderInputStream
- JBOSS編組序列化:速度是JDK序列化的3倍,體積更小
CompatibleMarshallingEncoder
CompatibleMarshallingDecoder
MarshallingEncoder
MarshallingDecoder
- protobuf序列化
ProtobufDecoder
ProtobufEncoder
ProtobufVarint32FrameDecoder
ProtobufVarint32LengthFieldPrepender
67 TCP粘包拆包問題
67.1 TCP為什么發(fā)生粘包拆包問題牵敷?為什么UDP不會(huì)發(fā)生粘包拆包問題胡岔?
- 粘包拆包是網(wǎng)絡(luò)底層的問題,常發(fā)生在數(shù)據(jù)鏈路層枷餐、網(wǎng)絡(luò)層靶瘸、傳輸層。
- TCP是基于字節(jié)流的,沒有邊界怨咪,且TCP首部沒有表示數(shù)據(jù)長度的字段
- UDP是基于報(bào)文的屋剑,有消息保護(hù)邊界,且UDP首部有16bit標(biāo)識(shí)報(bào)文長度惊暴,應(yīng)用層能區(qū)分開不同報(bào)文饼丘,不會(huì)發(fā)生粘包拆包問題,粘包拆包只發(fā)生在TCP協(xié)議中辽话。
- 粘包發(fā)生的原因
- 應(yīng)用程序?qū)懭霐?shù)據(jù)小于套接字緩沖區(qū)大小肄鸽,網(wǎng)卡將應(yīng)用多次寫入的數(shù)據(jù)發(fā)送到網(wǎng)絡(luò)上,這將會(huì)發(fā)生粘包油啤。
- 接收方法不及時(shí)讀取套接字緩沖區(qū)數(shù)據(jù)典徘,這將發(fā)生粘包。
- 拆包發(fā)生的原因
- 應(yīng)用程序?qū)懭氲臄?shù)據(jù)大于套接字緩沖區(qū)大小益咬,這將會(huì)發(fā)生拆包逮诲。
- 進(jìn)行MSS(最大報(bào)文長度)大小的TCP分段,當(dāng)TCP報(bào)文長度-TCP頭部長度>MSS的時(shí)候?qū)l(fā)生拆包幽告。
67.2 TCP粘包拆包解決方案
- 實(shí)際長度:發(fā)送端給每個(gè)數(shù)據(jù)包添加包首部梅鹦,首部中應(yīng)該至少包含數(shù)據(jù)包的長度,這樣接收端在接收到數(shù)據(jù)后冗锁,通過讀取包首部的長度字段齐唆,便知道每一個(gè)數(shù)據(jù)包的實(shí)際長度了。
- 固定長度:發(fā)送端將每個(gè)數(shù)據(jù)包封裝為固定長度(不夠的可以通過補(bǔ)0填充)冻河,這樣接收端每次從接收緩沖區(qū)中讀取固定長度的數(shù)據(jù)就自然而然的把每個(gè)數(shù)據(jù)包拆分開來箍邮。
- 分隔符:可以在數(shù)據(jù)包之間設(shè)置邊界,如添加特殊符號(hào)叨叙,這樣锭弊,接收端通過這個(gè)邊界就可以將不同的數(shù)據(jù)包拆分開。
67.3 Netty怎么解決粘包拆包擂错?
- 分隔符協(xié)議
- DelimiterBasedFrameDecoder味滞,解碼器,接收ByteBuf由一個(gè)或多個(gè)分隔符拆分钮呀,如NUL或換行符
- LineBasedFrameDecoder桃犬,解碼器,接收ByteBuf以分割線結(jié)束行楞,如"\n"和"\r\n"
- 長度協(xié)議
- FixedLengthFrameDecoder
- LengthFieldBasedFrameDecoder
68 Netty引導(dǎo)
68.1 引導(dǎo)的類圖
68.2 引導(dǎo)分類
- 引導(dǎo)客戶端和無連接協(xié)議:Bootstrap
Bootstrap用來連接遠(yuǎn)程主機(jī)调榄,有1個(gè)EventLoopGroup
- 引導(dǎo)服務(wù)端:ServerBootstrap
ServerBootstrap用來綁定本地端口番刊,有2個(gè)EventLoopGroup
69 RESTful
69.1 RESTful定義
- REST:表述性狀態(tài)轉(zhuǎn)移辐脖,Representational State Transfer奥裸,是一種互聯(lián)網(wǎng)軟件的架構(gòu)原則
- RESTful:一個(gè)架構(gòu)如果符合REST原則就轧,它就是RESTful架構(gòu)
69.2 RESTful特點(diǎn)
- 資源(Resources):每個(gè)資源對(duì)應(yīng)一個(gè)URI,通過URI訪問資源田度。
- 表現(xiàn)層(Representation):把資源呈現(xiàn)出來的的形式妒御,叫做它的表現(xiàn)層,如XML镇饺、json等
- 狀態(tài)轉(zhuǎn)換(State Transfer):HTTP協(xié)議無狀態(tài)乎莉,HTTP操作方式:
- GET:獲取資源
- POST:新建資源(也可用于更新資源)
- PUT:更新資源
- DELETE:刪除資源
69.3 RESTful架構(gòu)
- 瀏覽器使用GET/POST/PUT/DELETE等請(qǐng)求方式對(duì)指定的URI資源進(jìn)行增刪改查操作
- 前后端分離
69.4 GET與POST請(qǐng)求區(qū)別
- 傳輸方式:get通過瀏覽器地址欄傳送,post通過報(bào)文傳送
- 數(shù)據(jù)大屑轶浴:get參數(shù)有大小限制惋啃,post沒有
- 安全性:get安全性差于post
- 冪等性:get、put监右、delete都是冪等操作边灭,post不是冪等操作
- 對(duì)于GET方式的請(qǐng)求,瀏覽器會(huì)把http header和data一并發(fā)送出去健盒,服務(wù)器響應(yīng)200(返回?cái)?shù)據(jù))绒瘦;
而對(duì)于POST,瀏覽器先發(fā)送header扣癣,服務(wù)器響應(yīng)100 continue惰帽,瀏覽器再發(fā)送data,服務(wù)器響應(yīng)200 ok(返回?cái)?shù)據(jù))父虑。也不盡然该酗,F(xiàn)irefox對(duì)post請(qǐng)求就只發(fā)一次包。
70 Netty源碼
Bootstrap or ServerBootstrap
EventLoop
EventLoopGroup
ChannelPipeline
Channel
Future or ChannelFuture
ChannelInitializer
ChannelHandler
71 TCP擁塞控制算法
71.1 TCP四大擁塞控制策略
- 基于丟包的擁塞控制:將丟包視為出現(xiàn)擁塞频轿,采取緩慢探測的方式,逐漸增大擁塞窗口烁焙,當(dāng)出現(xiàn)丟包時(shí)航邢,將擁塞窗口減小,如 Reno骄蝇、Cubic 等膳殷。
- 基于時(shí)延的擁塞控制:將時(shí)延增加視為出現(xiàn)擁塞,延時(shí)增加時(shí)增大擁塞窗口九火,延時(shí)減小時(shí)減小擁塞窗口赚窃,如 Vegas、FastTCP 等岔激。
- 基于鏈路容量的擁塞控制:實(shí)時(shí)測量網(wǎng)絡(luò)帶寬和時(shí)延勒极,認(rèn)為網(wǎng)絡(luò)上報(bào)文總量大于帶寬時(shí)延乘積時(shí)出現(xiàn)了擁塞,如 BBR虑鼎。
- 基于學(xué)習(xí)的擁塞控制:沒有特定的擁塞信號(hào)辱匿,而是借助評(píng)價(jià)函數(shù)键痛,基于訓(xùn)練數(shù)據(jù),使用機(jī)器學(xué)習(xí)的方法形成一個(gè)控制策略匾七,如 Remy絮短。
71.2 Reno
擁塞控制狀態(tài)機(jī)(Congestion Control State Machine)
Open狀態(tài)
Open狀態(tài)是擁塞控制狀態(tài)機(jī)的默認(rèn)狀態(tài)。這種狀態(tài)下昨忆,當(dāng)ACK到達(dá)時(shí)丁频,發(fā)送方根據(jù)擁塞窗口cwnd(Congestion Window)是小于還是大于慢啟動(dòng)閾值ssthresh(slow start threshold),來按照慢啟動(dòng)或者擁塞避免算法來調(diào)整擁塞窗口邑贴。
Disorder狀態(tài)
當(dāng)發(fā)送方檢測到DACK(重復(fù)確認(rèn))或者SACK(選擇性確認(rèn))時(shí)席里,狀態(tài)機(jī)將轉(zhuǎn)變?yōu)镈isorder狀態(tài)。在此狀態(tài)下痢缎,發(fā)送方遵循飛行(in-flight)包守恒原則胁勺,即一個(gè)新包只有在一個(gè)老包離開網(wǎng)絡(luò)后才發(fā)送,也就是發(fā)送方收到老包的ACK后独旷,才會(huì)再發(fā)送一個(gè)新包署穗。
CWR狀態(tài)
發(fā)送方接收到一個(gè)顯示擁塞通知時(shí),并不會(huì)立刻減少擁塞窗口cwnd嵌洼,而是每收到兩個(gè)ACK就減少一個(gè)段案疲,直到窗口的大小減半為止。當(dāng)cwnd正在減小并且網(wǎng)絡(luò)中有沒有重傳包時(shí)麻养,這個(gè)狀態(tài)就叫CWR(Congestion Window Reduced褐啡,擁塞窗口減少)狀態(tài)。CWR狀態(tài)可以轉(zhuǎn)變成Recovery或者Loss狀態(tài)鳖昌。
Recovery狀態(tài)
當(dāng)發(fā)送方接收到足夠(推薦為三個(gè))的DACK(重復(fù)確認(rèn))后备畦,進(jìn)入該狀態(tài)。在該狀態(tài)下许昨,擁塞窗口cnwd每收到兩個(gè)ACK就減少一個(gè)段(segment)懂盐,直到cwnd等于慢啟動(dòng)閾值ssthresh,也就是剛進(jìn)入Recover狀態(tài)時(shí)cwnd的一半大小糕档。 發(fā)送方保持 Recovery 狀態(tài)直到所有進(jìn)入 Recovery狀態(tài)時(shí)正在發(fā)送的數(shù)據(jù)段都成功地被確認(rèn)莉恼,然后發(fā)送方恢復(fù)成Open狀態(tài),重傳超時(shí)有可能中斷 Recovery 狀態(tài)速那,進(jìn)入Loss狀態(tài)俐银。
Loss狀態(tài)
當(dāng)一個(gè)RTO(重傳超時(shí)時(shí)間)到期后,發(fā)送方進(jìn)入Loss狀態(tài)端仰。所有正在發(fā)送的數(shù)據(jù)標(biāo)記為丟失捶惜,擁塞窗口cwnd設(shè)置為一個(gè)段(segment),發(fā)送方再次以慢啟動(dòng)算法增大擁塞窗口cwnd荔烧。
Loss 和 Recovery 狀態(tài)的區(qū)別是:Loss狀態(tài)下售躁,擁塞窗口在發(fā)送方設(shè)置為一個(gè)段后增大坞淮,而 Recovery 狀態(tài)下,擁塞窗口只能被減小陪捷。Loss 狀態(tài)不能被其他的狀態(tài)中斷回窘,因此,發(fā)送方只有在所有 Loss 開始時(shí)正在傳輸?shù)臄?shù)據(jù)都得到成功確認(rèn)后市袖,才能退到 Open 狀態(tài)啡直。
四大擁塞控制算法
Reno將擁塞控制的過程分為四個(gè)階段:慢啟動(dòng)、擁塞避免苍碟、快重傳和快恢復(fù)酒觅,是現(xiàn)有的眾多擁塞控制算法的基礎(chǔ)。
1. 慢熱啟動(dòng)算法 – Slow Start
所謂慢啟動(dòng)微峰,也就是TCP連接剛建立舷丹,一點(diǎn)一點(diǎn)地提速,試探一下網(wǎng)絡(luò)的承受能力蜓肆,以免直接擾亂了網(wǎng)絡(luò)通道的秩序颜凯。
- 連接建好的開始先初始化擁塞窗口cwnd大小為1,表明可以傳一個(gè)MSS大小的數(shù)據(jù)仗扬。
- 每當(dāng)收到一個(gè)ACK症概,cwnd大小加一,呈線性上升早芭。
- 每當(dāng)過了一個(gè)往返延遲時(shí)間RTT(Round-Trip Time)彼城,cwnd大小直接翻倍,乘以2退个,呈指數(shù)上升募壕。
- 還有一個(gè)ssthresh(slow start threshold),是一個(gè)上限语盈,當(dāng)cwnd >= ssthresh時(shí)舱馅,就會(huì)進(jìn)入“擁塞避免算法”(后面會(huì)說這個(gè)算法)。
2. 擁塞避免算法 – Congestion Avoidance
如同前邊說的黎烈,當(dāng)擁塞窗口大小cwnd大于等于慢啟動(dòng)閾值ssthresh后习柠,就進(jìn)入擁塞避免算法匀谣。算法如下:
- 收到一個(gè)ACK照棋,則cwnd = cwnd + 1 / cwnd。
- 每當(dāng)過了一個(gè)往返延遲時(shí)間RTT武翎,cwnd大小加一烈炭。
過了慢啟動(dòng)閾值后,擁塞避免算法可以避免窗口增長過快導(dǎo)致窗口擁塞宝恶,而是緩慢的增加調(diào)整到網(wǎng)絡(luò)的最佳值符隙。
3. 擁塞狀態(tài)時(shí)的算法
一般來說趴捅,TCP擁塞控制默認(rèn)認(rèn)為網(wǎng)絡(luò)丟包是由于網(wǎng)絡(luò)擁塞導(dǎo)致的,所以一般的TCP擁塞控制算法以丟包為網(wǎng)絡(luò)進(jìn)入擁塞狀態(tài)的信號(hào)霹疫。對(duì)于丟包有兩種判定方式拱绑,一種是超時(shí)重傳RTO[Retransmission Timeout]超時(shí),另一個(gè)是收到三個(gè)重復(fù)確認(rèn)ACK丽蝎。
超時(shí)重傳是TCP協(xié)議保證數(shù)據(jù)可靠性的一個(gè)重要機(jī)制猎拨,其原理是在發(fā)送一個(gè)數(shù)據(jù)以后就開啟一個(gè)計(jì)時(shí)器,在一定時(shí)間內(nèi)如果沒有得到發(fā)送數(shù)據(jù)報(bào)的ACK報(bào)文屠阻,那么就重新發(fā)送數(shù)據(jù)红省,直到發(fā)送成功為止。
但是如果發(fā)送端接收到3個(gè)以上的重復(fù)ACK国觉,TCP就意識(shí)到數(shù)據(jù)發(fā)生丟失吧恃,需要重傳。這個(gè)機(jī)制不需要等到重傳定時(shí)器超時(shí)麻诀,所以叫做快速重傳痕寓,而快速重傳后沒有使用慢啟動(dòng)算法,而是擁塞避免算法针饥,所以這又叫做快速恢復(fù)算法厂抽。
超時(shí)重傳RTO[Retransmission Timeout]超時(shí),TCP會(huì)重傳數(shù)據(jù)包丁眼。TCP認(rèn)為這種情況比較糟糕筷凤,反應(yīng)也比較強(qiáng)烈:
- 由于發(fā)生丟包,將慢啟動(dòng)閾值ssthresh設(shè)置為當(dāng)前cwnd的一半苞七,即ssthresh = cwnd / 2.
- cwnd重置為1
- 進(jìn)入慢啟動(dòng)過程
最為早期的TCP Tahoe算法就使用上述處理辦法藐守,但是由于一丟包就一切重來,導(dǎo)致cwnd重置為1蹂风,十分不利于網(wǎng)絡(luò)數(shù)據(jù)的穩(wěn)定傳遞卢厂。
所以,TCP Reno算法進(jìn)行了優(yōu)化惠啄。當(dāng)收到三個(gè)重復(fù)確認(rèn)ACK時(shí)慎恒,TCP開啟快速重傳Fast Retransmit算法,而不用等到RTO超時(shí)再進(jìn)行重傳:
- cwnd大小縮小為當(dāng)前的一半
- ssthresh設(shè)置為縮小后的cwnd大小
- 然后進(jìn)入快速恢復(fù)算法Fast Recovery撵渡。
4. 快速恢復(fù)算法 – Fast Recovery
TCP Tahoe是早期的算法融柬,所以沒有快速恢復(fù)算法,而Reno算法有趋距。在進(jìn)入快速恢復(fù)之前粒氧,cwnd和ssthresh已經(jīng)被更改為原有cwnd的一半〗诟快速恢復(fù)算法的邏輯如下:
- cwnd = cwnd + 3 * MSS外盯,加3 * MSS的原因是因?yàn)槭盏?個(gè)重復(fù)的ACK摘盆。
- 重傳DACKs指定的數(shù)據(jù)包。
- 如果再收到DACKs饱苟,那么cwnd大小增加一孩擂。
- 如果收到新的ACK,表明重傳的包成功了箱熬,那么退出快速恢復(fù)算法肋殴。將cwnd設(shè)置為ssthresh,然后進(jìn)入擁塞避免算法坦弟。
如圖所示护锤,第五個(gè)包發(fā)生了丟失,所以導(dǎo)致接收方接收到三次重復(fù)ACK酿傍,也就是ACK5烙懦。所以將ssthresh設(shè)置為當(dāng)時(shí)cwnd的一半,也就是6/2 = 3赤炒,cwnd設(shè)置為3 + 3 = 6氯析。然后重傳第五個(gè)包。當(dāng)收到新的ACK時(shí)莺褒,也就是ACK11掩缓,則退出快速恢復(fù)階段,將cwnd重新設(shè)置為當(dāng)前的ssthresh遵岩,也就是3你辣,然后進(jìn)入擁塞避免算法階段。
Reno擁塞控制過程
慢啟動(dòng)階段尘执,在沒有出現(xiàn)丟包時(shí)每收到一個(gè) ACK 就將擁塞窗口大小加一(單位是 MSS舍哄,最大單個(gè)報(bào)文段長度),每輪次發(fā)送窗口增加一倍誊锭,呈指數(shù)增長表悬,若出現(xiàn)丟包,則將擁塞窗口減半丧靡,進(jìn)入擁塞避免階段蟆沫;當(dāng)窗口達(dá)到慢啟動(dòng)閾值或出現(xiàn)丟包時(shí),進(jìn)入擁塞避免階段温治,窗口每輪次加一饭庞,呈線性增長;當(dāng)收到對(duì)一個(gè)報(bào)文的三個(gè)重復(fù)的 ACK 時(shí)罐盔,認(rèn)為這個(gè)報(bào)文的下一個(gè)報(bào)文丟失了但绕,進(jìn)入快重傳階段救崔,立即重傳丟失的報(bào)文惶看,而不是等待超時(shí)重傳捏顺;快重傳完成后進(jìn)入快恢復(fù)階段,將慢啟動(dòng)閾值修改為當(dāng)前擁塞窗口值的一半纬黎,同時(shí)擁塞窗口值等于慢啟動(dòng)閾值幅骄,然后進(jìn)入擁塞避免階段,重復(fù)上訴過程本今。
Reno 算法將收到 ACK 這一信號(hào)作為擁塞窗口增長的依據(jù)拆座,在早期低帶寬、低時(shí)延的網(wǎng)絡(luò)中能夠很好的發(fā)揮作用冠息,但是隨著網(wǎng)絡(luò)帶寬和延時(shí)的增加挪凑,Reno 的缺點(diǎn)就漸漸體現(xiàn)出來了,發(fā)送端從發(fā)送報(bào)文到收到 ACK 經(jīng)歷一個(gè) RTT逛艰,在高帶寬延時(shí)(High Bandwidth-Delay Product躏碳,BDP)網(wǎng)絡(luò)中,RTT 很大散怖,導(dǎo)致?lián)砣翱谠鲩L很慢菇绵,傳輸速度需要經(jīng)過很長時(shí)間才能達(dá)到最大帶寬,導(dǎo)致帶寬利用率降低镇眷。
Reno適用場景
適用于低延時(shí)咬最、低帶寬的網(wǎng)絡(luò)。
71.3 Cubic
Cubic擁塞控制過程
Cubic是Linux 內(nèi)核 2.6 之后的默認(rèn) TCP 擁塞控制算法欠动,使用一個(gè)立方函數(shù)(cubic function)作為擁塞窗口的增長函數(shù)永乌,其中,C 是調(diào)節(jié)因子具伍,t 是從上一次縮小擁塞窗口經(jīng)過的時(shí)間铆遭,Wmax 是上一次發(fā)生擁塞時(shí)的窗口大小,β是乘法減小因子沿猜。從函數(shù)中可以看出擁塞窗口的增長不再與 RTT 有關(guān)枚荣,而僅僅取決上次發(fā)生擁塞時(shí)的最大窗口和距離上次發(fā)生擁塞的時(shí)間間隔值。
Cubic 擁塞窗口增長曲線如下啼肩,凸曲線部分為穩(wěn)定增長階段橄妆,凹曲線部分為最大帶寬探測階段。如圖 2 所示祈坠,在剛開始時(shí)害碾,擁塞窗口增長很快,在接近 Wmax 口時(shí)赦拘,增長速度變的平緩慌随,避免流量突增而導(dǎo)致丟包;在 Wmax 附近,擁塞窗口不再增加阁猜;之后開始緩慢地探測網(wǎng)絡(luò)最大吞吐量丸逸,保證穩(wěn)定性(在 Wmax 附近容易出現(xiàn)擁塞),在遠(yuǎn)離 Wmax 后剃袍,增大窗口增長的速度黄刚,保證了帶寬的利用率。
當(dāng)出現(xiàn)丟包時(shí)民效,將擁塞窗口進(jìn)行乘法減小憔维,再繼續(xù)開始上述增長過程。此方式可以使得擁塞窗口一直維持在 Wmax 附近畏邢,從而保證了帶寬的利用率业扒。
Cubic 算法的優(yōu)點(diǎn)在于只要沒有出現(xiàn)丟包,就不會(huì)主動(dòng)降低自己的發(fā)送速度舒萎,可以最大程度的利用網(wǎng)絡(luò)剩余帶寬凶赁,提高吞吐量,在高帶寬逆甜、低丟包率的網(wǎng)絡(luò)中可以發(fā)揮較好的性能虱肄。
但是,Cubic 同之前的擁塞控制算法一樣交煞,無法區(qū)分擁塞丟包和傳輸錯(cuò)誤丟包咏窿,只要發(fā)現(xiàn)丟包,就會(huì)減小擁塞窗口素征,降低發(fā)送速率集嵌,而事實(shí)上傳輸錯(cuò)誤丟包時(shí)網(wǎng)絡(luò)不一定發(fā)生了擁塞,但是傳輸錯(cuò)誤丟包的概率很低御毅,所以對(duì) Cubic 算法的性能影響不是很大根欧。
Cubic 算法的另一個(gè)不足之處是過于激進(jìn),在沒有出現(xiàn)丟包時(shí)會(huì)不停地增加擁塞窗口的大小端蛆,向網(wǎng)絡(luò)注入流量凤粗,將網(wǎng)絡(luò)設(shè)備的緩沖區(qū)填滿,出現(xiàn) Bufferbloat(緩沖區(qū)膨脹)今豆。由于緩沖區(qū)長期趨于飽和狀態(tài)嫌拣,新進(jìn)入網(wǎng)絡(luò)的的數(shù)據(jù)包會(huì)在緩沖區(qū)里排隊(duì),增加無謂的排隊(duì)時(shí)延呆躲,緩沖區(qū)越大异逐,時(shí)延就越高。另外 Cubic 算法在高帶寬利用率的同時(shí)依然在增加擁塞窗口插掂,間接增加了丟包率灰瞻,造成網(wǎng)絡(luò)抖動(dòng)加劇腥例。
Cubic適用場景
適用于高帶寬、低丟包率網(wǎng)絡(luò)酝润,能夠有效利用帶寬燎竖。
71.4 Vegas
Vegas擁塞控制過程
Vegas將時(shí)延 RTT 的增加作為網(wǎng)絡(luò)出現(xiàn)擁塞的信號(hào),RTT 增加袍祖,擁塞窗口減小,RTT 減小谢揪,擁塞窗口增加蕉陋。具體來說,Vegas 通過比較實(shí)際吞吐量和期望吞吐量來調(diào)節(jié)擁塞窗口的大小拨扶,
期望吞吐量:Expected = cwnd / BaseRTT凳鬓,
實(shí)際吞吐量:Actual = cwnd / RTT,
diff = (Expected-Actual) * BaseRTT患民,
BaseRTT 是所有觀測來回響應(yīng)時(shí)間的最小值缩举,一般是建立連接后所發(fā)的第一個(gè)數(shù)據(jù)包的 RTT,cwnd 是目前的擁塞窗口的大小匹颤。Vegas 定義了兩個(gè)閾值 a仅孩,b,當(dāng) diff > b 時(shí)印蓖,擁塞窗口減小辽慕,當(dāng) a <= diff <=b 時(shí),擁塞窗口不變赦肃,當(dāng) diff < a 時(shí)溅蛉,擁塞窗口增加。
Vegas 算法采用 RTT 的改變來判斷網(wǎng)絡(luò)的可用帶寬他宛,能精確地測量網(wǎng)絡(luò)的可用帶寬船侧,效率比較好。但是厅各,網(wǎng)絡(luò)中 Vegas 與其它算法共存的情況下镜撩,基于丟包的擁塞控制算法會(huì)嘗試填滿網(wǎng)絡(luò)中的緩沖區(qū),導(dǎo)致 Vegas 計(jì)算的 RTT 增大队塘,進(jìn)而降低擁塞窗口琐鲁,使得傳輸速度越來越慢,因此 Vegas 未能在 Internet 上普遍采用人灼。
Vegas適用場景
適用于網(wǎng)絡(luò)中只存在 Vegas 一種擁塞控制算法围段,競爭公平的情況。
71.5 BBR
BBR擁塞控制過程
BBR是谷歌在 2016 年提出的一種新的擁塞控制算法投放,已經(jīng)在 Youtube 服務(wù)器和谷歌跨數(shù)據(jù)中心廣域網(wǎng)上部署奈泪,據(jù) Youtube 官方數(shù)據(jù)稱,部署 BBR 后,在全球范圍內(nèi)訪問 Youtube 的延遲降低了 53%涝桅,在時(shí)延較高的發(fā)展中國家拜姿,延遲降低了 80%。目前 BBR 已經(jīng)集成到 Linux 4.9 以上版本的內(nèi)核中冯遂。
BBR 算法不將出現(xiàn)丟包或時(shí)延增加作為擁塞的信號(hào)蕊肥,而是認(rèn)為當(dāng)網(wǎng)絡(luò)上的數(shù)據(jù)包總量大于瓶頸鏈路帶寬和時(shí)延的乘積時(shí)才出現(xiàn)了擁塞,所以 BBR 也稱為基于擁塞的擁塞控制算法(Congestion-Based Congestion Control)蛤肌。BBR 算法周期性地探測網(wǎng)絡(luò)的容量壁却,交替測量一段時(shí)間內(nèi)的帶寬極大值和時(shí)延極小值饵撑,將其乘積作為作為擁塞窗口大械摺(交替測量的原因是極大帶寬和極小時(shí)延不可能同時(shí)得到塔插,帶寬極大時(shí)網(wǎng)絡(luò)被填滿造成排隊(duì)棠隐,時(shí)延必然極大钮孵,時(shí)延極小時(shí)需要數(shù)據(jù)包不被排隊(duì)直接轉(zhuǎn)發(fā)玫氢,帶寬必然極懈┘琛)号枕,使得擁塞窗口始的值始終與網(wǎng)絡(luò)的容量保持一致权悟。
由于 BBR 的擁塞窗口是精確測量出來的砸王,不會(huì)無限的增加擁塞窗口,也就不會(huì)將網(wǎng)絡(luò)設(shè)備的緩沖區(qū)填滿峦阁,避免了出現(xiàn) Bufferbloat 問題处硬,使得時(shí)延大大降低。如圖 4 所示拇派,網(wǎng)絡(luò)緩沖區(qū)被填滿時(shí)時(shí)延為 250ms荷辕,Cubic 算法會(huì)繼續(xù)增加擁塞窗口,使得時(shí)延持續(xù)增加到 500ms 并出現(xiàn)丟包件豌,整個(gè)過程 Cubic 一直處于高時(shí)延狀態(tài)疮方,而 BBR 由于不會(huì)填滿網(wǎng)絡(luò)緩沖區(qū),時(shí)延一直處于較低狀態(tài)茧彤。
由于 BBR 算法不將丟包作為擁塞信號(hào)骡显,所以在丟包率較高的網(wǎng)絡(luò)中,BBR 依然有極高的吞吐量曾掂,如圖 5 所示惫谤,在 1% 丟包率的網(wǎng)絡(luò)環(huán)境下,Cubic 的吞吐量已經(jīng)降低 90% 以上珠洗,而 BBR 的吞吐量幾乎沒有受到影響溜歪,當(dāng)丟包率大于 15% 時(shí),BBR 的吞吐量才大幅下降许蓖。
BBR 算法是反饋驅(qū)動(dòng)的蝴猪,有自主調(diào)節(jié)機(jī)制调衰,不受 TCP 擁塞控制狀態(tài)機(jī)的控制,通過測量網(wǎng)絡(luò)容量來調(diào)整擁塞窗口自阱,發(fā)送速率由自己掌控嚎莉,而傳統(tǒng)的擁塞控制算法只負(fù)責(zé)計(jì)算擁塞窗口,而不管發(fā)送速率(pacing rate)沛豌,怎么發(fā)由 TCP 自己決定趋箩,這樣會(huì)在瓶頸帶寬附近因發(fā)送速率的激增導(dǎo)致數(shù)據(jù)包排隊(duì)或出現(xiàn)丟包。
經(jīng)過測試加派,在高延時(shí)叫确、高丟包率的環(huán)境下,BBR 相對(duì)于 Cubic 算法在傳輸速度上有較大的提升哼丈,BBR 算法的不足之處在于設(shè)備隊(duì)列緩存較大時(shí)启妹,BBR 可能會(huì)競爭不過 Cubic 等比較激進(jìn)算法筛严,原因是 BBR 不主動(dòng)去占據(jù)隊(duì)列緩存醉旦,如果 Cubic 的流量長期占據(jù)隊(duì)列緩存,會(huì)使得 BBR 在多個(gè)周期內(nèi)測量的極小 RTT 增大桨啃,進(jìn)而使 BBR 的帶寬減小车胡。
BBR適用場景
適用于高帶寬、高時(shí)延照瘾、有一定丟包率的長肥網(wǎng)絡(luò)匈棘,可以有效降低傳輸時(shí)延,并保證較高的吞吐量析命。
71.6 Remy
Remy擁塞控制過程
Remy也稱為計(jì)算機(jī)生成的擁塞控制算法(computer-generated congestion-control algorithm)主卫,采用機(jī)器學(xué)習(xí)的方式生成擁塞控制算法模型。通過輸入各種參數(shù)模型(如瓶頸鏈路速率鹃愤、時(shí)延簇搅、瓶頸鏈路上的發(fā)送者數(shù)量等),使用一個(gè)目標(biāo)函數(shù)定量判斷算法的優(yōu)劣程度软吐,在生成算法的過程中瘩将,針對(duì)不同的網(wǎng)絡(luò)狀態(tài)采用不同的方式調(diào)整擁塞窗口,反復(fù)修改調(diào)節(jié)方式凹耙,直到目標(biāo)函數(shù)最優(yōu)姿现,最終會(huì)生成一個(gè)網(wǎng)絡(luò)狀態(tài)到調(diào)節(jié)方式的映射表,在真實(shí)的網(wǎng)絡(luò)中肖抱,根據(jù)特定的網(wǎng)絡(luò)環(huán)境從映射表直接選取擁塞窗口的調(diào)節(jié)方式备典。
Remy 試圖屏蔽底層網(wǎng)絡(luò)環(huán)境的差異,采用一個(gè)通用的擁塞控制算法模型來處理不同的網(wǎng)絡(luò)環(huán)境意述。這種方式比較依賴輸入的訓(xùn)練集(歷史網(wǎng)絡(luò)模型)熊经,如果訓(xùn)練集能夠全面覆蓋所有可能出現(xiàn)的網(wǎng)絡(luò)環(huán)境及擁塞調(diào)節(jié)算法泽艘,Remy 算法在應(yīng)用到真實(shí)的網(wǎng)絡(luò)環(huán)境中時(shí)能夠表現(xiàn)的很好,但是如果真實(shí)網(wǎng)絡(luò)與訓(xùn)練網(wǎng)絡(luò)差異較大镐依,Remy 算法的性能會(huì)比較差匹涮。
Remy適用場景
網(wǎng)絡(luò)環(huán)境為復(fù)雜的異構(gòu)網(wǎng)絡(luò),希望計(jì)算機(jī)能夠針對(duì)不同網(wǎng)絡(luò)場景自動(dòng)選擇合適的擁塞控制方式槐壳,要求現(xiàn)有的網(wǎng)絡(luò)模型能夠覆蓋所有可能出現(xiàn)情況然低。
72 C10K問題及解決方案
C10K,支持10000個(gè)客戶端同時(shí)連接务唐。
- 每個(gè)進(jìn)程/線程處理一個(gè)連接
- 資源占用過多雳攘,可擴(kuò)展性差
- 每個(gè)進(jìn)程/線程同時(shí)處理多個(gè)連接(IO多路復(fù)用)
- select-》poll-》epoll
73 為什么Redis的epoll是輪詢而Nginx是阻塞呢?
74 RPC和HTTP分別介紹一下枫笛,有什么區(qū)別和聯(lián)系吨灭?
最后編輯于 :?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者- 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來颜价,“玉大人涯保,你說我怎么就攤上這事≈苈祝” “怎么了夕春?”我有些...
- 文/不壞的土叔 我叫張陵,是天一觀的道長横辆。 經(jīng)常有香客問我撇他,道長,這世上最難降的妖魔是什么狈蚤? 我笑而不...
- 正文 為了忘掉前任困肩,我火速辦了婚禮,結(jié)果婚禮上脆侮,老公的妹妹穿的比我還像新娘锌畸。我一直安慰自己,他們只是感情好靖避,可當(dāng)我...
- 文/花漫 我一把揭開白布潭枣。 她就那樣靜靜地躺著比默,像睡著了一般。 火紅的嫁衣襯著肌膚如雪盆犁。 梳的紋絲不亂的頭發(fā)上命咐,一...
- 文/蒼蘭香墨 我猛地睜開眼航揉,長吁一口氣:“原來是場噩夢(mèng)啊……” “哼塞祈!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起帅涂,我...
- 序言:老撾萬榮一對(duì)情侶失蹤议薪,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后漠秋,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體笙蒙,經(jīng)...
- 正文 獨(dú)居荒郊野嶺守林人離奇死亡抵屿,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
- 正文 我和宋清朗相戀三年庆锦,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片轧葛。...
- 正文 年R本政府宣布衷笋,位于F島的核電站芳杏,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏辟宗。R本人自食惡果不足惜爵赵,卻給世界環(huán)境...
- 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望泊脐。 院中可真熱鬧空幻,春花似錦、人聲如沸容客。這莊子的主人今日做“春日...
- 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至但两,卻和暖如春鬓梅,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背谨湘。 一陣腳步聲響...
- 正文 我出身青樓谎僻,卻偏偏與公主長得像,于是被迫代替她去往敵國和親寓辱。 傳聞我的和親對(duì)象是個(gè)殘疾皇子艘绍,可洞房花燭夜當(dāng)晚...
28 數(shù)據(jù)鏈路層
29 公共網(wǎng)絡(luò)分類
- 模擬電話線路
- ADSL
- 移動(dòng)通信服務(wù)
- FTTH
- 有線電視
- 專線
- VPN
- 公共無線LAN
- X. 25
- 幀中繼
- ISDN
30 IP地址
- IP尋址
- 路由控制
- IP分包與組包
31 IP為什么要設(shè)計(jì)為面向無連接拗引?
- 簡單化,面向有連接比面向無連接復(fù)雜
- 高速化幌衣,管理連接繁瑣費(fèi)時(shí)矾削,IP要提高速度,需要連接時(shí)委托上層TCP處理豁护。
32 IPv4與IPv6
- IPv4
- 32位正整數(shù)哼凯,分4組,以.分割楚里,最多允許2^32(約43億)臺(tái)機(jī)器聯(lián)網(wǎng)
- 網(wǎng)絡(luò)標(biāo)識(shí) + 主機(jī)標(biāo)識(shí)
- 分配IP地址要去掉全部為0(IP地址無法獲知)和全部為1(廣播地址)的情況
- IP地址分為4類:
- A類:0開頭断部,0.0.0.0~127.0.0.0,后24位為主機(jī)標(biāo)識(shí)班缎,主機(jī)地址上限為16777214
- B類:10開頭蝴光,128.0.0.1~191.255.0.0她渴,后16位為主機(jī)標(biāo)識(shí),主機(jī)地址上限為65534
- C類:110開頭蔑祟,192.168.0.0~239.255.255.0趁耗,后8位為主機(jī)標(biāo)識(shí),主機(jī)地址上限為254(2^8-2)
- D類:1110開頭疆虚,224.0.0.0~239.255.255.255苛败,沒有主機(jī)標(biāo)識(shí),常用于多播
- 廣播地址:主機(jī)地址都是1
- 本地廣播:本地網(wǎng)絡(luò)內(nèi)的廣播
- 直接廣播:不同網(wǎng)絡(luò)之間的廣播
- IPv6
- IPv6是為了解決IPv4地址耗盡的問題径簿,IPv4是32位罢屈,IPv6是128位,最多支持2^128
33 IPv4首部&IPv6首部
34 DNS作用
- 域名解析牍帚,支持IPv4和IPv6
35 ARP原理(Address Resolution Protocol)
- ARP通過IP地址查找到MAC地址儡遮,只支持IPv4,IPv6可以用ICMPv6.
- IP地址和MAC地址缺一不可
36 RARP(Reverse Address Resolution Protocol)
- RARP暗赶,反地址解析協(xié)議,通過MAC地址定位IP地址肃叶。
37 ICMP原理
- 驗(yàn)證網(wǎng)絡(luò)設(shè)置是否正確蹂随、IP包是否成功送達(dá)等,便于網(wǎng)絡(luò)問題診斷因惭。
38 DHCP原理
- DHCP岳锁,Dynamic Host Configuration Protocol,自動(dòng)配置管理IP地址蹦魔,即插即用滨攻。
39 NAT原理
40 提升HTTP傳輸速率的方法沮趣?
- 壓縮傳輸?shù)膬?nèi)容編碼
- gzip(GNU zip)
- compress(UNIX系統(tǒng)的標(biāo)準(zhǔn)壓縮)
- deflate(zlib)
- identity(不進(jìn)行編碼)
- 分塊傳輸編碼
41 內(nèi)容協(xié)商機(jī)制?
內(nèi)容協(xié)商機(jī)制指的是客戶端和服務(wù)器端就響應(yīng)的資源內(nèi)容進(jìn)行交涉,然后提供給客戶端最合適的資源愕鼓。
- 服務(wù)器驅(qū)動(dòng)協(xié)商
- 客戶端驅(qū)動(dòng)協(xié)商
- 透明協(xié)商
42 端到端首部&逐跳首部
- 逐跳首部(Hop-by-hop Header):只對(duì)單次轉(zhuǎn)發(fā)有效,需提供Connection首部字段堪旧。
- Connection
- Keep-Alive
- Proxy-Authenticate
- Proxy-Authorization
- Trailer
- TE
- Transfer-Encoding
- Upgrade
- 端到端首部(End-to-end Header):必須保存在由緩存生成的響應(yīng)中涩禀,必須被轉(zhuǎn)發(fā)。
43 HTTP缺陷&HTTPS優(yōu)勢
HTTP缺陷
- 明文傳輸
- 缺乏身份驗(yàn)證
- 報(bào)文完整性問題咆繁,可能被篡改
https好處
- 加密
- 對(duì)稱加密
- AES讳推,Advanced Encryption Standard
- DES,Data Encryption Standard
- 非對(duì)稱加密
- RSA
- DH(Diffie-Hellman)
- 橢圓曲線
- 對(duì)稱加密
- 身份認(rèn)證
- 證書
- 完整性保護(hù)
- MD5
- SHA
44 HTTP身份認(rèn)證手段
- BASIC基本認(rèn)證
- 安全等級(jí)最低
- DIGEST摘要認(rèn)證
- 安全等級(jí)次低
- SSL客戶端認(rèn)證
- 安全等級(jí)高玩般,證書需要費(fèi)用
- 基于表單認(rèn)證
- Cookie
- Session
- token
45 HTTP增強(qiáng)協(xié)議
- SPDY
- Google開發(fā)的基于TCP協(xié)議的應(yīng)用層協(xié)議银觅,目的是優(yōu)化http協(xié)議的性能,核心思想是減少TCP連接數(shù)坏为。
- WebSocket
- 全雙工通信標(biāo)準(zhǔn)究驴,長連接
- websocket協(xié)議由IETF定位標(biāo)準(zhǔn)镊绪,websocket API由W3C定為標(biāo)準(zhǔn)
- WebDAV
- 基于萬維網(wǎng)的分布式文件系統(tǒng)
- HTTP2.0
- 二進(jìn)制傳輸
- 多路復(fù)用(Multiplexing):單一連接發(fā)起多重的請(qǐng)求/響應(yīng)
- 頭部壓縮
- 請(qǐng)求/響應(yīng)管線化pipeline
- 對(duì)請(qǐng)求劃分優(yōu)先級(jí)
- WebSocket
- TLS義務(wù)化
- 協(xié)商
- 流量控制
- 服務(wù)端push技術(shù)(Server Push)
- 更安全,對(duì)TLS進(jìn)行升級(jí)纳胧,網(wǎng)絡(luò)訪問用HTTPS
- 改善HTTP1.x的缺點(diǎn)
- HTTP1.0是短連接镰吆,一次只允許在一個(gè)TCP連接上發(fā)起一個(gè)請(qǐng)求,HTTP1.1的pipeline不成熟跑慕,只能部分處理請(qǐng)求并發(fā)万皿,瀏覽器也默認(rèn)不支持。
- 單向請(qǐng)求核行,只能由client發(fā)起請(qǐng)求牢硅。
- 請(qǐng)求與響應(yīng)報(bào)文首部冗余量大
- 文本傳輸,數(shù)據(jù)未壓縮芝雪,導(dǎo)致數(shù)據(jù)傳輸量大
46 構(gòu)建web內(nèi)容的技術(shù)
- 展示
- HTML/HTML5
- CSS/CSS3
- JavaScript
- 數(shù)據(jù)
- XML
- JSON
47 web攻擊技術(shù)
- 主動(dòng)攻擊
- SQL注入
- OS命令注入
- 被動(dòng)攻擊
- 跨站腳本攻擊(XSS减余,Cross-Site Scripting)
- 跨站點(diǎn)請(qǐng)求偽造(CSRF,Cross-Site Request Forgeries)
- HTTP首部注入攻擊:向首部添加內(nèi)容
- HTTP響應(yīng)截?cái)喙簦合蛑黧w添加內(nèi)容
- 郵件首部注入攻擊
- 目錄遍歷攻擊
- 遠(yuǎn)程文件包含漏洞
- 強(qiáng)制瀏覽
- 不正確的錯(cuò)誤消息處理
- 開放重定向
- 會(huì)話劫持
- 會(huì)話固定攻擊
- DNS劫持 / 域名劫持:把域名解析到錯(cuò)誤的IP地址或者惡意讓用戶訪問指定IP地址
- 其他安全漏洞
- 密碼破解
- 窮舉法 / 暴力破解法
- 字典攻擊
- 點(diǎn)擊劫持 / 界面?zhèn)窝b
- DoS攻擊 /拒絕服務(wù)攻擊
- DDoS攻擊惩系,多臺(tái)機(jī)器發(fā)起的DoS攻擊
- 后門程序
- 密碼破解
HTTPS攻擊
HTTPS攻擊多存在于中間人攻擊的環(huán)境中位岔,主要是針對(duì)HTTPS使用的壓縮算法和加密算法等進(jìn)行攻擊。
- 0x01 CRIME(Compression Ratio Info-leak Made Easy)
- 0x02 TIME(Timing Info-leak Made Easy)
- 0X03 BEAST(Browser Exploit Against SSL/TLS)
- 0x04 POODLE
中間人攻擊防御手段:
- 針對(duì)安全性要求比較高的 app堡牡,可采取客戶端預(yù)埋證書的方式鎖死證書抒抬,只有當(dāng)客戶端證書和服務(wù)端的證書完全一致的情況下才允許通信,如一些銀行類的app晤柄,但這種方式面臨一個(gè)問題擦剑,證書過期的問題,因證書有一定的有效期芥颈,當(dāng)預(yù)埋證書過期了惠勒,只有通過強(qiáng)制更新或者要求用戶下載證書來解決。
- 針對(duì)安全性要求一般的app爬坑,可采用通過校驗(yàn)域名纠屋,證書有效性、證書關(guān)鍵信息及證書鏈的方式妇垢。
48 應(yīng)用層協(xié)議
遠(yuǎn)程登錄
- Telnet
- SSH
文件傳輸
- FTP
- SFTP
電子郵件
- SMTP
- POP
- IMAP
網(wǎng)絡(luò)管理
- SNMP巾遭,Simple Network Management Protocol
- MIB,Management Information Base
- RMON闯估,Remote Monitoring
多媒體通信實(shí)現(xiàn)技術(shù)
- H. 323
- SIP
- RTP灼舍,Real-Time Protocol
- 數(shù)字壓縮技術(shù)
49 路由協(xié)議
路由控制類型
- 靜態(tài)路由:路由映射關(guān)系固定,通常手工處理涨薪。
- 動(dòng)態(tài)路由:自動(dòng)失效轉(zhuǎn)移
路由協(xié)議
路由控制范圍跟路由協(xié)議有關(guān)骑素,通常使用兩種路由協(xié)議。
- IGP刚夺,Interior Gateway Protocol献丑,內(nèi)部網(wǎng)關(guān)協(xié)議
- RIP末捣,Routing Information Protocol,路由信息協(xié)議
- RIP2
- OSPF创橄,Open Shortest Path First箩做,開放式最短路徑優(yōu)先
- EGP,Exterior Gateway Protocol妥畏,外部網(wǎng)關(guān)協(xié)議
- BGP邦邦,Border Gateway Protocol,邊界網(wǎng)關(guān)協(xié)議
路由算法
- 距離向量算法(Distance-Vector)
- 鏈路狀態(tài)算法(Link-State)
主要路由協(xié)議
50 SSO單點(diǎn)登錄原理及實(shí)現(xiàn)方案醉蚁?
單點(diǎn)登錄SSO(Single Sign On)燃辖,用戶在多系統(tǒng)環(huán)境只需要登錄一次,就可以得到其關(guān)聯(lián)系統(tǒng)的信任不用重新登錄网棍。SSO就是要解決兩個(gè)問題:
用戶憑證信息的存儲(chǔ)和驗(yàn)證黔龟。
基于Cookie作為憑證媒介
Cookie存儲(chǔ)在客戶端,客戶端登錄后服務(wù)端返回加密的cookie滥玷,用戶攜帶此cookie訪問其他子系統(tǒng)氏身,子系統(tǒng)服務(wù)端校驗(yàn)cookie,通過則允許登錄惑畴。
- cookie不安全
- 通過加密解決
- 不能跨域
- 通過JSONP解決跨域
基于Session
用redis存儲(chǔ)session實(shí)現(xiàn)sso
基于Token(JWT观谦,Jason Web Token)
JWT方案服務(wù)端不存儲(chǔ)session,服務(wù)端是無狀態(tài)的桨菜,便于擴(kuò)展。JWT的數(shù)據(jù)結(jié)構(gòu)主要分為三個(gè)部分捉偏,Header和Payload等JSON 對(duì)象也要使用 Base64URL 算法轉(zhuǎn)成字符串倒得。
- Header
Header 部分是一個(gè) JSON 對(duì)象,描述 JWT 的元數(shù)據(jù)夭禽。 - Payload
Payload部分也是一個(gè) JSON 對(duì)象霞掺,用來存放實(shí)際需要傳遞的數(shù)據(jù)。JWT 規(guī)定了7個(gè)官方字段讹躯,除了官方字段菩彬,你還可以在這個(gè)部分定義私有字段。- iss (issuer):簽發(fā)人
- exp (expiration time):過期時(shí)間
- sub (subject):主題
- aud (audience):受眾
- nbf (Not Before):生效時(shí)間
- iat (Issued At):簽發(fā)時(shí)間
- jti (JWT ID):編號(hào)
- Signature
Signature部分是對(duì)前兩部分的簽名潮梯,防止數(shù)據(jù)篡改骗灶。
JWT的特點(diǎn):
(1)JWT 默認(rèn)是不加密,但也是可以加密的秉馏。生成原始 Token 以后耙旦,可以用密鑰再加密一次。
(2)JWT 不加密的情況下萝究,不能將秘密數(shù)據(jù)寫入 JWT免都。
(3)JWT 不僅可以用于認(rèn)證锉罐,也可以用于交換信息。有效使用 JWT绕娘,可以降低服務(wù)器查詢數(shù)據(jù)庫的次數(shù)脓规。
(4)JWT 的最大缺點(diǎn)是,由于服務(wù)器不保存 session 狀態(tài)险领,因此無法在使用過程中廢止某個(gè) token侨舆,或者更改 token 的權(quán)限。也就是說舷暮,一旦 JWT 簽發(fā)了态罪,在到期之前就會(huì)始終有效,除非服務(wù)器部署額外的邏輯下面。
(5)JWT 本身包含了認(rèn)證信息复颈,一旦泄露沥割,任何人都可以獲得該令牌的所有權(quán)限。為了減少盜用在验,JWT 的有效期應(yīng)該設(shè)置得比較短。對(duì)于一些比較重要的權(quán)限渗蟹,使用時(shí)應(yīng)該再次對(duì)用戶進(jìn)行認(rèn)證块饺。
(6)為了減少盜用,JWT 不應(yīng)該使用 HTTP 協(xié)議明碼傳輸雌芽,要使用 HTTPS 協(xié)議傳輸授艰。
JWT適用場景:
一次性的身份認(rèn)證、api的鑒權(quán)等膘怕,這些場景能充分發(fā)揮jwt無狀態(tài)以及分布式驗(yàn)證的優(yōu)勢想诅。
JWT不適用的場景:
不要試圖用jwt去代替session。這種模式下其實(shí)傳統(tǒng)的session+cookie機(jī)制工作的更好,jwt因?yàn)槠錈o狀態(tài)和分布式来破,事實(shí)上只要在有效期內(nèi)篮灼,是無法作廢的,用戶的簽退更多是一個(gè)客戶端的簽退徘禁,服務(wù)端token仍然有效诅诱,你只要使用這個(gè)token,仍然可以登陸系統(tǒng)送朱。另外一個(gè)問題是續(xù)簽問題娘荡,使用token,無疑令續(xù)簽變得十分麻煩驶沼,當(dāng)然你也可以通過redis去記錄token狀態(tài)炮沐,并在用戶訪問后更新這個(gè)狀態(tài),但這就是硬生生把jwt的無狀態(tài)搞成有狀態(tài)了回怜,而這些在傳統(tǒng)的session+cookie機(jī)制中都是不需要去考慮的大年。
CAS
CAS是開源的單點(diǎn)登錄系統(tǒng),主要分為CAS client和CAS server玉雾,CAS只是說明了原理翔试,具體實(shí)現(xiàn)要自己考慮。
基于 SAML
SAML(Security Assertion Markup Language 复旬,安全斷言標(biāo)記語言)的出現(xiàn)大大簡化了 SSO 垦缅,并被 OASIS 批準(zhǔn)為 SSO 的執(zhí)行標(biāo)準(zhǔn) 。開源組織 OpenSAML 實(shí)現(xiàn)了 SAML 規(guī)范驹碍。
基于網(wǎng)關(guān)
基于OAuth2.0
51 cookie壁涎、session、token區(qū)別志秃?
51.1 cookie
cookie生成規(guī)則
- cookie是服務(wù)端生成的粹庞,在客戶端以key-value形式保存用戶信息的
- 瀏覽器F12》Storage》Cookies可以看到cookie的組成:
- Name,相當(dāng)于key
- Value洽损,當(dāng)前用戶信息
- Domain,域名
- Path革半,路徑
- Expires/Max-Age碑定,過期時(shí)間
- Size,大小
cookie使用規(guī)則
- 服務(wù)器端響應(yīng)頭中設(shè)置set-cookie
- 客戶端保存cookie信息又官,并在發(fā)送請(qǐng)求時(shí)候在請(qǐng)求頭中帶上cookies
cookie有效期
- 如果設(shè)置了cookie的有效期延刘,則在有效期內(nèi)有效,即使瀏覽器關(guān)閉了六敬,cookie也存在碘赖;
- 如果沒有設(shè)置cookie的有效期,則瀏覽器關(guān)閉cookie失效。
cookie優(yōu)缺點(diǎn)
- 優(yōu)點(diǎn)
- 可以保存用戶信息和狀態(tài)普泡,配合無狀態(tài)的http完成用戶身份驗(yàn)證
- 缺點(diǎn)
- 瀏覽器保存的cookie數(shù)量和大小有限制
- cookie信息通過header或者URL明文傳輸容易泄露或被人劫持
- cookie在客戶端保存播掷,客戶端可以關(guān)閉cookie
- 不支持跨域訪問
51.2 session
session生成規(guī)則
- session在服務(wù)端生成,以hash表的key-value形式保存在服務(wù)端的內(nèi)存中
- 一個(gè)用戶一個(gè)session撼班,一個(gè)session對(duì)應(yīng)一個(gè)sessionid歧匈,key就是sessionid,value就是session中存儲(chǔ)的用戶信息砰嘁。
session使用規(guī)則
- 客戶端請(qǐng)求服務(wù)端分配sessionid件炉,sessionid隨響應(yīng)頭set-cookie保存在客戶端的cookie中;
- 客戶端發(fā)請(qǐng)求時(shí)候帶上cookies矮湘,服務(wù)端從cookies中取出sessionid斟冕,根據(jù)sessionid找到對(duì)應(yīng)的用戶信息。
session有效期
- session默認(rèn)有效期是30分鐘缅阳,如果30分鐘內(nèi)session沒有被訪問過磕蛇,則session失效。
session優(yōu)缺點(diǎn)
- 優(yōu)點(diǎn)
- 保存在服務(wù)端中券时,比保存在客戶端要安全
- 缺點(diǎn)
- 保存在服務(wù)端內(nèi)存中孤里,當(dāng)訪問用戶很多時(shí)候內(nèi)存占用很大,性能會(huì)收到影響橘洞。
- 可擴(kuò)展性差捌袜,增加了新節(jié)點(diǎn)沒有用戶的session信息
- CORS(跨域資源共享):當(dāng)我們需要讓數(shù)據(jù)跨多臺(tái)移動(dòng)設(shè)備上使用時(shí),跨域資源的共享會(huì)是一個(gè)讓人頭疼的問題炸枣。在使用Ajax抓取另一個(gè)域的資源虏等,就可以會(huì)出現(xiàn)禁止請(qǐng)求的情況。
- CSRF(跨站請(qǐng)求偽造):用戶在訪問銀行網(wǎng)站時(shí)适肠,他們很容易受到跨站請(qǐng)求偽造的攻擊霍衫,并且能夠被利用其訪問其他的網(wǎng)站
51.3 token
token生成規(guī)則
token一般是登錄時(shí)候由服務(wù)端生成,組成規(guī)則如下:
- UUID侯养,用戶唯一身份標(biāo)識(shí)
- time敦跌,時(shí)間戳
- sign,簽名逛揩,一般是UUID+time+salt(根據(jù)hash算法生成的字符串)
- 常用固定參數(shù)柠傍,可選
token使用規(guī)則
- 用戶通過用戶名和密碼發(fā)送請(qǐng)求后,服務(wù)端生成token辩稽,隨http響應(yīng)保存在客戶端的cookies或local storage中惧笛;
- 用戶請(qǐng)求時(shí)候帶上token,服務(wù)端獲取token用于驗(yàn)證用戶身份逞泄。
token有效期
- 根據(jù)token中的時(shí)間戳跟當(dāng)前時(shí)間對(duì)比計(jì)算患整,判斷過期與否拜效,默認(rèn)有效期是7天。
token優(yōu)缺點(diǎn)
- 優(yōu)點(diǎn)
- 支持跨域訪問
- 可以在多個(gè)服務(wù)間共享各谚,不占用服務(wù)端內(nèi)存紧憾,用CPU計(jì)算時(shí)間替代session存儲(chǔ)空間,服務(wù)端可以無狀態(tài)擴(kuò)展
- 支持移動(dòng)設(shè)備
- 安全
- 缺點(diǎn)
- 需要額外的時(shí)間開銷嘲碧,CPU需要每次校驗(yàn)傳過來的token是否有效稻励。
52 OAuth2.0原理
52.1 OAuth2.0 & JWT & SSO & Shiro區(qū)別
- SSO,單點(diǎn)登錄愈涩,OAuth2.0可以用來實(shí)現(xiàn)SSO望抽。
- OAuth2.0是授權(quán)的協(xié)議、框架履婉、標(biāo)準(zhǔn)煤篙,跟OAuth1.0不兼容,核心思想是頒發(fā)令牌(token)毁腿,使得第三方應(yīng)用使用該token在特定時(shí)間辑奈、特定范圍內(nèi)訪問指定資源。
- JWT已烤,Json Web Token鸠窗,一個(gè)開放的用戶認(rèn)證標(biāo)準(zhǔn),通過Header胯究、Payload稍计、Signature生成token。
- Shiro裕循,基于java語言的安全框架臣嚣,也可以實(shí)現(xiàn)授權(quán)。
52.2 OAuth2.0四種角色
- 資源所有者(resources owner):擁有被訪問資源的用戶
- 客戶端/第三方應(yīng)用(client):第三方應(yīng)用剥哑,獲取資源服務(wù)器提供的資源
- 授權(quán)服務(wù)器(authorization server):認(rèn)證服務(wù)器硅则,提供授權(quán)許可code、令牌token等
- 資源服務(wù)器(resource server):資源服務(wù)器株婴,擁有被訪問資源的服務(wù)器怎虫,需要通過token來確定是否有權(quán)限訪問。
52.3 OAuth2.0四種授權(quán)模式
授權(quán)碼模式(authorization code)
功能最完整困介、流程最嚴(yán)密揪垄、最安全的授權(quán)模式,code保證了token的安全性逻翁,即使code被攔截,由于沒有app_secret捡鱼,也是無法通過code獲得token的八回。
應(yīng)用場景:
各大應(yīng)用內(nèi)的qq,微信,微博登錄等缠诅。比如某應(yīng)用內(nèi)的qq登錄溶浴,過程如下:
a.用戶點(diǎn)擊qq登錄,會(huì)先跳轉(zhuǎn)到qq登錄頁面管引,這時(shí)請(qǐng)求已經(jīng)跳轉(zhuǎn)到qq服務(wù)器了士败,然后用戶輸入賬號(hào)或者掃碼登錄,這時(shí)所有請(qǐng)求都在qq服務(wù)器完成褥伴。
b.用戶正確登錄后谅将,qq服務(wù)器返回用戶的code給第三方應(yīng)用,然后第三方應(yīng)用再使用code去授權(quán)服務(wù)器請(qǐng)求獲取token重慢。(這一步用戶不可見)
c.第三方應(yīng)用獲取到token后饥臂,再使用token獲取用戶的qq名稱,頭像等信息似踱。-
優(yōu)缺點(diǎn):
- 優(yōu)點(diǎn):用戶可以控制自身的一些權(quán)限是否給第三方隅熙,第三方只能獲取到用戶臨時(shí)產(chǎn)生的一個(gè)訪問的code,安全性核芽。
- 缺點(diǎn):認(rèn)證過程繁瑣囚戚。
隱式授權(quán)碼模式/簡單模式(implicit)
和授權(quán)碼模式類似,只不過少了獲取code的步驟轧简,是直接獲取令牌token的东揣,適用于公開的瀏覽器單頁應(yīng)用,令牌直接從授權(quán)服務(wù)器返回拙寡,不支持刷新令牌鼻疮,且沒有code安全保證,令牌容易因?yàn)楸粩r截竊聽而泄露借嗽。
不支持refresh token态鳖。
密碼模式(resource owner password credentials)
這種模式是最不推薦的,因?yàn)閏lient可能存了用戶密碼恶导。這種模式主要用來做遺留項(xiàng)目升級(jí)為oauth2的適配方案浆竭,當(dāng)然如果client是自家的應(yīng)用,也是可以的惨寿。支持refresh token邦泄。
客戶端憑證模式(client credentials)
這種模式直接根據(jù)client的id和密鑰即可獲取token,無需用戶參與裂垦。這種模式比較合適消費(fèi)api的后端服務(wù)顺囊,比如拉取一組用戶信息等,不支持refresh token蕉拢,主要是沒有必要特碳。
53 IO模型(AIO & NIO & BIO(同步阻塞) & 多路復(fù)用IO)
- 阻塞IO模型(BIO(Blocking IO)诚亚,同步阻塞IO,即傳統(tǒng)的IO)
用戶線程發(fā)出IO請(qǐng)求后午乓,如果數(shù)據(jù)沒有就緒就會(huì)一直阻塞等待站宗,用戶線程交出CPU,待數(shù)據(jù)就緒后益愈,內(nèi)核返回結(jié)果給用戶線程梢灭,用戶線程才會(huì)解除block狀態(tài)。 - 非阻塞IO模型(NIO(Non-blocking IO)蒸其,同步非阻塞IO敏释,不同于Java的NIO(New IO))
用戶線程會(huì)一直占用CPU輪詢內(nèi)核數(shù)據(jù)是否準(zhǔn)備就緒 - 多路復(fù)用IO模型(多路復(fù)用IO(IO Multiplexing),異步阻塞IO枣接,Reactor設(shè)計(jì)模式)
- 通過一個(gè)線程管理多個(gè)socket颂暇,只有當(dāng)socket真正有讀寫事件發(fā)生時(shí)才會(huì)占用資源進(jìn)行實(shí)際的讀寫操作,適合連接數(shù)比較多的情況但惶。
- 多路復(fù)用IO模型是通過輪詢的方式檢測是否有事件到達(dá)耳鸯,一旦事件響應(yīng)體很大,輪詢事件就會(huì)很長膀曾,導(dǎo)致后續(xù)事件遲遲得不到處理县爬,影響新的事件輪詢。
- 信號(hào)驅(qū)動(dòng)IO模型
用戶線程發(fā)起一個(gè)IO請(qǐng)求添谊,會(huì)給對(duì)應(yīng)的socket注冊(cè)一個(gè)信號(hào)函數(shù)然后繼續(xù)執(zhí)行财喳,待內(nèi)核數(shù)據(jù)準(zhǔn)備好后會(huì)發(fā)送一個(gè)信號(hào)給用戶線程,用戶線程收到信號(hào)后斩狱,便在信號(hào)函數(shù)中調(diào)用IO讀寫操作完成真實(shí)的IO請(qǐng)求操作耳高。 - 異步IO模型(AIO(Asynchronous IO),NIO2.0所踊,JDK7開始支持泌枪,異步非阻塞IO,Proactor設(shè)計(jì)模式)
異步IO是最理想的IO模型秕岛,跟信號(hào)驅(qū)動(dòng)IO不同的是碌燕,當(dāng)用戶線程收到內(nèi)核返回的信號(hào)時(shí)表示IO操作已完成,不用再去顯示調(diào)用IO操作继薛。
54 Java傳統(tǒng)IO
54.1 Java IO包
54.2 Java IO分類
54.3 Java IO & NIO
- NIO三大核心部分:Channel通道修壕、Buffer緩沖區(qū)、Selector選擇器遏考。
- IO是面向流的慈鸠,NIO是面向緩沖區(qū)的。
54.4 Java NIO比傳統(tǒng)IO的優(yōu)勢
- 傳統(tǒng)IO是BIO(Blocking IO)灌具,Java NIO是異步非阻塞IO
- Java NIO有緩沖機(jī)制:buffer和channel機(jī)制
- NIO有零拷貝(零拷貝的前提是數(shù)據(jù)不需要加工)
- NIO提供MappedByteBuffer青团,將文件直接映射到虛擬內(nèi)存像棘,提高IO吞吐能力
- NIO的IO多路復(fù)用模型、事件驅(qū)動(dòng)模型壶冒、非阻塞模型
55 Java NIO
55.1 Java NIO包
55.2 Channel
- NIO的Channel類似于IO的Stream,Stream是單向的截歉,Channel是雙向的胖腾。
- NIO的Channel有4種實(shí)現(xiàn):
- FileChannel:文件IO
- DatagramChannel:UDP
- SocketChannel:TCP Client
- ServerSocketChannel:TCP Server
55.3 Buffer
- Buffer,緩沖區(qū)瘪松,實(shí)際上是一個(gè)容器咸作,是一個(gè)連續(xù)數(shù)組,Channel提供從網(wǎng)絡(luò)或文件讀取數(shù)據(jù)的通道宵睦,但是讀寫數(shù)據(jù)都必須經(jīng)過Buffer记罚。
- 在NIO中,Buffer是頂層父類壳嚎,是抽象類桐智,常用的Buffer子類有:
- ByteBuffer
- ShortBuffer
- IntBuffer
- LongBuffer
- FloatBuffer
- DoubleBuffer
- CharBuffer
- 客戶端發(fā)送數(shù)據(jù),服務(wù)端接受數(shù)據(jù)的過程:
55.4 Selector
- Selector檢測多個(gè)Channel是否有事件發(fā)生烟馅,如果有事件發(fā)生说庭,就獲取事件針對(duì)每個(gè)事件做相應(yīng)的處理。
- 只用一個(gè)單線程就可以管理多個(gè)Channel郑趁,不用維護(hù)多個(gè)線程刊驴,避免多線程上下文切換帶來的的開銷。
56 Netty原理
- 基于Java NIO實(shí)現(xiàn)的異步事件驅(qū)動(dòng)NIO框架寡润。
- Netty的所有IO操作都是異步非阻塞的捆憎。
- 通過Future-Listener機(jī)制,用戶可以方便的主動(dòng)獲取或者通過通知機(jī)制獲得IO操作結(jié)果梭纹。
57 Netty為什么是高性能的躲惰?
- IO多路復(fù)用
- 事件驅(qū)動(dòng)
- 異步非阻塞NIO,優(yōu)于同步阻塞IO
- 高效傳輸
- 零拷貝技術(shù):transferTo
- 堆外直接內(nèi)存
- ByteBuffer采用堆外直接內(nèi)存進(jìn)行Socket讀寫栗柒,避免字節(jié)緩沖區(qū)二次拷貝礁扮;
- 多個(gè)小的Buffer可以合并成大的Buffer批量傳輸
- 內(nèi)存池
- 直接內(nèi)存分配和回收比較麻煩,為了重用緩沖區(qū)瞬沦,Netty提供了基于內(nèi)存池的緩沖區(qū)重用機(jī)制
- 高效的Reactor線程模型
- Reactor單線程模型
- 一個(gè)NIO線程處理所有IO操作
- Reactor多線程模型
- 一組NIO線程處理所有IO操作
- Acceptor線程監(jiān)聽服務(wù)端太伊,接收客戶端的TCP連接請(qǐng)求
- NIO線程池負(fù)責(zé)網(wǎng)絡(luò)IO讀寫操作
- 主從Reactor多線程模型
- 接收請(qǐng)求的是Acceptor線程池
- Reactor單線程模型
- 無鎖設(shè)計(jì)
- Netty的IO線程采用串行無鎖設(shè)計(jì),避免多線程競爭導(dǎo)致性能下降
- 高性能序列化框架protobuf
- SO_RCVBUF和SO_SNDBUF:通常建議值為128K或者256K逛钻。
- 小包封大包僚焦,防止網(wǎng)絡(luò)阻塞
- 軟中斷Hash值和CPU綁定
58 Netty為什么不支持AIO而用NIO?
- Linux系統(tǒng)AIO的實(shí)現(xiàn)底層仍然是epoll曙痘,與NIO相比芳悲,性能沒有明顯優(yōu)勢立肘;
- Windows系統(tǒng)AIO底層實(shí)現(xiàn)良好,但是Netty不看重Windows市場名扛。
59 Netty服務(wù)端通信流程
60 Netty客戶端通信流程
61 高效序列化機(jī)制
- Google protobuf > Google thrift > kryo / FST / Apache Avro / fastjson > Google Gson / Jackson > JDK
61.1 Google protobuf
-
Protocol Buffer的序列化 & 反序列化簡單 & 速度快的原因是:
- 編碼 / 解碼 方式簡單(只需要簡單的數(shù)學(xué)運(yùn)算 = 位移等等)
- 采用 Protocol Buffer 自身的框架代碼 和 編譯器 共同完成
-
Protocol Buffer的數(shù)據(jù)壓縮效果好(即序列化后的數(shù)據(jù)量體積辛履辍)的原因:
- 采用了獨(dú)特的編碼方式,如Varint肮韧、Zigzag編碼方式等等
- 采用T - L - V 的數(shù)據(jù)存儲(chǔ)方式:減少了分隔符的使用 & 數(shù)據(jù)存儲(chǔ)得緊湊
-
Google protobuf優(yōu)點(diǎn)
- 二進(jìn)制消息融蹂,性能好/效率高(空間和時(shí)間效率都很不錯(cuò))
- proto文件生成目標(biāo)代碼,簡單易用
- 序列化反序列化直接對(duì)應(yīng)程序中的數(shù)據(jù)類弄企,不需要解析后在進(jìn)行映射(XML,JSON都是這種方式)
- 支持向前兼容(新加字段采用默認(rèn)值)和向后兼容(忽略新加字段)超燃,簡化升級(jí)
- 支持多種語言(可以把proto文件看做IDL文件)
- Netty等一些框架集成
-
Google protobuf缺點(diǎn)
- 官方只支持C++,JAVA和Python語言綁定
- 二進(jìn)制可讀性差(貌似提供了Text_Fromat功能)
- 二進(jìn)制不具有自描述特性
- 默認(rèn)不具備動(dòng)態(tài)特性(可以通過動(dòng)態(tài)定義生成消息類型或者動(dòng)態(tài)編譯支持)
- 只涉及序列化和反序列化技術(shù),不涉及RPC功能(類似XML或者JSON的解析器)
61.2 Facebook thrift
-
Facebook thrift優(yōu)點(diǎn)
- 支持非常多的語言綁定
- 性能高效
- thrift文件生成目標(biāo)代碼拘领,簡單易用
- 消息定義文件支持注釋
- 數(shù)據(jù)結(jié)構(gòu)與傳輸表現(xiàn)的分離意乓,支持多種消息格式
- 包含完整的客戶端/服務(wù)端堆棧,可快速實(shí)現(xiàn)RPC
- 支持同步和異步通信
- 應(yīng)用在Facebook開源日志收集系統(tǒng)约素、淘寶實(shí)時(shí)數(shù)據(jù)傳輸平臺(tái)届良、Evernote開放接口、Quora业汰、HBase等
-
Facebook thrift缺點(diǎn)
- 和protobuf一樣不支持動(dòng)態(tài)特性
61.3 Apache Avro
-
Apache Avro優(yōu)點(diǎn)
- 二進(jìn)制消息伙窃,性能好/效率高
- 使用JSON描述模式
- 模式和數(shù)據(jù)統(tǒng)一存儲(chǔ),消息自描述样漆,不需要生成stub代碼(支持生成IDL)
- RPC調(diào)用在握手階段交換模式定義
- 包含完整的客戶端/服務(wù)端堆棧为障,可快速實(shí)現(xiàn)RPC
- 支持同步和異步通信
- 支持動(dòng)態(tài)消息
- 模式定義允許定義數(shù)據(jù)的排序(序列化時(shí)會(huì)遵循這個(gè)順序)
- 提供了基于Jetty內(nèi)核的服務(wù)基于Netty的服務(wù)
- Hadoop和Redis默認(rèn)的序列化框架
-
Apache Avro缺點(diǎn)
- 只支持Avro自己的序列化格式
- 語言綁定不如Thrift豐富
61.4 kryo
- 速度快,序列化后體積小
- 跨語言支持較復(fù)雜
- dubbox默認(rèn)的就是kryo+FST
61.5 FST
fst是完全兼容JDK序列化協(xié)議的系列化框架放祟,序列化速度大概是JDK的4-10倍鳍怨,大小是JDK大小的1/3左右。
61.6 hessian
- 默認(rèn)支持跨語言
- 較慢
61.7 json
開源的Jackson
- 相比json-lib框架跪妥,Jackson所依賴的jar包較少鞋喇,簡單易用并且性能也要相對(duì)高些。
- Jackson社區(qū)相對(duì)比較活躍眉撵,更新速度也比較快侦香。
- Jackson對(duì)于復(fù)雜類型的json轉(zhuǎn)換bean會(huì)出現(xiàn)問題,一些集合Map纽疟,List的轉(zhuǎn)換出現(xiàn)問題罐韩。
- Jackson對(duì)于復(fù)雜類型的bean轉(zhuǎn)換Json,轉(zhuǎn)換的json格式不是標(biāo)準(zhǔn)的Json格式污朽。
阿里巴巴Fastjson
- Fastjson是一個(gè)Java語言編寫的高性能的JSON處理器,由阿里巴巴公司開發(fā)散吵。
- 無依賴,不需要例外額外的jar,能夠直接跑在JDK上矾睦。
- FastJson在復(fù)雜類型的Bean轉(zhuǎn)換Json上會(huì)出現(xiàn)一些問題晦款,可能會(huì)出現(xiàn)引用的類型,導(dǎo)致Json轉(zhuǎn)換出錯(cuò)枚冗,需要制定引用缓溅。
- FastJson采用獨(dú)創(chuàng)的算法,將parse的速度提升到極致赁温,超過所有json庫肛宋。
Google的Gson
- Gson是目前功能最全的Json解析神器,Gson當(dāng)初是為因應(yīng)Google公司內(nèi)部需求而由Google自行研發(fā)而來束世,但自從在2008年五月公開發(fā)布第一版后已被許多公司或用戶應(yīng)用。
- Gson的應(yīng)用主要為toJson與fromJson兩個(gè)轉(zhuǎn)換函數(shù)床玻,無依賴毁涉,不需要例外額外的jar,能夠直接跑在JDK上锈死。
- 使用這種對(duì)象轉(zhuǎn)換之前需先創(chuàng)建好對(duì)象的類型以及其成員才能成功的將JSON字符串成功轉(zhuǎn)換成相對(duì)應(yīng)的對(duì)象贫堰。
- 類里面只要有g(shù)et和set方法,Gson完全可以將復(fù)雜類型的json到bean或bean到j(luò)son的轉(zhuǎn)換待牵,是JSON解析的神器其屏。
- Gson在功能上面無可挑剔,但是性能上面比FastJson有所差距缨该。
61.8 JDK序列化
- 無法跨語言偎行。這應(yīng)該是java序列化最致命的問題了。由于java序列化是java內(nèi)部私有的協(xié)議贰拿,其他語言不支持蛤袒,導(dǎo)致別的語言無法反序列化,這嚴(yán)重阻礙了它的應(yīng)用膨更。
- 序列后的碼流太大妙真。java序列化的大小是二進(jìn)制編碼的5倍多!
- 序列化性能太低荚守。java序列化的性能只有二進(jìn)制編碼的6.17倍珍德,可見java序列化性能實(shí)在太差了。
62 Netty Channel原理
62.1 Channel類圖
62.2 Netty傳輸方式/協(xié)議
- NIO矗漾,Non-blocking IO锈候,io.netty.channel.socket.nio,基于java.nio.channels的工具包缩功,使用選擇器作為基礎(chǔ)的方法晴及,在高連接數(shù)時(shí)使用;
- OIO,Old blocking IO虑稼,io.netty.channel.socket.oio琳钉,基于java.net的工具包,使用阻塞流蛛倦,適用于低連接數(shù)歌懒、需要低延時(shí)、阻塞時(shí)使用溯壶;
- Local及皂,io.netty.channel.local,用來在虛擬機(jī)之間本地通信且改,在同一個(gè)JVM內(nèi)通信時(shí)使用验烧;
- Embedded,io.netty.channel.embedded又跛,嵌入傳輸碍拆,它允許在沒有真正網(wǎng)絡(luò)的運(yùn)輸中使用ChannelHandler,可以非常有用的來測試ChannelHandler的實(shí)現(xiàn)慨蓝。測試ChannelHandler時(shí)使用感混。
63 Netty Buffer原理
63.1 Buffer API
ByteBuf的作用是在Netty中通過Channel傳輸數(shù)據(jù),Netty的ByteBuf相當(dāng)于JDK的ByteBuffer礼烈,只是比JDK做了很多優(yōu)化弧满。Netty的Buffer API主要有兩個(gè)接口:
- ByteBuf:字節(jié)數(shù)據(jù)容器
- ByteBuf分為讀和寫兩部分,所有數(shù)據(jù)操作都要維護(hù)數(shù)據(jù)索引此熬,根據(jù)數(shù)據(jù)索引可以順序讀或者跳讀庭呜。
- ByteBuf類型字節(jié)數(shù)組,讀和寫的開始索引都為0犀忱,讀寫索引位置相同時(shí)候再讀取會(huì)拋出異常IndexOutOfBoundsException
- ByteBuf默認(rèn)最大容量限制是Integer.MAX_VALUE
- ByteBufHolder:輔助接口疟赊,提供的方法很少,主要用于釋放資源等輔助操作
- ByteBufAllocator:類似線程池峡碉,負(fù)責(zé)分配ByteBuf實(shí)例
- Unpooled:創(chuàng)建緩沖區(qū)的工具類
- ByteBufUtil:靜態(tài)工具類
63.2 Buffer分類
- Heap Buffer(堆緩沖區(qū))
- 最常用的緩沖區(qū)近哟,數(shù)據(jù)存儲(chǔ)在JVM的堆空間,訪問非堆緩沖區(qū)的數(shù)組會(huì)導(dǎo)致UnsupportedOperationException
- 提供了直接訪問數(shù)組的方法鲫寄,通過ByteBuf.array()來獲取Byte[]數(shù)據(jù)吉执。
- Direct Buffer(直接緩沖區(qū))
- 直接緩沖區(qū)在堆外直接分配內(nèi)存,缺點(diǎn)就是內(nèi)存的分配和釋放比堆緩沖區(qū)復(fù)雜地来,Netty使用內(nèi)存池來解決戳玫。
- 直接緩沖區(qū)不支持?jǐn)?shù)組訪問數(shù)據(jù)
- Composite Buffer(復(fù)合緩沖區(qū))
- JDK的ByteBuffer沒有復(fù)合緩沖區(qū)的功能
64 Netty ChannelHandler
64.1 ChannelHandler類圖
64.2 ChannelPipeline
ChannelPipeline是ChannelHandler實(shí)例的列表,用于處理或截獲通道的接收和發(fā)送數(shù)據(jù)未斑。
64.3 ChannelHandlerContext
ChannelHandler的上下文
64.4 Channel生命周期狀態(tài)模型
- channelUnregistered
- channelRegistered
- channelActive
- channelInactive
65 Netty編解碼器codec
65.1 編碼器Encoder
- MessageToByteEncoder咕宿,消息對(duì)象到字節(jié)對(duì)象
- MessageToMessageEncoder,消息對(duì)象到消息對(duì)象
65.2 解碼器Decoder
- ByteToMessageDecoder,解碼字節(jié)到消息
- ReplayingDecoder府阀,解碼消息到字節(jié)
- MessageToMessageDecoder缆镣,解碼消息到消息
65.3 編解碼器codec
- byte-to-byte
- ByteToMessageCodec
- MessageToMessageCodec
65.4 HTTP編解碼器
- HttpRequestEncoder,將HttpRequest或HttpContent編碼成ByteBuf
- HttpRequestDecoder试浙,將ByteBuf解碼成HttpRequest和HttpContent
- HttpResponseEncoder董瞻,將HttpResponse或HttpContent編碼成ByteBuf
- HttpResponseDecoder,將ByteBuf解碼成HttpResponse和HttpContent
66 Netty對(duì)HTTP的優(yōu)化
66.1 HTTP
- 使用HTTP時(shí)候通過數(shù)據(jù)壓縮可以減少傳輸流量田巴,但是壓縮數(shù)據(jù)會(huì)增加CPU負(fù)載钠糊,Netty支持兩種數(shù)據(jù)壓縮方式:gzip和deflate
66.2 HTTPS
- 網(wǎng)絡(luò)傳輸?shù)闹匾獢?shù)據(jù)要加密,Netty提供了SSLHandler可以實(shí)現(xiàn)加密壹哺。
66.3 WebSocket
- WebSocket是全雙工傳輸數(shù)據(jù)抄伍,不需要請(qǐng)求-響應(yīng)模式,早期的WebSocket只能傳輸文本數(shù)據(jù)管宵,現(xiàn)在也能傳輸二進(jìn)制數(shù)據(jù)逝慧。
- Netty中的WebSocket類型有:
- BinaryWebSocketFrame,包含二進(jìn)制數(shù)據(jù)
- TextWebSocketFrame啄糙,包含文本數(shù)據(jù)
- ContinuationWebSocketFrame,包含二進(jìn)制數(shù)據(jù)或文本數(shù)據(jù)云稚,BinaryWebSocketFrame和
- TextWebSocketFrame的結(jié)合體
- CloseWebSocketFrame隧饼,WebSocketFrame代表一個(gè)關(guān)閉請(qǐng)求,包含關(guān)閉狀態(tài)碼和短語
- PingWebSocketFrame静陈,WebSocketFrame要求PongWebSocketFrame發(fā)送數(shù)據(jù)
- PongWebSocketFrame燕雁,WebSocketFrame要求PingWebSocketFrame響應(yīng)
66.4 SPDY
- Google開發(fā)的基于TCP的應(yīng)用層協(xié)議,對(duì)HTTP協(xié)議的增加鲸拥,采用多路復(fù)用拐格、請(qǐng)求優(yōu)先級(jí)、HTTP報(bào)文頭壓縮刑赶、強(qiáng)制使用SSL加密等手段提高網(wǎng)絡(luò)速度捏浊。
66.5 Netty處理空閑連接和超時(shí)
- IdleStateHandler,當(dāng)一個(gè)通道沒有進(jìn)行讀寫或運(yùn)行了一段時(shí)間后出發(fā)IdleStateEvent
- ReadTimeoutHandler撞叨,在指定時(shí)間內(nèi)沒有接收到任何數(shù)據(jù)將拋出ReadTimeoutException
- WriteTimeoutHandler金踪,在指定時(shí)間內(nèi)有寫入數(shù)據(jù)將拋出WriteTimeoutException
66.6 Netty序列化機(jī)制
- JDK序列化
CompatibleObjectEncoder
CompactObjectInputStream
CompactObjectOutputStream
ObjectEncoder
ObjectDecoder
ObjectEncoderOutputStream
ObjectDecoderInputStream - JBOSS編組序列化:速度是JDK序列化的3倍,體積更小
CompatibleMarshallingEncoder
CompatibleMarshallingDecoder
MarshallingEncoder
MarshallingDecoder - protobuf序列化
ProtobufDecoder
ProtobufEncoder
ProtobufVarint32FrameDecoder
ProtobufVarint32LengthFieldPrepender
67 TCP粘包拆包問題
67.1 TCP為什么發(fā)生粘包拆包問題牵敷?為什么UDP不會(huì)發(fā)生粘包拆包問題胡岔?
- 粘包拆包是網(wǎng)絡(luò)底層的問題,常發(fā)生在數(shù)據(jù)鏈路層枷餐、網(wǎng)絡(luò)層靶瘸、傳輸層。
- TCP是基于字節(jié)流的,沒有邊界怨咪,且TCP首部沒有表示數(shù)據(jù)長度的字段
- UDP是基于報(bào)文的屋剑,有消息保護(hù)邊界,且UDP首部有16bit標(biāo)識(shí)報(bào)文長度惊暴,應(yīng)用層能區(qū)分開不同報(bào)文饼丘,不會(huì)發(fā)生粘包拆包問題,粘包拆包只發(fā)生在TCP協(xié)議中辽话。
- 粘包發(fā)生的原因
- 應(yīng)用程序?qū)懭霐?shù)據(jù)小于套接字緩沖區(qū)大小肄鸽,網(wǎng)卡將應(yīng)用多次寫入的數(shù)據(jù)發(fā)送到網(wǎng)絡(luò)上,這將會(huì)發(fā)生粘包油啤。
- 接收方法不及時(shí)讀取套接字緩沖區(qū)數(shù)據(jù)典徘,這將發(fā)生粘包。
- 拆包發(fā)生的原因
- 應(yīng)用程序?qū)懭氲臄?shù)據(jù)大于套接字緩沖區(qū)大小益咬,這將會(huì)發(fā)生拆包逮诲。
- 進(jìn)行MSS(最大報(bào)文長度)大小的TCP分段,當(dāng)TCP報(bào)文長度-TCP頭部長度>MSS的時(shí)候?qū)l(fā)生拆包幽告。
67.2 TCP粘包拆包解決方案
- 實(shí)際長度:發(fā)送端給每個(gè)數(shù)據(jù)包添加包首部梅鹦,首部中應(yīng)該至少包含數(shù)據(jù)包的長度,這樣接收端在接收到數(shù)據(jù)后冗锁,通過讀取包首部的長度字段齐唆,便知道每一個(gè)數(shù)據(jù)包的實(shí)際長度了。
- 固定長度:發(fā)送端將每個(gè)數(shù)據(jù)包封裝為固定長度(不夠的可以通過補(bǔ)0填充)冻河,這樣接收端每次從接收緩沖區(qū)中讀取固定長度的數(shù)據(jù)就自然而然的把每個(gè)數(shù)據(jù)包拆分開來箍邮。
- 分隔符:可以在數(shù)據(jù)包之間設(shè)置邊界,如添加特殊符號(hào)叨叙,這樣锭弊,接收端通過這個(gè)邊界就可以將不同的數(shù)據(jù)包拆分開。
67.3 Netty怎么解決粘包拆包擂错?
- 分隔符協(xié)議
- DelimiterBasedFrameDecoder味滞,解碼器,接收ByteBuf由一個(gè)或多個(gè)分隔符拆分钮呀,如NUL或換行符
- LineBasedFrameDecoder桃犬,解碼器,接收ByteBuf以分割線結(jié)束行楞,如"\n"和"\r\n"
- 長度協(xié)議
- FixedLengthFrameDecoder
- LengthFieldBasedFrameDecoder
68 Netty引導(dǎo)
68.1 引導(dǎo)的類圖
68.2 引導(dǎo)分類
- 引導(dǎo)客戶端和無連接協(xié)議:Bootstrap
Bootstrap用來連接遠(yuǎn)程主機(jī)调榄,有1個(gè)EventLoopGroup - 引導(dǎo)服務(wù)端:ServerBootstrap
ServerBootstrap用來綁定本地端口番刊,有2個(gè)EventLoopGroup
69 RESTful
69.1 RESTful定義
- REST:表述性狀態(tài)轉(zhuǎn)移辐脖,Representational State Transfer奥裸,是一種互聯(lián)網(wǎng)軟件的架構(gòu)原則
- RESTful:一個(gè)架構(gòu)如果符合REST原則就轧,它就是RESTful架構(gòu)
69.2 RESTful特點(diǎn)
- 資源(Resources):每個(gè)資源對(duì)應(yīng)一個(gè)URI,通過URI訪問資源田度。
- 表現(xiàn)層(Representation):把資源呈現(xiàn)出來的的形式妒御,叫做它的表現(xiàn)層,如XML镇饺、json等
- 狀態(tài)轉(zhuǎn)換(State Transfer):HTTP協(xié)議無狀態(tài)乎莉,HTTP操作方式:
- GET:獲取資源
- POST:新建資源(也可用于更新資源)
- PUT:更新資源
- DELETE:刪除資源
69.3 RESTful架構(gòu)
- 瀏覽器使用GET/POST/PUT/DELETE等請(qǐng)求方式對(duì)指定的URI資源進(jìn)行增刪改查操作
- 前后端分離
69.4 GET與POST請(qǐng)求區(qū)別
- 傳輸方式:get通過瀏覽器地址欄傳送,post通過報(bào)文傳送
- 數(shù)據(jù)大屑轶浴:get參數(shù)有大小限制惋啃,post沒有
- 安全性:get安全性差于post
- 冪等性:get、put监右、delete都是冪等操作边灭,post不是冪等操作
- 對(duì)于GET方式的請(qǐng)求,瀏覽器會(huì)把http header和data一并發(fā)送出去健盒,服務(wù)器響應(yīng)200(返回?cái)?shù)據(jù))绒瘦;
而對(duì)于POST,瀏覽器先發(fā)送header扣癣,服務(wù)器響應(yīng)100 continue惰帽,瀏覽器再發(fā)送data,服務(wù)器響應(yīng)200 ok(返回?cái)?shù)據(jù))父虑。也不盡然该酗,F(xiàn)irefox對(duì)post請(qǐng)求就只發(fā)一次包。
70 Netty源碼
Bootstrap or ServerBootstrap
EventLoop
EventLoopGroup
ChannelPipeline
Channel
Future or ChannelFuture
ChannelInitializer
ChannelHandler
71 TCP擁塞控制算法
71.1 TCP四大擁塞控制策略
- 基于丟包的擁塞控制:將丟包視為出現(xiàn)擁塞频轿,采取緩慢探測的方式,逐漸增大擁塞窗口烁焙,當(dāng)出現(xiàn)丟包時(shí)航邢,將擁塞窗口減小,如 Reno骄蝇、Cubic 等膳殷。
- 基于時(shí)延的擁塞控制:將時(shí)延增加視為出現(xiàn)擁塞,延時(shí)增加時(shí)增大擁塞窗口九火,延時(shí)減小時(shí)減小擁塞窗口赚窃,如 Vegas、FastTCP 等岔激。
- 基于鏈路容量的擁塞控制:實(shí)時(shí)測量網(wǎng)絡(luò)帶寬和時(shí)延勒极,認(rèn)為網(wǎng)絡(luò)上報(bào)文總量大于帶寬時(shí)延乘積時(shí)出現(xiàn)了擁塞,如 BBR虑鼎。
- 基于學(xué)習(xí)的擁塞控制:沒有特定的擁塞信號(hào)辱匿,而是借助評(píng)價(jià)函數(shù)键痛,基于訓(xùn)練數(shù)據(jù),使用機(jī)器學(xué)習(xí)的方法形成一個(gè)控制策略匾七,如 Remy絮短。
71.2 Reno
擁塞控制狀態(tài)機(jī)(Congestion Control State Machine)
Open狀態(tài)
Open狀態(tài)是擁塞控制狀態(tài)機(jī)的默認(rèn)狀態(tài)。這種狀態(tài)下昨忆,當(dāng)ACK到達(dá)時(shí)丁频,發(fā)送方根據(jù)擁塞窗口cwnd(Congestion Window)是小于還是大于慢啟動(dòng)閾值ssthresh(slow start threshold),來按照慢啟動(dòng)或者擁塞避免算法來調(diào)整擁塞窗口邑贴。Disorder狀態(tài)
當(dāng)發(fā)送方檢測到DACK(重復(fù)確認(rèn))或者SACK(選擇性確認(rèn))時(shí)席里,狀態(tài)機(jī)將轉(zhuǎn)變?yōu)镈isorder狀態(tài)。在此狀態(tài)下痢缎,發(fā)送方遵循飛行(in-flight)包守恒原則胁勺,即一個(gè)新包只有在一個(gè)老包離開網(wǎng)絡(luò)后才發(fā)送,也就是發(fā)送方收到老包的ACK后独旷,才會(huì)再發(fā)送一個(gè)新包署穗。CWR狀態(tài)
發(fā)送方接收到一個(gè)顯示擁塞通知時(shí),并不會(huì)立刻減少擁塞窗口cwnd嵌洼,而是每收到兩個(gè)ACK就減少一個(gè)段案疲,直到窗口的大小減半為止。當(dāng)cwnd正在減小并且網(wǎng)絡(luò)中有沒有重傳包時(shí)麻养,這個(gè)狀態(tài)就叫CWR(Congestion Window Reduced褐啡,擁塞窗口減少)狀態(tài)。CWR狀態(tài)可以轉(zhuǎn)變成Recovery或者Loss狀態(tài)鳖昌。Recovery狀態(tài)
當(dāng)發(fā)送方接收到足夠(推薦為三個(gè))的DACK(重復(fù)確認(rèn))后备畦,進(jìn)入該狀態(tài)。在該狀態(tài)下许昨,擁塞窗口cnwd每收到兩個(gè)ACK就減少一個(gè)段(segment)懂盐,直到cwnd等于慢啟動(dòng)閾值ssthresh,也就是剛進(jìn)入Recover狀態(tài)時(shí)cwnd的一半大小糕档。 發(fā)送方保持 Recovery 狀態(tài)直到所有進(jìn)入 Recovery狀態(tài)時(shí)正在發(fā)送的數(shù)據(jù)段都成功地被確認(rèn)莉恼,然后發(fā)送方恢復(fù)成Open狀態(tài),重傳超時(shí)有可能中斷 Recovery 狀態(tài)速那,進(jìn)入Loss狀態(tài)俐银。Loss狀態(tài)
當(dāng)一個(gè)RTO(重傳超時(shí)時(shí)間)到期后,發(fā)送方進(jìn)入Loss狀態(tài)端仰。所有正在發(fā)送的數(shù)據(jù)標(biāo)記為丟失捶惜,擁塞窗口cwnd設(shè)置為一個(gè)段(segment),發(fā)送方再次以慢啟動(dòng)算法增大擁塞窗口cwnd荔烧。
Loss 和 Recovery 狀態(tài)的區(qū)別是:Loss狀態(tài)下售躁,擁塞窗口在發(fā)送方設(shè)置為一個(gè)段后增大坞淮,而 Recovery 狀態(tài)下,擁塞窗口只能被減小陪捷。Loss 狀態(tài)不能被其他的狀態(tài)中斷回窘,因此,發(fā)送方只有在所有 Loss 開始時(shí)正在傳輸?shù)臄?shù)據(jù)都得到成功確認(rèn)后市袖,才能退到 Open 狀態(tài)啡直。
四大擁塞控制算法
Reno將擁塞控制的過程分為四個(gè)階段:慢啟動(dòng)、擁塞避免苍碟、快重傳和快恢復(fù)酒觅,是現(xiàn)有的眾多擁塞控制算法的基礎(chǔ)。
1. 慢熱啟動(dòng)算法 – Slow Start
所謂慢啟動(dòng)微峰,也就是TCP連接剛建立舷丹,一點(diǎn)一點(diǎn)地提速,試探一下網(wǎng)絡(luò)的承受能力蜓肆,以免直接擾亂了網(wǎng)絡(luò)通道的秩序颜凯。
- 連接建好的開始先初始化擁塞窗口cwnd大小為1,表明可以傳一個(gè)MSS大小的數(shù)據(jù)仗扬。
- 每當(dāng)收到一個(gè)ACK症概,cwnd大小加一,呈線性上升早芭。
- 每當(dāng)過了一個(gè)往返延遲時(shí)間RTT(Round-Trip Time)彼城,cwnd大小直接翻倍,乘以2退个,呈指數(shù)上升募壕。
- 還有一個(gè)ssthresh(slow start threshold),是一個(gè)上限语盈,當(dāng)cwnd >= ssthresh時(shí)舱馅,就會(huì)進(jìn)入“擁塞避免算法”(后面會(huì)說這個(gè)算法)。
2. 擁塞避免算法 – Congestion Avoidance
如同前邊說的黎烈,當(dāng)擁塞窗口大小cwnd大于等于慢啟動(dòng)閾值ssthresh后习柠,就進(jìn)入擁塞避免算法匀谣。算法如下:
- 收到一個(gè)ACK照棋,則cwnd = cwnd + 1 / cwnd。
- 每當(dāng)過了一個(gè)往返延遲時(shí)間RTT武翎,cwnd大小加一烈炭。
過了慢啟動(dòng)閾值后,擁塞避免算法可以避免窗口增長過快導(dǎo)致窗口擁塞宝恶,而是緩慢的增加調(diào)整到網(wǎng)絡(luò)的最佳值符隙。
3. 擁塞狀態(tài)時(shí)的算法
一般來說趴捅,TCP擁塞控制默認(rèn)認(rèn)為網(wǎng)絡(luò)丟包是由于網(wǎng)絡(luò)擁塞導(dǎo)致的,所以一般的TCP擁塞控制算法以丟包為網(wǎng)絡(luò)進(jìn)入擁塞狀態(tài)的信號(hào)霹疫。對(duì)于丟包有兩種判定方式拱绑,一種是超時(shí)重傳RTO[Retransmission Timeout]超時(shí),另一個(gè)是收到三個(gè)重復(fù)確認(rèn)ACK丽蝎。
超時(shí)重傳是TCP協(xié)議保證數(shù)據(jù)可靠性的一個(gè)重要機(jī)制猎拨,其原理是在發(fā)送一個(gè)數(shù)據(jù)以后就開啟一個(gè)計(jì)時(shí)器,在一定時(shí)間內(nèi)如果沒有得到發(fā)送數(shù)據(jù)報(bào)的ACK報(bào)文屠阻,那么就重新發(fā)送數(shù)據(jù)红省,直到發(fā)送成功為止。
但是如果發(fā)送端接收到3個(gè)以上的重復(fù)ACK国觉,TCP就意識(shí)到數(shù)據(jù)發(fā)生丟失吧恃,需要重傳。這個(gè)機(jī)制不需要等到重傳定時(shí)器超時(shí)麻诀,所以叫做快速重傳痕寓,而快速重傳后沒有使用慢啟動(dòng)算法,而是擁塞避免算法针饥,所以這又叫做快速恢復(fù)算法厂抽。
超時(shí)重傳RTO[Retransmission Timeout]超時(shí),TCP會(huì)重傳數(shù)據(jù)包丁眼。TCP認(rèn)為這種情況比較糟糕筷凤,反應(yīng)也比較強(qiáng)烈:
- 由于發(fā)生丟包,將慢啟動(dòng)閾值ssthresh設(shè)置為當(dāng)前cwnd的一半苞七,即ssthresh = cwnd / 2.
- cwnd重置為1
- 進(jìn)入慢啟動(dòng)過程
最為早期的TCP Tahoe算法就使用上述處理辦法藐守,但是由于一丟包就一切重來,導(dǎo)致cwnd重置為1蹂风,十分不利于網(wǎng)絡(luò)數(shù)據(jù)的穩(wěn)定傳遞卢厂。
所以,TCP Reno算法進(jìn)行了優(yōu)化惠啄。當(dāng)收到三個(gè)重復(fù)確認(rèn)ACK時(shí)慎恒,TCP開啟快速重傳Fast Retransmit算法,而不用等到RTO超時(shí)再進(jìn)行重傳:
- cwnd大小縮小為當(dāng)前的一半
- ssthresh設(shè)置為縮小后的cwnd大小
- 然后進(jìn)入快速恢復(fù)算法Fast Recovery撵渡。
4. 快速恢復(fù)算法 – Fast Recovery
TCP Tahoe是早期的算法融柬,所以沒有快速恢復(fù)算法,而Reno算法有趋距。在進(jìn)入快速恢復(fù)之前粒氧,cwnd和ssthresh已經(jīng)被更改為原有cwnd的一半〗诟快速恢復(fù)算法的邏輯如下:
- cwnd = cwnd + 3 * MSS外盯,加3 * MSS的原因是因?yàn)槭盏?個(gè)重復(fù)的ACK摘盆。
- 重傳DACKs指定的數(shù)據(jù)包。
- 如果再收到DACKs饱苟,那么cwnd大小增加一孩擂。
- 如果收到新的ACK,表明重傳的包成功了箱熬,那么退出快速恢復(fù)算法肋殴。將cwnd設(shè)置為ssthresh,然后進(jìn)入擁塞避免算法坦弟。
如圖所示护锤,第五個(gè)包發(fā)生了丟失,所以導(dǎo)致接收方接收到三次重復(fù)ACK酿傍,也就是ACK5烙懦。所以將ssthresh設(shè)置為當(dāng)時(shí)cwnd的一半,也就是6/2 = 3赤炒,cwnd設(shè)置為3 + 3 = 6氯析。然后重傳第五個(gè)包。當(dāng)收到新的ACK時(shí)莺褒,也就是ACK11掩缓,則退出快速恢復(fù)階段,將cwnd重新設(shè)置為當(dāng)前的ssthresh遵岩,也就是3你辣,然后進(jìn)入擁塞避免算法階段。
Reno擁塞控制過程
慢啟動(dòng)階段尘执,在沒有出現(xiàn)丟包時(shí)每收到一個(gè) ACK 就將擁塞窗口大小加一(單位是 MSS舍哄,最大單個(gè)報(bào)文段長度),每輪次發(fā)送窗口增加一倍誊锭,呈指數(shù)增長表悬,若出現(xiàn)丟包,則將擁塞窗口減半丧靡,進(jìn)入擁塞避免階段蟆沫;當(dāng)窗口達(dá)到慢啟動(dòng)閾值或出現(xiàn)丟包時(shí),進(jìn)入擁塞避免階段温治,窗口每輪次加一饭庞,呈線性增長;當(dāng)收到對(duì)一個(gè)報(bào)文的三個(gè)重復(fù)的 ACK 時(shí)罐盔,認(rèn)為這個(gè)報(bào)文的下一個(gè)報(bào)文丟失了但绕,進(jìn)入快重傳階段救崔,立即重傳丟失的報(bào)文惶看,而不是等待超時(shí)重傳捏顺;快重傳完成后進(jìn)入快恢復(fù)階段,將慢啟動(dòng)閾值修改為當(dāng)前擁塞窗口值的一半纬黎,同時(shí)擁塞窗口值等于慢啟動(dòng)閾值幅骄,然后進(jìn)入擁塞避免階段,重復(fù)上訴過程本今。
Reno 算法將收到 ACK 這一信號(hào)作為擁塞窗口增長的依據(jù)拆座,在早期低帶寬、低時(shí)延的網(wǎng)絡(luò)中能夠很好的發(fā)揮作用冠息,但是隨著網(wǎng)絡(luò)帶寬和延時(shí)的增加挪凑,Reno 的缺點(diǎn)就漸漸體現(xiàn)出來了,發(fā)送端從發(fā)送報(bào)文到收到 ACK 經(jīng)歷一個(gè) RTT逛艰,在高帶寬延時(shí)(High Bandwidth-Delay Product躏碳,BDP)網(wǎng)絡(luò)中,RTT 很大散怖,導(dǎo)致?lián)砣翱谠鲩L很慢菇绵,傳輸速度需要經(jīng)過很長時(shí)間才能達(dá)到最大帶寬,導(dǎo)致帶寬利用率降低镇眷。
Reno適用場景
適用于低延時(shí)咬最、低帶寬的網(wǎng)絡(luò)。
71.3 Cubic
Cubic擁塞控制過程
Cubic是Linux 內(nèi)核 2.6 之后的默認(rèn) TCP 擁塞控制算法欠动,使用一個(gè)立方函數(shù)(cubic function)作為擁塞窗口的增長函數(shù)永乌,其中,C 是調(diào)節(jié)因子具伍,t 是從上一次縮小擁塞窗口經(jīng)過的時(shí)間铆遭,Wmax 是上一次發(fā)生擁塞時(shí)的窗口大小,β是乘法減小因子沿猜。從函數(shù)中可以看出擁塞窗口的增長不再與 RTT 有關(guān)枚荣,而僅僅取決上次發(fā)生擁塞時(shí)的最大窗口和距離上次發(fā)生擁塞的時(shí)間間隔值。
Cubic 擁塞窗口增長曲線如下啼肩,凸曲線部分為穩(wěn)定增長階段橄妆,凹曲線部分為最大帶寬探測階段。如圖 2 所示祈坠,在剛開始時(shí)害碾,擁塞窗口增長很快,在接近 Wmax 口時(shí)赦拘,增長速度變的平緩慌随,避免流量突增而導(dǎo)致丟包;在 Wmax 附近,擁塞窗口不再增加阁猜;之后開始緩慢地探測網(wǎng)絡(luò)最大吞吐量丸逸,保證穩(wěn)定性(在 Wmax 附近容易出現(xiàn)擁塞),在遠(yuǎn)離 Wmax 后剃袍,增大窗口增長的速度黄刚,保證了帶寬的利用率。
當(dāng)出現(xiàn)丟包時(shí)民效,將擁塞窗口進(jìn)行乘法減小憔维,再繼續(xù)開始上述增長過程。此方式可以使得擁塞窗口一直維持在 Wmax 附近畏邢,從而保證了帶寬的利用率业扒。
Cubic 算法的優(yōu)點(diǎn)在于只要沒有出現(xiàn)丟包,就不會(huì)主動(dòng)降低自己的發(fā)送速度舒萎,可以最大程度的利用網(wǎng)絡(luò)剩余帶寬凶赁,提高吞吐量,在高帶寬逆甜、低丟包率的網(wǎng)絡(luò)中可以發(fā)揮較好的性能虱肄。
但是,Cubic 同之前的擁塞控制算法一樣交煞,無法區(qū)分擁塞丟包和傳輸錯(cuò)誤丟包咏窿,只要發(fā)現(xiàn)丟包,就會(huì)減小擁塞窗口素征,降低發(fā)送速率集嵌,而事實(shí)上傳輸錯(cuò)誤丟包時(shí)網(wǎng)絡(luò)不一定發(fā)生了擁塞,但是傳輸錯(cuò)誤丟包的概率很低御毅,所以對(duì) Cubic 算法的性能影響不是很大根欧。
Cubic 算法的另一個(gè)不足之處是過于激進(jìn),在沒有出現(xiàn)丟包時(shí)會(huì)不停地增加擁塞窗口的大小端蛆,向網(wǎng)絡(luò)注入流量凤粗,將網(wǎng)絡(luò)設(shè)備的緩沖區(qū)填滿,出現(xiàn) Bufferbloat(緩沖區(qū)膨脹)今豆。由于緩沖區(qū)長期趨于飽和狀態(tài)嫌拣,新進(jìn)入網(wǎng)絡(luò)的的數(shù)據(jù)包會(huì)在緩沖區(qū)里排隊(duì),增加無謂的排隊(duì)時(shí)延呆躲,緩沖區(qū)越大异逐,時(shí)延就越高。另外 Cubic 算法在高帶寬利用率的同時(shí)依然在增加擁塞窗口插掂,間接增加了丟包率灰瞻,造成網(wǎng)絡(luò)抖動(dòng)加劇腥例。
Cubic適用場景
適用于高帶寬、低丟包率網(wǎng)絡(luò)酝润,能夠有效利用帶寬燎竖。
71.4 Vegas
Vegas擁塞控制過程
Vegas將時(shí)延 RTT 的增加作為網(wǎng)絡(luò)出現(xiàn)擁塞的信號(hào),RTT 增加袍祖,擁塞窗口減小,RTT 減小谢揪,擁塞窗口增加蕉陋。具體來說,Vegas 通過比較實(shí)際吞吐量和期望吞吐量來調(diào)節(jié)擁塞窗口的大小拨扶,
期望吞吐量:Expected = cwnd / BaseRTT凳鬓,
實(shí)際吞吐量:Actual = cwnd / RTT,
diff = (Expected-Actual) * BaseRTT患民,
BaseRTT 是所有觀測來回響應(yīng)時(shí)間的最小值缩举,一般是建立連接后所發(fā)的第一個(gè)數(shù)據(jù)包的 RTT,cwnd 是目前的擁塞窗口的大小匹颤。Vegas 定義了兩個(gè)閾值 a仅孩,b,當(dāng) diff > b 時(shí)印蓖,擁塞窗口減小辽慕,當(dāng) a <= diff <=b 時(shí),擁塞窗口不變赦肃,當(dāng) diff < a 時(shí)溅蛉,擁塞窗口增加。
Vegas 算法采用 RTT 的改變來判斷網(wǎng)絡(luò)的可用帶寬他宛,能精確地測量網(wǎng)絡(luò)的可用帶寬船侧,效率比較好。但是厅各,網(wǎng)絡(luò)中 Vegas 與其它算法共存的情況下镜撩,基于丟包的擁塞控制算法會(huì)嘗試填滿網(wǎng)絡(luò)中的緩沖區(qū),導(dǎo)致 Vegas 計(jì)算的 RTT 增大队塘,進(jìn)而降低擁塞窗口琐鲁,使得傳輸速度越來越慢,因此 Vegas 未能在 Internet 上普遍采用人灼。
Vegas適用場景
適用于網(wǎng)絡(luò)中只存在 Vegas 一種擁塞控制算法围段,競爭公平的情況。
71.5 BBR
BBR擁塞控制過程
BBR是谷歌在 2016 年提出的一種新的擁塞控制算法投放,已經(jīng)在 Youtube 服務(wù)器和谷歌跨數(shù)據(jù)中心廣域網(wǎng)上部署奈泪,據(jù) Youtube 官方數(shù)據(jù)稱,部署 BBR 后,在全球范圍內(nèi)訪問 Youtube 的延遲降低了 53%涝桅,在時(shí)延較高的發(fā)展中國家拜姿,延遲降低了 80%。目前 BBR 已經(jīng)集成到 Linux 4.9 以上版本的內(nèi)核中冯遂。
BBR 算法不將出現(xiàn)丟包或時(shí)延增加作為擁塞的信號(hào)蕊肥,而是認(rèn)為當(dāng)網(wǎng)絡(luò)上的數(shù)據(jù)包總量大于瓶頸鏈路帶寬和時(shí)延的乘積時(shí)才出現(xiàn)了擁塞,所以 BBR 也稱為基于擁塞的擁塞控制算法(Congestion-Based Congestion Control)蛤肌。BBR 算法周期性地探測網(wǎng)絡(luò)的容量壁却,交替測量一段時(shí)間內(nèi)的帶寬極大值和時(shí)延極小值饵撑,將其乘積作為作為擁塞窗口大械摺(交替測量的原因是極大帶寬和極小時(shí)延不可能同時(shí)得到塔插,帶寬極大時(shí)網(wǎng)絡(luò)被填滿造成排隊(duì)棠隐,時(shí)延必然極大钮孵,時(shí)延極小時(shí)需要數(shù)據(jù)包不被排隊(duì)直接轉(zhuǎn)發(fā)玫氢,帶寬必然極懈┘琛)号枕,使得擁塞窗口始的值始終與網(wǎng)絡(luò)的容量保持一致权悟。
由于 BBR 的擁塞窗口是精確測量出來的砸王,不會(huì)無限的增加擁塞窗口,也就不會(huì)將網(wǎng)絡(luò)設(shè)備的緩沖區(qū)填滿峦阁,避免了出現(xiàn) Bufferbloat 問題处硬,使得時(shí)延大大降低。如圖 4 所示拇派,網(wǎng)絡(luò)緩沖區(qū)被填滿時(shí)時(shí)延為 250ms荷辕,Cubic 算法會(huì)繼續(xù)增加擁塞窗口,使得時(shí)延持續(xù)增加到 500ms 并出現(xiàn)丟包件豌,整個(gè)過程 Cubic 一直處于高時(shí)延狀態(tài)疮方,而 BBR 由于不會(huì)填滿網(wǎng)絡(luò)緩沖區(qū),時(shí)延一直處于較低狀態(tài)茧彤。
由于 BBR 算法不將丟包作為擁塞信號(hào)骡显,所以在丟包率較高的網(wǎng)絡(luò)中,BBR 依然有極高的吞吐量曾掂,如圖 5 所示惫谤,在 1% 丟包率的網(wǎng)絡(luò)環(huán)境下,Cubic 的吞吐量已經(jīng)降低 90% 以上珠洗,而 BBR 的吞吐量幾乎沒有受到影響溜歪,當(dāng)丟包率大于 15% 時(shí),BBR 的吞吐量才大幅下降许蓖。
BBR 算法是反饋驅(qū)動(dòng)的蝴猪,有自主調(diào)節(jié)機(jī)制调衰,不受 TCP 擁塞控制狀態(tài)機(jī)的控制,通過測量網(wǎng)絡(luò)容量來調(diào)整擁塞窗口自阱,發(fā)送速率由自己掌控嚎莉,而傳統(tǒng)的擁塞控制算法只負(fù)責(zé)計(jì)算擁塞窗口,而不管發(fā)送速率(pacing rate)沛豌,怎么發(fā)由 TCP 自己決定趋箩,這樣會(huì)在瓶頸帶寬附近因發(fā)送速率的激增導(dǎo)致數(shù)據(jù)包排隊(duì)或出現(xiàn)丟包。
經(jīng)過測試加派,在高延時(shí)叫确、高丟包率的環(huán)境下,BBR 相對(duì)于 Cubic 算法在傳輸速度上有較大的提升哼丈,BBR 算法的不足之處在于設(shè)備隊(duì)列緩存較大時(shí)启妹,BBR 可能會(huì)競爭不過 Cubic 等比較激進(jìn)算法筛严,原因是 BBR 不主動(dòng)去占據(jù)隊(duì)列緩存醉旦,如果 Cubic 的流量長期占據(jù)隊(duì)列緩存,會(huì)使得 BBR 在多個(gè)周期內(nèi)測量的極小 RTT 增大桨啃,進(jìn)而使 BBR 的帶寬減小车胡。
BBR適用場景
適用于高帶寬、高時(shí)延照瘾、有一定丟包率的長肥網(wǎng)絡(luò)匈棘,可以有效降低傳輸時(shí)延,并保證較高的吞吐量析命。
71.6 Remy
Remy擁塞控制過程
Remy也稱為計(jì)算機(jī)生成的擁塞控制算法(computer-generated congestion-control algorithm)主卫,采用機(jī)器學(xué)習(xí)的方式生成擁塞控制算法模型。通過輸入各種參數(shù)模型(如瓶頸鏈路速率鹃愤、時(shí)延簇搅、瓶頸鏈路上的發(fā)送者數(shù)量等),使用一個(gè)目標(biāo)函數(shù)定量判斷算法的優(yōu)劣程度软吐,在生成算法的過程中瘩将,針對(duì)不同的網(wǎng)絡(luò)狀態(tài)采用不同的方式調(diào)整擁塞窗口,反復(fù)修改調(diào)節(jié)方式凹耙,直到目標(biāo)函數(shù)最優(yōu)姿现,最終會(huì)生成一個(gè)網(wǎng)絡(luò)狀態(tài)到調(diào)節(jié)方式的映射表,在真實(shí)的網(wǎng)絡(luò)中肖抱,根據(jù)特定的網(wǎng)絡(luò)環(huán)境從映射表直接選取擁塞窗口的調(diào)節(jié)方式备典。
Remy 試圖屏蔽底層網(wǎng)絡(luò)環(huán)境的差異,采用一個(gè)通用的擁塞控制算法模型來處理不同的網(wǎng)絡(luò)環(huán)境意述。這種方式比較依賴輸入的訓(xùn)練集(歷史網(wǎng)絡(luò)模型)熊经,如果訓(xùn)練集能夠全面覆蓋所有可能出現(xiàn)的網(wǎng)絡(luò)環(huán)境及擁塞調(diào)節(jié)算法泽艘,Remy 算法在應(yīng)用到真實(shí)的網(wǎng)絡(luò)環(huán)境中時(shí)能夠表現(xiàn)的很好,但是如果真實(shí)網(wǎng)絡(luò)與訓(xùn)練網(wǎng)絡(luò)差異較大镐依,Remy 算法的性能會(huì)比較差匹涮。
Remy適用場景
網(wǎng)絡(luò)環(huán)境為復(fù)雜的異構(gòu)網(wǎng)絡(luò),希望計(jì)算機(jī)能夠針對(duì)不同網(wǎng)絡(luò)場景自動(dòng)選擇合適的擁塞控制方式槐壳,要求現(xiàn)有的網(wǎng)絡(luò)模型能夠覆蓋所有可能出現(xiàn)情況然低。
72 C10K問題及解決方案
C10K,支持10000個(gè)客戶端同時(shí)連接务唐。
- 每個(gè)進(jìn)程/線程處理一個(gè)連接
- 資源占用過多雳攘,可擴(kuò)展性差
- 每個(gè)進(jìn)程/線程同時(shí)處理多個(gè)連接(IO多路復(fù)用)
- select-》poll-》epoll
73 為什么Redis的epoll是輪詢而Nginx是阻塞呢?
74 RPC和HTTP分別介紹一下枫笛,有什么區(qū)別和聯(lián)系吨灭?
- 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來颜价,“玉大人涯保,你說我怎么就攤上這事≈苈祝” “怎么了夕春?”我有些...
- 文/不壞的土叔 我叫張陵,是天一觀的道長横辆。 經(jīng)常有香客問我撇他,道長,這世上最難降的妖魔是什么狈蚤? 我笑而不...
- 正文 為了忘掉前任困肩,我火速辦了婚禮,結(jié)果婚禮上脆侮,老公的妹妹穿的比我還像新娘锌畸。我一直安慰自己,他們只是感情好靖避,可當(dāng)我...
- 文/花漫 我一把揭開白布潭枣。 她就那樣靜靜地躺著比默,像睡著了一般。 火紅的嫁衣襯著肌膚如雪盆犁。 梳的紋絲不亂的頭發(fā)上命咐,一...
- 文/蒼蘭香墨 我猛地睜開眼航揉,長吁一口氣:“原來是場噩夢(mèng)啊……” “哼塞祈!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起帅涂,我...
- 序言:老撾萬榮一對(duì)情侶失蹤议薪,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后漠秋,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體笙蒙,經(jīng)...
- 正文 獨(dú)居荒郊野嶺守林人離奇死亡抵屿,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
- 正文 我和宋清朗相戀三年庆锦,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片轧葛。...
- 正文 年R本政府宣布衷笋,位于F島的核電站芳杏,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏辟宗。R本人自食惡果不足惜爵赵,卻給世界環(huán)境...
- 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望泊脐。 院中可真熱鬧空幻,春花似錦、人聲如沸容客。這莊子的主人今日做“春日...
- 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至但两,卻和暖如春鬓梅,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背谨湘。 一陣腳步聲響...
- 正文 我出身青樓谎僻,卻偏偏與公主長得像,于是被迫代替她去往敵國和親寓辱。 傳聞我的和親對(duì)象是個(gè)殘疾皇子艘绍,可洞房花燭夜當(dāng)晚...