從HTTP 2.0想到的關於傳輸層協議的一些事

來源:互聯網
上載者:User

0.HTTP協議的曆史我也不知道...
1.關於HTTP 2.0收到了訂閱的郵件,頭版是說HTTP 2.0的內容,我本人不是很關注HTTP這一塊兒,但是閑得無聊時也會瞟兩眼的。HTTP 2.0的最大改進我覺得有兩點:
第一:新增了幀層
幀層的好處在於重新分發流資訊,伺服器處理順序可以不再依賴使用者提交請求的順序了。另外就是不必一定用TCP傳輸HTTP了,實際上規範一開始就是這麼說的。
第二:HTTP頭的內容可以增量互動了
很多的HTTP頭裡面的資訊都是參數的協商,每次都要攜帶,如key/value的形式,HTTP 2.0改變了,它只攜帶新增的或者變化的內容。既然HTTP是基於請求/應答會話的,那麼何必不把參數儲存在會話中呢?類似SSL/TLS的方式。即便是IPSec這種不需連線的協議族,也只是每次傳輸一個SPI索引而已。
2.不需要設計一種新的傳輸層協議在傳輸層,只有TCP和UDP就夠了,如果想擴充,那就在UDP上擴充好了。
3.幾個關於TCP和UDP的誤區在協議改造之前,首先要澄清幾個誤區,那就是你要知道為何要使用UDP而不再使用TCP,或者反過來,你始終認為TCP比UDP好:
誤區一:UDP更高效很多人以為是因為UDP效率高,因為不需要ACK,這最有可能是從教科書上學到的,要麼就是老師親口告訴你的,但是看看你馬上就要做的事,讓UDP變得可靠,按序到達,那麼除非你發明一種不要ACK的按序到達機制,否則你的ACK機制可能比TCP的更低效。
誤區二:TCP更加健壯防攻擊這是徹頭徹尾的誤區,TCP協議頭裡面有什麼保證了安全?校正和嗎?大多數情況是IP層先替你擋了一刀而已,如果IP層去掉了防火牆,校正和,手無寸鐵的TCP將面對什麼!序號嗎?一個32位的數字而已,想讓對端接收你偽造的TCP段,你只需要構造一個序號在合理視窗範圍內且匹配五元組的段即可。事實上,TCP的協議規範中從來就沒有安全機制,雖然你確實可以在TCP選項中放一些和PKI體系相關的東西。
誤區三:TCP和UDP都不安全這實際上是一個偽命題。問題根本就不在點子上,可能IPv6的出現更加助長了持這種觀點的人的威風。TCP也好,UDP也好,只是一個傳輸層協議,它提供的是端到端的節點通訊,在IP之上提供應用的多工機制,而已。安全不是它的職責,當然也不是IP層的職責。按照嚴格分層模型,身份認證屬於會話層的職責,而資料完整性則是展示層的職責。
誤區四:TCP的低效在於其握手,慢啟動等協商反饋機制相反,基於反饋的慢啟動和快速重傳/快速恢複都是合理的,它們的目的正是探測端到端路徑的傳輸能力,TCP沒有使用顯式的NAK機制,而將丟包視為擁塞,將連續收到相同ACK視為丟包,這一環套一環的反饋機制已經是TCP可以使用的最高效的方式了,更高效的方式當然是丟包點或者擁堵點直接發送源抑制反饋訊號,但那樣會破壞簡單性原則。有人為了減少TCP短串連的握手開銷,發明了TCP重用,即TCP快速開啟機制,使得在SYN包中都可以攜帶資料,這並不是一種好方式,為何要在相同兩台端到端主機之間頻繁開啟短串連呢?為何不在期間開一條長串連呢,然後將短連線應用程式請求附著而上呢?用長串連平滑掉握手開銷才是正解,握手是為了協商參數,這點開銷都承受不起,免費的午餐一定是剩飯!難道所謂能重用的串連不是以前遺留下來的嗎?
       HTTP 1.1支援長串連,但是支援的不夠好,每個請求必須按照請求發出的順序被回應,如果兩個請求是關聯性很小的請求,第一個請求的處理延遲使得第二個請求被連累,這是傷不起的。這如何解釋??個人認為這是傳輸層協議的使用方式不對的問題而不是協議設計的問題,傳輸層只是在整個層次上提供了上層的多工機制,而這個上層並不是說一定就得是應用程式層。誰讓你把兩個GET請求塞到一個TCP串連了啊,好吧,那你可以用兩條TCP串連,也是,完全可以用多條TCP串連!但是還是有問題,問題在哪兒呢?我們來看下應用的模式。
