【发布时间】:2017-08-14 22:17:00
【问题描述】:
现在,我正在 AWS 的一个生产区域中测试一个极其简单的信号量。在部署时,延迟从 150 毫秒跃升至 300 毫秒。我假设会发生延迟,但如果它可以被丢弃,那就太好了。这对我来说有点新,所以我正在尝试。我已将信号量设置为允许 10000 个连接。这与 Redis 设置的最大连接数相同。下面的代码是最优的吗?如果没有,有人可以帮我优化它,如果我做错了什么等等。我想把它作为一个中间件,这样我就可以在服务器上简单地调用它n.UseHandler(wrappers.DoorMan(wrappers.DefaultHeaders(myRouter), 10000))。
package wrappers
import "net/http"
// DoorMan limit requests
func DoorMan(h http.Handler, n int) http.Handler {
sema := make(chan struct{}, n)
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
sema <- struct{}{}
defer func() { <-sema }()
h.ServeHTTP(w, r)
})
}
【问题讨论】:
-
信号量本身不会给请求增加任何明显的延迟。您是否检查过您实际上有超过 10000 个并发请求?如果您在该信号量上达到阻塞状态,我的猜测是您从额外的并发中受益,而之前只阻塞 redis 请求。
-
AWS 每分钟报告 30,000 个请求。我在两台服务器上进行负载平衡。我担心的是当我将代码移动到东海岸时,我们的峰值达到每分钟 300,000。此外,我的大部分延迟来自我们的生产 mongo 服务器。尽管我们尽可能使用 redis,但当流量增加时,mongo 会受到猛烈抨击,并且全国延迟会达到峰值。所以我正在关注 mongo (mgo) 文档并试图限制在“门口”。
-
这已经尽可能高效了,因此您将不得不做一些更好的系统分析(平均延迟基本上不会告诉您任何有用的信息)。阻塞处理程序可能会导致活动连接激增,您可能想尝试直接限制网络连接,看看是否有帮助。
-
30,000 个请求 每分钟 不等于 10,000 个并发/同时请求(没有直接关联,这实际上取决于为请求提供服务所需的时间)。
-
我同意@icza。我使用这个数字是因为它是 redis 可以处理的最大并发连接数。所以在精神上我知道它不应该超过那个......仍在试验。