在 Go 中创建空闲超时?
Creating an idle timeout in Go?
我将 CloudFlare 用于我的一个高流量网站,它位于我的堆栈前面。
问题是,CloudFlare 除了创建新连接外,还会打开空闲连接,这不是我可以更改的设置。
当我让 Varnish 或 Nginx 坐在前面侦听端口 80 时,它们具有开箱即用的配置来挂断空闲连接。
这很好,直到我不得不将一个用 Go 编写的代理添加到我的堆栈的前面。它使用 net/http
标准库。
我不是 Go 高手,但根据人们告诉我的情况,只有读写超时设置,但不会挂断空闲连接。
现在我的服务器会被连接填满然后挂掉,除非我设置了一组读写超时,但问题是我的后端有时会花费很长时间,这会导致好的请求在它们应该被切断的时候被切断't。
使用 Go http 处理空闲连接的正确方法是什么?
编辑 1: 更清楚地说,我正在使用 httputil.NewSingleHostReverseProxy
构建一个代理,它公开传输选项但仅针对上游。我遇到的问题是下游问题,需要在使用 ReverseProxy 作为处理程序的 http.Server
对象上设置它们。 http.Server
不公开传输。
编辑 2:我更喜欢空闲超时而不是读取超时,因为后者适用于活跃的上传者。
谢谢
请参阅 net/http.Transport 文档。 Transport 类型有一些选项用于处理处于保持活动状态的空闲 HTTP 连接。通过阅读您的问题,似乎与您的问题最相关的选项是 MaxIdleConnsPerHost 字段:
MaxIdleConnsPerHost, if non-zero, controls the maximum idle (keep-alive) to keep per-host. If zero, DefaultMaxIdleConnsPerHost is used.
阅读代码,默认为每个主机 2 个。
传输类型也有一个方法来关闭所有空闲连接:CloseIdleConnections。
CloseIdleConnections closes any connections which were previously connected from previous requests but are now sitting idle in a "keep-alive" state. It does not interrupt any connections currently in use.
您可以在任何 http 客户端上指定传输:
tr := &http.Transport{
TLSClientConfig: &tls.Config{RootCAs: pool},
DisableCompression: true,
MaxIdleConnsPerHost: 1,
}
client := &http.Client{Transport: tr}
resp, err := client.Get("https://example.com")
另一件值得注意的事情:文档建议您保留一个在所有请求中重复使用的 http 客户端对象(即像全局变量一样)。
Clients and Transports are safe for concurrent use by multiple goroutines and for efficiency should only be created once and re-used.
如果您在代理实现中创建许多 http 客户端对象,它可能会解释空闲连接的无限增长(尽管只是猜测您可能如何实现它)。
编辑:多读一点,net/httputil 包有一些方便的反向代理类型。参见ReverseProxy type。该结构还允许您提供自己的传输对象,从而允许您通过此帮助程序类型控制代理的空闲客户端行为。
在 Go http 服务器中挂断空闲连接的正确方法是设置 read timeout。
没有必要设置写入超时以挂断空闲客户端。如果它会切断响应,请不要设置或调整它。
如果您的上传时间较长,请使用 a connection state callback 实现单独的空闲和读取超时:
server.ConnState = func(c net.Conn, cs http.ConnState) {
switch cs {
case http.StateIdle, http.StateNew:
c.SetReadDeadline(time.Now() + idleTimeout)
case http.StateActive:
c.SetReadDeadline(time.Now() + activeTimeout)
}
}
我将 CloudFlare 用于我的一个高流量网站,它位于我的堆栈前面。
问题是,CloudFlare 除了创建新连接外,还会打开空闲连接,这不是我可以更改的设置。
当我让 Varnish 或 Nginx 坐在前面侦听端口 80 时,它们具有开箱即用的配置来挂断空闲连接。
这很好,直到我不得不将一个用 Go 编写的代理添加到我的堆栈的前面。它使用 net/http
标准库。
我不是 Go 高手,但根据人们告诉我的情况,只有读写超时设置,但不会挂断空闲连接。
现在我的服务器会被连接填满然后挂掉,除非我设置了一组读写超时,但问题是我的后端有时会花费很长时间,这会导致好的请求在它们应该被切断的时候被切断't。
使用 Go http 处理空闲连接的正确方法是什么?
编辑 1: 更清楚地说,我正在使用 httputil.NewSingleHostReverseProxy
构建一个代理,它公开传输选项但仅针对上游。我遇到的问题是下游问题,需要在使用 ReverseProxy 作为处理程序的 http.Server
对象上设置它们。 http.Server
不公开传输。
编辑 2:我更喜欢空闲超时而不是读取超时,因为后者适用于活跃的上传者。
谢谢
请参阅 net/http.Transport 文档。 Transport 类型有一些选项用于处理处于保持活动状态的空闲 HTTP 连接。通过阅读您的问题,似乎与您的问题最相关的选项是 MaxIdleConnsPerHost 字段:
MaxIdleConnsPerHost, if non-zero, controls the maximum idle (keep-alive) to keep per-host. If zero, DefaultMaxIdleConnsPerHost is used.
阅读代码,默认为每个主机 2 个。
传输类型也有一个方法来关闭所有空闲连接:CloseIdleConnections。
CloseIdleConnections closes any connections which were previously connected from previous requests but are now sitting idle in a "keep-alive" state. It does not interrupt any connections currently in use.
您可以在任何 http 客户端上指定传输:
tr := &http.Transport{
TLSClientConfig: &tls.Config{RootCAs: pool},
DisableCompression: true,
MaxIdleConnsPerHost: 1,
}
client := &http.Client{Transport: tr}
resp, err := client.Get("https://example.com")
另一件值得注意的事情:文档建议您保留一个在所有请求中重复使用的 http 客户端对象(即像全局变量一样)。
Clients and Transports are safe for concurrent use by multiple goroutines and for efficiency should only be created once and re-used.
如果您在代理实现中创建许多 http 客户端对象,它可能会解释空闲连接的无限增长(尽管只是猜测您可能如何实现它)。
编辑:多读一点,net/httputil 包有一些方便的反向代理类型。参见ReverseProxy type。该结构还允许您提供自己的传输对象,从而允许您通过此帮助程序类型控制代理的空闲客户端行为。
在 Go http 服务器中挂断空闲连接的正确方法是设置 read timeout。
没有必要设置写入超时以挂断空闲客户端。如果它会切断响应,请不要设置或调整它。
如果您的上传时间较长,请使用 a connection state callback 实现单独的空闲和读取超时:
server.ConnState = func(c net.Conn, cs http.ConnState) {
switch cs {
case http.StateIdle, http.StateNew:
c.SetReadDeadline(time.Now() + idleTimeout)
case http.StateActive:
c.SetReadDeadline(time.Now() + activeTimeout)
}
}