4.應用模式的演化最初的史前年代,是沒有所謂的應用的,如何非得說有,那就是兩類,一類是檔案下載,另一類就是終端登入,看看那些著名的史前協議吧,FTP,Telnet...TCP當時和IP是在一起的,並沒有分成兩個層級,也沒有必要分開,因為不管是檔案下載還是登入,都需要嚴格的資料按序到達,那時的網路其實就是一個資料精確按序到達的網路,但當它們發展到第三個版本的時候,它們分手了,至於說它們為什麼分手,說好聽點就是分層模型的每一層只負責一類處理的職責原則,說得不那麼好聽但很容易理解一點就是出現了小三,因為當時出現了一種需求,並不需要提供按序到達的機制,但要提供資料邊界,屬於一種發後不管的需求,很多的控制報文的投遞屬於這一種,它們不需要一個長串連,但需要資料邊界,即一個報文從哪裡開始在哪裡結束,這些控制報文本身提供額外的校正機制,並不需要網路的反饋。顯然TCP-IP無法滿足這些需求,於是IP就納妾了,從而變成了TCP/IP,實際上是(TCP-UDP)/IP。
       按照搶先性原則,以後的應用要麼使用TCP,要麼使用UDP,也有很多不需要多工直接使用IP,比如很多路由協議。隨著應用的蓬勃發展,一直到HTTP 2.0之前,TCP和UDP都能應對,即便出現了很多的效率問題,但總體上都有解決的方法。但是HTTP 2.0帶來一個全新的時代,一切和以前都不同了。
       一個應用要請求一台主機上的很多資源,按照以往對會話的理解,需要建立多個會話,但是為了效率,提倡共用一條TCP串連,HTTP 2.0和以往不同的是,它加入了一個新的幀層,將每一個HTTP資料包封裝在一個幀中,每一個幀都攜帶一個流標號,這就意味著HTTP的回應不必按照請求的順序處理了,流標號可以識別一個HTTP回應對應哪個請求,然後問題還是存在,不過是出在了TCP層。雖然應用伺服器不必再按照請求順序將處理排隊,但是由於TCP串連是嚴格按序到達的,因此萬一有丟包,其後續的資料將全部被阻塞,直到丟包到達,這是TCP一直都存在的顛簸問題,玩過祖馬小遊戲的都應該體會過。在訊號不穩定的無線環境下,一個TCP流的顛簸帶來的問題是全面且嚴重的。HTTP 2.0 over TCP帶來的問題是TCP的阻塞代替了應用伺服器的阻塞。那麼怎麼解決呢?
5.會話傳輸層設想如果能有一個端到端協議,每個串連佔據一個五元組,在該串連上提供幀邊界的按序可靠到達,或者在該串連上複用多個流,每個流上按序可靠到達,這不就解決了HTTP 2.0的問題了嗎?同時解決的還有連接埠資源佔用的問題,再也不用為連接埠不夠用犯愁了。
       OSI模型中有會話層,但是TCP/IP模型沒有,實際上這個層還是必要的,如果HTTP 2.0承載於會話層而不是傳輸層,那麼傳輸層就可以用輕量級的UDP了,只要在會話層確保每一個會話按序處理即可,如果承載於傳輸層,那麼對於TCP而言,一個WEB應用的所有會話都要共用一個TCP串連,在按序處理上造成了互相牽制。
6.實現思路與措施不知道你對OpenVPN的Reliable層有沒有瞭解,這是一個活生生的例子,經過我個人的改造,在它之上實現一個基於UDP的多個流多工是很簡單的,協議封裝圖如下:
基於Reliable層的stream1----基於Reliable層的stream2----基於Reliable層的stream3
----------------------------------------------------------------------------------------------------------------------------
                          UDP協議(我使用了一對OpenSSL的BIO來代替)
----------------------------------------------------------------------------------------------------------------------------
依照,如果stream2中的一個中間資料包沒有到達,它只會阻塞stream2的後續資料包嚮應用提交,而stream1和stream3的資料包即便是在沒有到達的stream2的資料包後面到達的,只要是按序的,就可以儘快提交給應用程式層。我的這個stream的協議頭很簡單,為了方便就兩個欄位,一個標識session ID,一個標識長度,其實這個長度也是不需要的,因為Reliable層中本來就有長度。按照這個思想,還有一個引申出的協議,即按照邊界標識來提供按序到達的語義,此時協議頭中的長度欄位就是必須的了,這個引申的意義是,我只要保證協議頭中指示的長度為length的這些資料按序到達即可。如果這樣,每一個資料包都需要一個序號,但是只有length範圍內的序號用於按序到達語義,如果序號落到了length範圍內,則按照按序語義處理,否則直接提交給應用。在我的測試中,我沒有提供效能最佳化措施,我只是調通了而已,因為我覺得最佳化總是有辦法的,再說用BIO來類比丟包也不是很準確。
      之所以使用OpenVPN的Reliable層,不是因為它有多麼好,而是我比較熟悉它而已,據我對世界曆史的瞭解,輪子只在美索不達米亞被發明過一次,借用總比重新來一遍要好。整個過程就是對OpenVPN的裁剪過程,最終剩下的C檔案是:
