程序员修神之路--简约而不简单的分布式通信基石
點(diǎn)擊“藍(lán)字”關(guān)注,領(lǐng)取架構(gòu)書(shū)籍
菜菜哥,請(qǐng)教一個(gè)問(wèn)題唄
面試又被卡住了?
還是你了解我呀,tcp協(xié)議面向連接是怎么回事呢?
這個(gè)說(shuō)詳細(xì)起來(lái),那本好幾百頁(yè)的tcp協(xié)議的書(shū)籍你倒是可以看看
分布式系統(tǒng)可以總結(jié)為是處于不同物理位置的多個(gè)進(jìn)程組成的整體,為了確保這個(gè)整體有效并且高效的對(duì)外提供服務(wù),每個(gè)節(jié)點(diǎn)之間都有可能需要進(jìn)行通信來(lái)交換信息,而這個(gè)交換信息的過(guò)程多數(shù)使用的是tcp協(xié)議。tcp協(xié)議是位于ip層之上的傳輸層協(xié)議,在這個(gè)傳輸層里有兩個(gè)比較重要的協(xié)議:tcp和udp。對(duì)于應(yīng)用層的開(kāi)發(fā)人員來(lái)說(shuō),用的最多的就是這兩個(gè)協(xié)議,這也是一些面試官必問(wèn)的知識(shí)點(diǎn)之一
無(wú)論是tcp還是udp,都是建立在ip+端口的規(guī)則之上,什么意思呢?也就是說(shuō)采用tcp和udp的進(jìn)程都需要一個(gè)端口來(lái)讀取和寫(xiě)入數(shù)據(jù)。
01
PART
TCP協(xié)議
tcp協(xié)議是可靠的協(xié)議,而且是面向連接的,建立連接的過(guò)程會(huì)經(jīng)過(guò)三次握手。為什么會(huì)是三次握手而不是二次或者四次呢?
說(shuō)到這個(gè)問(wèn)題,可以抽象出一個(gè)場(chǎng)景,怎么樣才能確定一端是和另外一端互通的呢?其實(shí)很簡(jiǎn)單,一端發(fā)送給另一端的消息能順利給我答復(fù),這就說(shuō)明兩端是聯(lián)通的。tcp協(xié)議的三次握手恰好說(shuō)明了這一點(diǎn),A和B通信,只要三次握手,A能得到B的答復(fù),B也能得到A的答復(fù)。
基于ip層發(fā)送的報(bào)文,在網(wǎng)絡(luò)中是無(wú)法確定是否正確到達(dá)對(duì)方的。tcp協(xié)議在ip協(xié)議之上添加了一系列數(shù)據(jù)結(jié)構(gòu)和算法來(lái)保證tcp的數(shù)據(jù)正確到達(dá)。
1. tcp的數(shù)據(jù)包是有編號(hào)的,這么做主要是為了解決順序問(wèn)題,如果沒(méi)有編號(hào),對(duì)方怎么確定順序呢?另外一點(diǎn),編號(hào)是為了發(fā)送方來(lái)確認(rèn)哪些包已經(jīng)正確到達(dá)對(duì)方
2. 當(dāng)tcp的數(shù)據(jù)包被接收方接收,接收方需要發(fā)送確認(rèn)包給發(fā)送方,發(fā)送方在接收到確認(rèn)包之后會(huì)把對(duì)應(yīng)的數(shù)據(jù)包做狀態(tài)修改,由于每個(gè)數(shù)據(jù)包其實(shí)有超時(shí)機(jī)制,在超時(shí)之后,發(fā)送方會(huì)進(jìn)行重試
3. tcp是面向字節(jié)流的,發(fā)送的時(shí)候發(fā)的是一個(gè)字節(jié)流,這是tcp自己的狀態(tài)維護(hù)的事情。
說(shuō)了這么多,其實(shí)可以把tcp看做是一個(gè)有狀態(tài)的協(xié)議,它可以根據(jù)網(wǎng)絡(luò)狀況,對(duì)方接收情況等諸多因素來(lái)調(diào)整自己的發(fā)送狀態(tài)。
02
PART
UPP協(xié)議
相對(duì)于tcp協(xié)議來(lái)說(shuō),udp要簡(jiǎn)單很多
1. udp協(xié)議不需要建立連接,這就意味著發(fā)送方只要知道對(duì)方的ip和端口,就可以發(fā)送,基于這一點(diǎn)可以做廣播。
2.udp協(xié)議不負(fù)責(zé)可靠交付,因?yàn)樗幌駎cp協(xié)議那樣有一堆的算法和數(shù)據(jù)結(jié)構(gòu)來(lái)做保證。?
3. udp是基于數(shù)據(jù)報(bào)形式的,一個(gè)一個(gè)的發(fā),一個(gè)一個(gè)的接收。而且udp數(shù)據(jù)的發(fā)送不會(huì)根據(jù)因?yàn)榫W(wǎng)絡(luò)環(huán)境的阻塞而改變
udp基于以上特性可以在網(wǎng)絡(luò)環(huán)境比較好或者對(duì)于丟包不敏感的應(yīng)用中使用。udp在舍棄了重傳,順序等一些列特性之后,處理速度特別快,在一些不敏感但是實(shí)時(shí)性要求比較高的場(chǎng)景中應(yīng)用非常廣泛。
03
PART
Socket
在有了tcp和udp協(xié)議之后,進(jìn)程間通信的基石就有了。但是總不能每次通信自己都需要寫(xiě)tcp的三次握手等這些復(fù)雜過(guò)程吧。為了屏蔽這些復(fù)雜的過(guò)程,使通信程序簡(jiǎn)單,在tcp和udp協(xié)議之上,便抽象出來(lái)了socket這個(gè)概念。
所謂套接字(Socket),就是對(duì)網(wǎng)絡(luò)中不同主機(jī)上的應(yīng)用進(jìn)程之間進(jìn)行雙向通信的端點(diǎn)的抽象。一個(gè)套接字就是網(wǎng)絡(luò)上進(jìn)程通信的一端,提供了應(yīng)用層進(jìn)程利用網(wǎng)絡(luò)協(xié)議交換數(shù)據(jù)的機(jī)制。從所處的地位來(lái)講,套接字上聯(lián)應(yīng)用進(jìn)程,下聯(lián)網(wǎng)絡(luò)協(xié)議棧,是應(yīng)用程序通過(guò)網(wǎng)絡(luò)協(xié)議進(jìn)行通信的接口,是應(yīng)用程序與網(wǎng)絡(luò)協(xié)議根進(jìn)行交互的接口
socket是區(qū)分服務(wù)端和客戶(hù)端的,本地的socket與遠(yuǎn)程的一個(gè)socket建立連接的過(guò)程,其實(shí)就是tcp協(xié)議三次握手的過(guò)程。一旦socket連接建立,就可以利用socket抽象出來(lái)的read或者write方法來(lái)進(jìn)行通信了。
socket需要指定使用的IP協(xié)議,還需要指定使用的是tcp還是udp協(xié)議。基于tcp協(xié)議的服務(wù)端的socket需要bind一個(gè)端口來(lái)listen并且accept客戶(hù)端的socket連接。這也是服務(wù)端socket和客戶(hù)端socket的一個(gè)區(qū)別。
對(duì)于udp來(lái)說(shuō),過(guò)程有點(diǎn)不一樣。udp是沒(méi)有連接的,一是不需要三次握手,二是不需要listen和connect,但是仍然需要ip和端口bind,要不然遠(yuǎn)端的數(shù)據(jù)到來(lái)的時(shí)候,系統(tǒng)會(huì)找不到接收程序的。UDP是沒(méi)有連接狀態(tài)的,因而不需要每次連接都建立一組Socket,而是只用一個(gè)Socket,就能夠和多個(gè)客戶(hù)端通信。也正是因?yàn)闆](méi)有連接狀態(tài),每次通信的時(shí)候,調(diào)用sendto和recvfrom,都需要傳入 IP 地址和端口。
基于tcp的socket在內(nèi)核中都有一個(gè)發(fā)送緩沖區(qū)和接收緩沖區(qū),tcp的雙工工作模式以及tcp的滑動(dòng)窗口就是依賴(lài)于這兩個(gè)獨(dú)立的buffer以及buffer的數(shù)據(jù)填充狀態(tài)。接收緩沖區(qū)把數(shù)據(jù)緩存入內(nèi)核之中,如果對(duì)應(yīng)的應(yīng)用一直沒(méi)有調(diào)用socket的read方法進(jìn)行數(shù)據(jù)讀取,則此數(shù)據(jù)會(huì)一直被緩存在接收緩沖區(qū)中,如果接收緩沖區(qū)滿(mǎn)了,便會(huì)通知對(duì)方socket,以調(diào)整對(duì)方socket的發(fā)送窗口大小,這就是滑動(dòng)窗口的實(shí)現(xiàn)。如果對(duì)方仍然持續(xù)發(fā)送數(shù)據(jù),接收方在接收緩沖區(qū)沒(méi)有被讀取的情況下將丟棄后到的數(shù)據(jù),這就是tcp的流量控制。對(duì)于udp來(lái)說(shuō),它沒(méi)有真正的發(fā)送緩沖區(qū),只要有數(shù)據(jù)就會(huì)發(fā)送,無(wú)論對(duì)方能否正常正確接收,這也是udp丟包的原因之一,但是udp的socket 和tcp的socket一樣都會(huì)有接收緩沖區(qū),而且行為也一樣。
04
PART
寫(xiě)在最后
有的面試官吹水,號(hào)稱(chēng)http長(zhǎng)連接,這個(gè)說(shuō)法其實(shí)是不準(zhǔn)確的,長(zhǎng)連接和短連接是針對(duì)tcp協(xié)議而言,http只是建立在tcp/ip協(xié)議之上的應(yīng)用層的一個(gè)協(xié)議。總體而言,tcp和udp設(shè)計(jì)的數(shù)據(jù)結(jié)構(gòu)和算法有很多,這里只是粗略的說(shuō)了一下,有興趣的同學(xué)可以去研究tcp協(xié)議那本書(shū)。
●程序員修神之路--為什么我會(huì)了SOA,你們還要逼我學(xué)微服務(wù)?
●程序員過(guò)關(guān)斬將--數(shù)據(jù)庫(kù)的樂(lè)觀鎖和悲觀鎖并非真實(shí)的鎖
●程序員修神之路--設(shè)計(jì)一套R(shí)PC框架并非易事
●程序員過(guò)關(guān)斬將--要想獲取我的用戶(hù)信息,就得按照規(guī)矩來(lái)
●程序員過(guò)關(guān)斬將--更加優(yōu)雅的Token認(rèn)證方式JWT
●程序員過(guò)關(guān)斬將--cookie和session的關(guān)系其實(shí)很簡(jiǎn)單
●程序員修神之路--用NOSql給高并發(fā)系統(tǒng)加速
●程序員修神之路--高并發(fā)系統(tǒng)設(shè)計(jì)負(fù)載均衡架構(gòu)
●程序員過(guò)關(guān)斬將--你為什么還在用存儲(chǔ)過(guò)程?
●程序員修神之路--問(wèn)世間異步為何物?
●程序員修神之路--提高網(wǎng)站的吞吐
長(zhǎng)按添加菜菜好友
關(guān)注后回復(fù):“大禮包”和“福利”,領(lǐng)取驚喜
總結(jié)
以上是生活随笔為你收集整理的程序员修神之路--简约而不简单的分布式通信基石的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 手动造轮子——为Ocelot集成Naco
- 下一篇: 一个有趣的问题, 你知道SqlDataA