我已将 Apache httpd (2.2.22) 配置为反向代理。
有时候我需要将我的 Web 服务器(代理请求的接收者)离线几毫秒。在此期间,Web 服务器不应接收任何请求,但我也不想拒绝任何请求。
我想做的是以某种方式让 httpd 在那段时间内延迟所有请求。步骤如下:
- 告诉 httpd 延迟所有请求,直到另行通知
- 停止 Web 服务器
- 启动 Web 服务器
- 继续从 httpd 转发请求
固定延迟也可以解决问题,但由于我无法预见 Web 服务器离线的实际时间(除非少于一秒),因此动态方法更适合。
我研究过 mod_proxy 或 mod_balancer 如何帮助我,但没有找到明显的解决方案。
我将非常高兴接受您提供的任何指点。
编辑:
看起来静态方法就足够了。一些有用的资源:
- httpd 代理密码
- httpd 代理超时
- 带有 mod_rewrite 的 ProxyPass(无需明确使用 ProxyPass;无需使用 ProxyPassInterpolateEnv)
- 也可以看看这个帖子有关 httpd 立即返回 503(代理和平衡器)的讨论。
替代解决方案:
我们将部署systemd到我们的服务器。systemd 将解决我的问题,因为它可以在一端关闭的套接字上保留请求。这意味着当我短暂停止后端服务器时,所有请求都将排队,直到我再次启动它并连接到套接字。这就是我所说的优雅 :)
答案1
答案2
除了使用 Apache,您还可以在 Web 服务器上使用 Iptables 按照以下方式获取此信息:
- 删除与 Web 服务器的新连接 (tcp-SYN)
- 重启网络服务器
- 重新接受所有连接
由于防火墙会默默地丢弃新连接,因此反向代理将继续向 Web 服务器重新发送 tcp-syn。已建立的连接不会受到影响。
如果该周期在不到 1 秒的时间内完成,新客户端将看到(恰好)1 秒的延迟,等于第一次 SYN 重试的延迟
示例 iptables 配置(假设 INPUT 链有一个空的 ACCEPT 策略):
/sbin/iptables -A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
/sbin/iptables -A INPUT -p tcp -m conntrack --ctstate NEW -m tcp --dport 80 -j DROP
重新启动网络服务器后:
/sbin/iptables -F
您也可以在反向代理的 OUTPUT 链上应用该策略,但快速同步操作可能会更具挑战性。
答案3
这是一种低技术含量的方法,类似于 iptables 提案,但对客户端完全透明:只需使用 停止 apachekill -stop
并使用 重新启动它kill -cont
。根据传入数据包的数量,内核应该在这段短时间内缓冲所有内容。也许这个缓冲甚至可以配置。
答案4
如果只需要停滞几毫秒,只需使用 Apache 的优雅重启即可。它已经具有这些属性
- 一个现有连接可以完成的正在进行的请求
- 新的连接将在监听积压中停留一秒钟左右