美文网首页向日葵武士
深入理解 Golang HTTP Timeout

深入理解 Golang HTTP Timeout

作者: liudankinglongl | 来源:发表于2018-02-19 20:26 被阅读0次

深入理解 Golang HTTP Timeout

背景

前段时间,线上服务器因为部分微服务提供的 HTTP API 响应慢,而我们没有用正确的姿势来处理 HTTP 超时(当然,还有少量 RPC 超时), 同时我们也没有服务降级策略和容灾机制,导致服务相继挂掉😂。服务降级和容灾需要一段时间的架构改造,但是以正确的姿势使用 HTTP 超时确是马上可以习得的。

超时的本质

所有的 Timeout 都构建于 Golang 提供的 Set[Read|Write]Deadline 原语之上。

服务器超时

server timeout
  • ReadTimout 包括了TCP 消耗的时间,可以一定程度预防慢客户端和意外断开的客户端占用文件描述符

  • 对于 https请求,ReadTimeout 包括了 TLS 握手的时间;WriteTimeout 包括了 TLS握手、读取 Header 的时间(虚线部分), 而 http 请求只包括读取 body 和写 response 的时间。

此外,http.ListenAndServe, http.ListenAndServeTLS and http.Serve 等方法都没有设置超时,且无法设置超时。因此不适合直接用来提供公网服务。正确的姿势是:


package main

import (

"net/http"

"time"

)

func main() {

server := &http.Server{

Addr:        ":8081",

ReadTimeout:  3 * time.Second,

WriteTimeout: 5 * time.Second,

}

http.HandleFunc("/hi", func(w http.ResponseWriter, r *http.Request) {

w.Write([]byte("hi"))

})

server.ListenAndServe()

}

客户端超时

client timeout
  • http.Client 会自动跟随重定向(301, 302), 重定向时间也会记入 http.Client.Timeout, 这点一定要注意。

取消一个 http request 有两种方式:

  1. Request.Cancel

  2. Context (Golang >= 1.7.0)

后一种因为可以传递 parent context, 因此可以做级联 cancel, 效果更佳。代码示例:


ctx, cancel := context.WithCancel(context.TODO())  // or parant context

timer := time.AfterFunc(5*time.Second, func() { 

    cancel()

})

req, err := http.NewRequest("GET", "http://httpbin.org/range/2048?duration=8&chunk_size=256", nil) 

if err != nil { 

    log.Fatal(err)

}

req = req.WithContext(ctx) 

Credits

  1. The complete guide to Go net/http timeouts

  2. Go middleware for net.Conn tracking (Prometheus/trace)

同步自我的博客深入理解 Golang HTTP Timeout

相关文章

  • 深入理解 Golang HTTP Timeout

    深入理解 Golang HTTP Timeout 背景 前段时间,线上服务器因为部分微服务提供的 HTTP API...

  • 用Python 判断http下载超时

    由于对http请求理解不深入,开始我一直是使用的requests里的timeout参数,即: req = requ...

  • Golang源码之Channel

    引用 图解Golang的channel底层原理 深入理解Golang Channel Go语言设计与实现-Chan...

  • golang深入理解

    go使用踩过什么坑(for range,数据库连接defer close) 1.select是随机的还是顺序的?s...

  • 深入理解HTTP

    0x01 HTTP是什么 HTTP全称是HyperText Transfer Protocal,即:超文本传输协议...

  • 深入理解http

    HTTP协议是Hyper Text Transfer Protocol(超文本传输协议)的缩写,是用于从万维网服务...

  • HTTP深入理解

    HTTP(Hyper Text Transfer Protocol 超文本传输协议)是一个应用层协议,由请求和响应...

  • golang的包(package)

    理解Golang包导入 http://tonybai.com/2015/03/09/understanding-i...

  • golang的深入理解

    https://tiancaiamao.gitbooks.io/go-internals/content/zh/0...

  • Golang 深入理解 Slice

    参考链接: https://github.com/lvgithub/go_blog/blob/master/Boo...

网友评论

    本文标题:深入理解 Golang HTTP Timeout

    本文链接:https://www.haomeiwen.com/subject/pzhwtftx.html