Golang的http.Serve坑

2018-03-24

最近一直在调试 http 的反向代理,随着运行时间,总是会慢慢有很多 ESTABLISHED 连接状态的连接,甚至会保持一个晚上没有关闭。

然后就想着是不是 Transport 的问题,因为这是负责 client <-> Self <-> Server 的传输。

然后设置超时自动 cancel Context,自动 close body,然而都没有用。。

然后我发现不对啊,虽然 Transport 负责传输,但是他并不维护客户的连接啊,而且 Accept 连接是从下面这个方法中获取的啊:

http.Serve(l net.Listener, handler http.Handler)

srv.Serve(l)

然后看了下 该方法的源码:

func Serve(l net.Listener, handler Handler) error {
	srv := &Server{Handler: handler}
	return srv.Serve(l)
}

然后看了下 Server 这个结构体,发现各个超时都在这里面设置。

那么不使用 http.Serve() 方法了, 直接构建 Server 结构体:

	srv := &http.Server{
		Handler:           this,
		ReadHeaderTimeout: 10 * time.Second,
		ReadTimeout:       10 * time.Minute,
		WriteTimeout:      10 * time.Minute,
		IdleTimeout:       30 * time.Second,
	}
	return srv.Serve(ln)

然后再观察 tcp 连接,目前运行良好了。