尝试按照标题所述进行操作:在高负载下保留现有会话,并向新到达的访问者提供 503 消息。
问题:它可以起作用,但是会话持续时间不会超过 90 秒。
目前的结果让我怀疑是否存在我遗漏的超时设置。
目的
我正在尝试让 haproxy 执行以下操作:
- 发送请求新的当前端的会话总数低于某个阈值时,会话到 backend-001。
- 向新的当前端会话总数超过该阈值时
- 即使会话数超出阈值,也允许对现有会话的请求
这样,正在填写多步骤表单的访问者就不会对 503 错误感到惊讶,并且可以告知新访问者“请稍后再来,因为我们现在真的很忙”。
设置
设置如下:
{visitors}
↓
[haproxy]
↓
[rails app on unicorn served by nginx] (right now just one
backend: 'backend-001')
当前方法
为了实现上述目标,我使用以下配置。
这个用于测试,具有非常低的限制(前端有 10 个连接(fe_conn gt 10)),以使测试更容易。
为了增加服务器的负载,我使用了 httperf,如下所示:
httperf --hog --server staging.machine.tld --uri /do_some_things --wsess=500,10,30 --rate 2
global
daemon
maxconn 10000
defaults
mode http
timeout connect 6s
timeout client 60s
timeout server 60s
balance roundrobin
option http-server-close
frontend http-in
bind [PUBLIC_IP]:80
default_backend backend-001
acl too_many fe_conn gt 10
use_backend b_too_many if too_many
backend backend-001
fullconn 10
appsession _session_id len 128 timeout 7200s
cookie SERVERID insert maxidle 7200s
server Server1 127.0.10.1:80 cookie backend-001 check
backend b_too_many
errorfile 503 /var/www/50x.html
问题
如上所述,问题是:它几乎可以工作,但会话持续时间不会超过 90 秒。
如果您继续点击,即使有 10 个会话很忙,您也可以保留您的会话。
尝试使用不同的浏览器实例打开服务器上的页面会导致 503 错误。
所以,看起来我快要成功了。有人知道是什么原因导致会话时间短吗?
特别是我该如何修复它:)
(编辑:从“服务器”行中删除了“weight 1 maxconn 10”,不相关且可能会造成混淆)(编辑第二个:将“前端的 10 个会话”更正为“前端的 10 个连接”)
答案1
不幸的是,您似乎完全混淆了连接和应用程序级会话。访问网站的用户可能有一个 cookie,这让您认为他拥有一个连接,但事实并非如此。他可能会根据需要打开任意数量的连接来获取对象和浏览页面。
您观察到的 90 秒肯定是浏览器的空闲连接保持超时时间。
这是可以实现你想要的,但它比这更复杂一些,因为你还必须考虑请求中持久性 cookie 的存在,以确定访问者是否是新访问者。
此外,一般来说,依赖平均每台服务器的连接数比依赖前端连接数更有效。原因是当服务器死机时,您需要重新调整此数字。最有效的方法是设置服务器 maxconn 值以启用排队,并使用 avg_queue 以便限制适用于服务器上排队请求的平均数量。这允许您正确处理已知访问者,同时在现有访问者导致负载增加时将新用户轻轻地移动到另一个后端。