buffer.c  error.c  interval.c  list.c  mbuf.c  memcmp.c  otime.c  packet_id.c  reliable.c  schedule.c  session_id.c  ssl.c
相應的H檔案和Makefile也要改,我只是在bio_read/write和Reliable層之間加了一個複用的機制而已。BIO真是一個好東西,類比UDP再好不過了,
6.看到些曙光了嗎寫到這裡,我有點脫離HTTP 2.0了,其實本文的大部分都不是在說HTTP 2.0,而完全是針對TCP的,HTTP 2.0運行於TCP之上真的不合適了,因為TCP的邏輯太簡單又太複雜。說它簡單是因為它依然和幾十年前一樣,僅僅適合於檔案傳輸和遠程長串連登入,說它複雜是因為針對這兩類需求以及少量的這兩類需求之外,TCP衍生了各種複雜的基於反饋的演算法,要知道,只要是反饋系統就是複雜的,動物正是有了負反饋系統而和植物區分開來!因此,如果應用邏輯越來越複雜的時候,比如如今的各類WEB應用,TCP能否作為一匹好馬就值得懷疑了,HTTP 2.0正是為了應對複雜的WEB應用而出世的,絕不能被TCP牽絆住,總的來講,TCP太重了,HTTP 2.0同樣也不輕,TCP的諸多最佳化並不是針對WEB的。舉一個最簡單的例子,TCP的目標是填充頻寬延時乘機的管道,為此它和端到端的流控機制有了衝突,接收端只可以接收N個資料,難道發送端只能發N個嗎?要知道N個資料還要在網路上跑一會兒呢!所以發送端應該發送的是N*延時個資料,可是如果延時很長的話,你能保證延時期間接收端的接收視窗保持不變嗎?特別在複雜WEB應用環境下,這個接收視窗轉瞬即變,因此又需要反饋...如果是用於檔案傳輸,就沒有問題了,因為檔案傳輸的目的是盡量填滿整個頻寬,實現最大輸送量。
       好了,說了這麼多TCP怎麼不適合HTTP 2.0,那麼我的上面的想法就一定好嗎?我不敢說,但是我覺得起碼解決了幾個問題,第一個就是你不用建立多個串連了(這實際上是HTTP 2.0解決的問題,但是本文不限於HTTP 2.0),要知道對於同一個目標,你的機器上的每個IP地址只能使用65535個連接埠,這不是你的機器的限制,而是協議的限制,在頻寬稀缺且資料量不大(載荷率很低)的年代,協議頭裡面的16位連接埠欄位要比32連接埠欄位節省很多的頻寬!也許你會覺得,你在一個連接埠上複用多個session ID,道理不也一樣嗎? 難道session ID就不怕浪費嗎?是的,它也不是取之不盡的,問題的關鍵來了,這個關鍵可能推翻IPv6的糟糕架構!
       問題是你願意橫向擴充還是願意縱向擴充。我不得不用IP層的一個現實來說明問題,因此我不得不扯到IP層。以IPv4為例,它的地址空間總是被認為有限的,人們一直擔心它會耗盡,於是IPv6的思想之一很簡單,那就是加大地址空間,一下子變成了128位,說什麼地球上每一平方可以擁有多少地址之類的宣傳性言語,其無聊性不亞於經濟大蕭條時美國總統承諾每人鍋裡面有一隻雞!這麼一來IPv6是解決了問題,但是協議棧不相容了,整個IP層要重寫,在重寫其間需要截斷整個上下層的通訊,但是這是不能截斷的,因為IP目前基本成了所有通訊的必經之路,這個很不像修路時那樣,可以向左向右改道,IP實際上是一個雙向2車道的路徑。
       有沒有辦法呢?有!那就是LISP的思想,即將IP分成兩層,外層標識位置,內層標識裝置,這樣是不是更好呢?類似IPv6的那種宣傳,LISP可以說,每一個位置都可以有2的32次方個IP地址,是不是更誘人呢?畢竟並沒有說一個位置有多大!!和IPv6不同,實現這個很簡單,只需要提供一個相容層即可,過渡很方便,如果支援LISP,那就處理,如果不支援,那就剝掉外衣直通。注意,我這裡說的可不是標準的LISP,而是基於LISP思想而對IPv4的改進。
       回到TCP/UDP的問題,我們如果採用類似的思想,是不是也不錯呢?如果一個session ID為32位,那麼一個UDP連接埠就可以承載2的32次方個session!完全滿足了當前複雜的應用需求,應用可以串連同一個UDP端點,但是發送不同的業務資料,每一個業務或者說事務都是session獨立的,互不影響。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.