稍早我們見識到net.tcp不容易偵錯的黑暗面,但net.tcp的好處在於通訊協定簡單,較HTTP簡潔輕巧,資料採二進位格式,體積比SOAP XML小。由於資料傳輸較少,預期會有較好的執行效能。但以上所說都是按理推想,我對二者資料傳輸量的真實差異感到好奇,便用Microsoft Network Monitor幫它們做了一次斷層掃瞄,分享給對二者差異有興趣的朋友。

沿用先前的範例,在WCF Client端做一點修改:

程式透過HTTP及TCP各呼叫一次GetData(0),程式執行同時開啟MNM側錄網路封包。得到HTTP傳輸內容如下:

分析其傳輸過程為:

  1. 建立TCP連線:三個封包 52+52+40=144 bytes
  2. Client傳送HTTP Post Header:395 bytes
  3. Server回覆Status 100請Client繼續送:65 bytes
  4. Client送出Post本文,以SOAP包裝的Value參數0:197 bytes
  5. Server傳回以SOAP包裝的執行結果"You entered: 0":541bytes

排除TCP連線建立過程,整個呼叫涉及四個封包,總傳輸量為395+65+197+541=1198 bytes

接著來看TCP傳輸:

圖中出現的NMF是.Net Message Framing Portocol的縮寫,是一種可取代SOAP XML的二進位資料封裝格式,用於WCF TCP及MSMQ傳輸,它被定位成非公開的WCF內部實作黑箱,所幸在MSDN仍找得到相關文件,這堆封包才沒變成天書。

TCP呼叫的傳輸過程為:

  1. 建立TCP連線:三個封包 52+52+40=144 bytes
  2. Client送出一個NFM Preamble Message:93 bytes
  3. Server回應Preamble Ack Message:41 bytes (下一個TCP控制封包略過不計)
  4. Client送出內含呼叫參數的Sized Envelop Message:378 bytes
  5. Server回應內含執行結果"You entered: 0"的Sized Envelop Message:212 bytes (如下圖)

排除TCP連線建立過程,整個呼叫也涉及四個封包,總傳輸量為93+41+378+212=724 bytes

在這個單次呼叫案例中,TCP傳輸比HTTP傳輸少了474 bytes,資料量只有HTTP傳輸的60%。

接著我們再調整程式,建立Service1Client後連呼叫三次GetData()

比較二者傳輸:(我用紅黃藍底色標出三次呼叫的封包)

 

結果顯示NFM的Preamble Message及Preamble Ack Message只需傳送一次,之後每次GetData()只需兩個封包,而且我還注意到第二次跟第三次的Request與Response的封包都比第一次小(378->263、212->116),比對內容,第二、三次的封包省略掉某些內容(可能先前傳過就不再傳,而HTTP第一個封包也從395->371,其他未變),因此三次呼叫的傳輸量為:

HTTP:395+65+197+541+371+65+197+541+371+65+197+541=3546

TCP:93+41+378+212+263+116+264+116=1483

TCP的傳輸量只有HTTP的41.8%。由此可得,TCP在傳輸效率上大勝HTTP,不難想見此一資料量差距對執行效能的影響。

結論:WCF應用於Intranet時,若Client/Server未受防火牆阻隔,TCP是較佳的選擇。


Comments

# by player

請問Http的部分, 有把ASP.NET預設的幾個HTTP Response Headers給關掉嗎? 例如 Server, X-Powered-By, X-AspNet-Version

# by Joney

這應該是 HTTP & MFP (.NET Message Framing Protocol) 的比較?? 通常提到 TCP 是在說 TCP/IP 這個通訊協定。

# by Jeffrey

to player,實驗以預設大家使用WCF HTTP的方式運作,經過一些微調可以讓HTTP更有效率一點,結論傾向「若可走TCP,就不要用HTTP」,暫不考慮非HTTP/HTTPS不可的情境,故未在改善HTTP效能著墨。 to Joney,文章所討論只聚焦WCF,嚴格來說是basicHttpBinding與netTcpBinding的比較,為求簡化寫成HTTP vs TCP,我想熟悉WCF的讀者可意會,希望沒有造成誤解。

Post a comment