如何利用nginx或haproxy限制并发会话?

我目前正在使用nginx反向代理请求从长期轮询到上游的Web客户端。

由于我们正在进行长轮询(而不是websockets),所以当客户端连接时,它会以串行方式与服务器build立多个http连接,每次服务器发送一些数据时重新build立一个连接(或者超时,确定服务器无话可说10秒)。

我想要做的是限制并发的Web客户端的数量。 由于客户端不断地发出新的HTTP请求,而不是保持单个请求的打开,所以计算Web客户端的总数(因为与并发连接的http客户端的总数不相同)是有点棘手的。

我想到的方法是跟踪起始IP地址的http请求,并将IP地址存储在TTL为20秒的地方。 如果一个请求的IP地址不被识别,那么我们检查未过期的存储IP地址的总数; 如果这小于最大值,那么我们允许通过这个请求。 如果一个请求带有一个IP地址,我们可以在查找表中find一个尚未过期的IP地址,那么这个IP地址也可以通过。 所有允许通过的请求都将其IP添加到表中(如果不存在),并且TTL再次刷新为20秒。

实际上,我用nginx和Redis 2.0 Nginx模块 (以及nginx lua模块来简化条件分支),使用redis来存储我的IP地址和TTL( SETEX命令),这样一来,用DBSIZE命令检查表的大小。

这工作,但performance是可怕的。 nginx和redis结束了使用大量的CPU,机器只能处理less量的并发请求。

在1.5版本中添加到Haproxy(通过serverfault提供的一个佣金 )的新的stick-table和跟踪计数器似乎是实现这种限速的理想select,因为粘贴表可以跟踪IP地址并自动过期条目。 但是,我没有看到一个简单的方法来获得棒表中未到期条目的总数,这将是必要的知道连接的Web客户端的数量。

我很好奇,如果有人有任何build议,对于nginx或haproxy,甚至没有提到的其他东西,我还没有想到。

现在还没有什么好报告ACL中使用的表格的条目数量,不过这可能是一个10行补丁,可以添加到haproxy 1.5中,如果有帮助的话。

如果你碰巧自己动手,请把它发给我,我会把它合并到主线。 否则,请将我closures清单,以便我不要忘记添加这个。