成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

有關Http持久連接的一切,卷給你看

網絡 通信技術
HTTP Keep-Alive 是在應用層對TCP連接進行滑動續約復用, 如果客戶端/服務器穩定續約,就成了名副其實的長連接。

[[438351]]

上文中我的結論是: HTTP Keep-Alive 是在應用層對TCP連接進行滑動續約復用, 如果客戶端/服務器穩定續約,就成了名副其實的長連接。

目前所有的Http網絡庫都默認開啟了HTTP Keep-Alive,今天我們從底層TCP連接和排障角度撕碎HTTP持久連接。

“我只是一個寫web程序的猿,我為什么要知道這么多??????”。

使用go語言倒騰一個httpServer/httpClient,粗略聊一聊go的使用風格。

使用go語言net/http包快速搭建httpserver,注入用于記錄請求日志的Handler

  1. package main 
  2.  
  3. import ( 
  4.  "fmt" 
  5.  "log" 
  6.  "net/http" 
  7.  
  8. // IndexHandler記錄請求的基本信息: 請關注r.RemoteAddr 
  9. func Index(w http.ResponseWriter, r *http.Request) { 
  10.  fmt.Println("receive a request from:", r.RemoteAddr, r.Header) 
  11.  w.Write([]byte("ok")) 
  12.  
  13. // net/http 默認開啟持久連接 
  14. func main() {  
  15.  fmt.Printf("Starting server at port 8081\n"
  16.  if err := http.ListenAndServe(":8081", http.HandlerFunc(Index)); err != nil { 
  17.   log.Fatal(err) 
  18.  } 

ListenAndServe創建了默認的httpServer服務器,go通過首字母大小寫來控制訪問權限,如果首字母大寫,則可以被外部包訪問, 類比C#全局函數、靜態函數。

  1. func ListenAndServe(addr string, handler Handler) error { 
  2.  server := &Server{Addr: addr, Handler: handler} 
  3.  return server.ListenAndServe() 

net/http服務器默認開啟了Keep-Alive, 由Server的私有變量disableKeepAlives體現。

  1. type  Server  struct { 
  2.   ... 
  3.   disableKeepAlives int32     // accessed atomically.  
  4.   ... 

使用者也可以手動關閉Keep-Alive, SetKeepAlivesEnabled()會修改私有變量disableKeepAlives的值

  1. s := &http.Server{ 
  2.   Addr:           ":8081"
  3.   Handler: http.HandlerFunc(Index), 
  4.   ReadTimeout:    10 * time.Second
  5.   WriteTimeout:   10 * time.Second
  6.   MaxHeaderBytes: 1 << 20, 
  7.  } 
  8.  s.SetKeepAlivesEnabled(true
  9.  if err := s.ListenAndServe(); err != nil { 
  10.   log.Fatal(err) 
  11.  } 

以上也是go語言包的基本制作/使用風格。

請注意我在httpserver插入了IndexHander,記錄httpclient的基本信息。

這里有個知識點:如果httpclient建立新的TCP連接,系統會按照一定規則給你分配隨機端口。

啟動服務器程序,瀏覽器訪問localhost:8081,

服務器會收到如下日志, 圖中紅圈處表明瀏覽器使用了系統隨機的固定端口建立tcp連接。

使用net/http編寫客戶端:間隔1s向服務器發起HTTP請求

  1. package main 
  2.  
  3. import ( 
  4.  "fmt" 
  5.  "io/ioutil" 
  6.  "log" 
  7.  "net/http" 
  8.  "time" 
  9.  
  10. func main() { 
  11.  client := &http.Client{ 
  12.   Timeout: 10 * time.Second
  13.  } 
  14.  for { 
  15.   requestWithClose(client) 
  16.   time.Sleep(time.Second * 1) 
  17.  } 
  18.  
  19. func requestWithClose(client *http.Client) { 
  20.  
  21.  resp, err := client.Get("http://127.0.0.1:8081"
  22.  
  23.  if err != nil { 
  24.   fmt.Printf("error occurred while fetching page, error: %s", err.Error()) 
  25.   return 
  26.  } 
  27.  defer resp.Body.Close() 
  28.  
  29.  c, err := ioutil.ReadAll(resp.Body) 
  30.  if err != nil { 
  31.   log.Fatalf("Couldn't parse response body. %+v", err) 
  32.  } 
  33.  
  34.  fmt.Println(string(c)) 

服務器收到的請求日志如下:

圖中紅框顯示httpclient使用固定端口61799發起了http請求,客戶端/服務器維持了HTTP Keep-alive。

使用netstat -an | grep 127.0.0.1:8081可圍觀系統針對特定ip的TCP連接:客戶端系統中針對 服務端也只建立了一個tcp連接,tcp連接的端口是61799,與上文呼應。

使用Wireshark查看localhost網卡發生的tcp連接

可以看到每次http請求/響應之前均沒有tcp三次握手

tcp每次發包后,對端需要回ACK確認包

反面教材-高能預警

go的net/http明確提出:

If the Body is not both read to EOF and closed, the Client's underlying RoundTripper (typically Transport) may not be able to re-use a persistent TCP connection to the server for a subsequent "keep-alive" request.

也就是說:httpclient客戶端在每次請求結束后,如果不讀完body或者沒有關閉body, 可能會導致Keep-alive失效,也會導致goroutine泄露。

  1. //  下面的代碼沒有讀完body,導致Keep-alive失效 
  2. func requestWithClose(client *http.Client) { 
  3.    resp, err := client.Get("http://127.0.0.1:8081"
  4.    if err != nil { 
  5.     fmt.Printf("error occurred while fetching page, error: %s", err.Error()) 
  6.     return 
  7.    } 
  8.    defer resp.Body.Close() 
  9.    //_, err = ioutil.ReadAll(resp.Body) 
  10.    fmt.Println("ok"

此次服務端日志如下:

上圖紅框顯示客戶端持續使用新的隨機端口建立了TCP連接。

查看客戶端系統建立的tcp連接:

Wireshark抓包結果:

圖中紅框顯示每次HTTP請求/響應 前后均發生了三次握手、四次揮手。

全文梳理

目前已知的httpclient、httpServer均默認開啟keep-alive

禁用keep-alive或者keep-alive失效,會導致客戶端、服務器頻繁建立tcp連接, 可通過 netstat -an | grep {ip} 查看客戶機上建立的tcp連接

 

Wireshark抓包, 明確keep-alive和非Keep-alive的抓包效果

 

責任編輯:武曉燕 來源: 精益碼農
相關推薦

2022-04-02 09:38:00

CSS3flex布局方式

2022-04-27 09:28:11

HTTPExpires

2019-08-01 07:56:43

安全數據網絡安全安全分析

2017-12-30 00:23:10

容器開源

2012-12-31 11:22:58

開源開放

2019-08-20 09:24:54

Python編程語言Java

2020-09-11 10:55:10

useState組件前端

2018-01-09 20:35:11

Swift編程語言

2017-12-29 10:29:34

HTTP驅動程序

2011-04-11 10:14:09

服務器虛擬化

2021-02-28 09:47:54

軟件架構軟件開發軟件設計

2018-11-23 11:17:24

負載均衡分布式系統架構

2021-02-19 23:08:27

軟件測試軟件開發

2018-06-13 12:22:37

康普智能樓宇智慧建筑

2017-09-29 16:39:33

2017-03-23 14:51:21

HTTP緩存CDN緩存

2017-03-23 15:05:50

HTTP緩存Cookie

2016-08-31 17:24:05

大數據分析

2015-08-21 09:56:15

物聯網

2021-11-07 23:41:39

Windows 11Windows微軟
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 亚洲国产一区二区三区 | 亚洲国产看片 | 综合久久亚洲 | 在线成人av | 一级无毛片 | www国产成人免费观看视频,深夜成人网 | 欧美日韩综合一区 | 五月天国产在线 | 精品视频免费 | 久久精品国产一区 | 日韩中出 | 国产午夜精品一区二区三区在线观看 | 久久综合激情 | 2018天天干天天操 | 中文字幕av第一页 | 一区二区av | 欧美色成人 | 日批免费看 | 欧美福利 | 亚洲啪啪 | 视频一区 亚洲 | 国产精品一区在线 | 一区在线观看视频 | 涩涩视频在线观看 | 91五月天 | 天天摸天天干 | 日韩精品 | 亚洲一区二区视频在线观看 | 成人av在线播放 | 久久精品成人 | 成人国产精品 | 久久黄色| 成人av网站在线观看 | av在线免费观看网站 | 日韩一区二区在线视频 | 在线观看中文字幕视频 | www日日日 | 久久久精品视频一区二区三区 | 999热精品视频 | 久久激情网 | 亚洲欧美在线观看 |