[譯]Go net/http 逾時機制完全手冊

來源:互聯網
上載者:User

英文原始出處: The complete guide to Go net/http timeouts, 作者: Filippo Valsorda

當用Go寫HTTP的伺服器和用戶端的時候,逾時處理總是最易犯錯和最微妙的地方之一。錯誤可能來自很多地方,一個錯誤可能等待很長時間沒有結果,直到網路故障或者進程掛起。

HTTP是一個複雜的、多階段(multi-stage)協議,所以沒有一個放之四海而皆準的逾時解決方案,比如一個流服務、一個JSON API和一個Comet服務對逾時的需求都不相同, 往往預設值不是你想要的。

本文我將拆解需要逾時設定的各個階段,看看用什麼不同的方式去處理它, 包括伺服器端和用戶端。 SetDeadline

首先,你需要瞭解Go實現逾時的網路原語(primitive): Deadline (期限)。

net.Conn為Deadline提供了多個方法Set[Read|Write]Deadline(time.Time)。Deadline是一個絕對時間值,當到達這個時間的時候,所有的 I/O 操作都會失敗,返回逾時(timeout)錯誤。

Deadline不是逾時(timeout)。一旦設定它們永久生效(或者直到下一次調用SetDeadline), 不管此時串連是否被使用和怎麼用。所以如果想使用SetDeadline建立逾時機制,你不得不每次在Read/Write操作之前調用它。

你可能不想自己調用SetDeadline, 而是讓net/http代替你調用,所以你可以調用更進階的timeout方法。但是請記住,所有的逾時的實現都是基於Deadline, 所以它們不會每次接收或者發送重新設定這個值(so they do NOT reset every time data is sent or received)。

江南雨的指正:
應該是由於“Deadline是一個絕對時間值”,不是真的逾時機制,所以作者特別提醒,這個值不會自動重設的,需要每次手動設定。 伺服器端逾時設定

對於暴露在網上的伺服器來說,為用戶端串連設定逾時至關重要,否則巨慢的或者隱失的用戶端可能導致檔案控制代碼無法釋放,最終導致伺服器出現下面的錯誤:

http: Accept error: accept tcp [::]:80: accept4: too many open files; retrying in 5ms  

http.Server有兩個設定逾時的方法: ReadTimeout 和 andWriteTimeout`。你可以顯示地設定它們:

 1 2 3 4 5 
 srv := &http.Server{ ReadTimeout: 5 * time.Second, WriteTimeout: 10 * time.Second, } log.Println(srv.ListenAndServe()) 

ReadTimeout的時間計算是從串連被接受(accept)到request body完全被讀取(如果你不讀取body,那麼時間截止到讀完header為止)。它的內部實現是在Accept立即調用SetReadDeadline方法(程式碼)。

 1 2 3 4 5 6 7 8 
 …… if d := c.server.ReadTimeout; d != 0 { c.rwc.SetReadDeadline(time.Now().Add(d)) } if d := c.server.WriteTimeout; d != 0 { c.rwc.SetWriteDeadline(time.Now().Add(d)) } …… 

WriteTimeout的時間計算正常是從request header的讀取結束開始,到 response write結束為止 (也就是 ServeHTTP 方法的聲明周期), 它是通過在readRequest方法結束的時候調用SetWriteDeadline實現的(程式碼)。

 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 
 func (c *conn) readRequest(ctx context.Context) (w *response, err error) { if c.hijacked() { return nil, ErrHijacked } if d := c.server.ReadTimeout; d != 0 { c.rwc.SetReadDeadline(time.Now().Add(d)) } if d := c.server.WriteTimeout; d != 0 { 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.