Golang的http.Serve坑

·

1 min read

最近一直在调试 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 连接,目前运行良好了。