httpd:如何动态延迟请求转发到代理?

httpd:如何动态延迟请求转发到代理?

我已将 Apache httpd (2.2.22) 配置为反向代理。

有时候我需要将我的 Web 服务器(代理请求的接收者)离线几毫秒。在此期间,Web 服务器不应接收任何请求,但我也不想拒绝任何请求。

我想做的是以某种方式让 httpd 在那段时间内延迟所有请求。步骤如下:

  1. 告诉 httpd 延迟所有请求,直到另行通知
  2. 停止 Web 服务器
  3. 启动 Web 服务器
  4. 继续从 httpd 转发请求

固定延迟也可以解决问题,但由于我无法预见 Web 服务器离线的实际时间(除非少于一秒),因此动态方法更适合。

我研究过 mod_proxy 或 mod_balancer 如何帮助我,但没有找到明显的解决方案。

我将非常高兴接受您提供的任何指点。

编辑:

看起来静态方法就足够了。一些有用的资源:

替代解决方案:

我们将部署systemd到我们的服务器。systemd 将解决我的问题,因为它可以在一端关闭的套接字上保留请求。这意味着当我短暂停止后端服务器时,所有请求都将排队,直到我再次启动它并连接到套接字。这就是我所说的优雅 :)

答案1

ProxyPass指令接受许多参数来配置如何处理与后端服务器的连接。

在这些参数中,您可能对以下内容感兴趣:

  • connectiontimeout <n>Apache 等待与后端的连接创建完成的秒数。
  • timeout <n>Apache 等待后端发送的数据(秒数)。
  • ttl <n>非活动连接和相关连接池条目的生存时间(以秒为单位)。

更好的解决方案是拥有多个后端服务器并平衡负载成员并使用该ping参数检测离线服务器。因此,当您重新启动后端服务器时,另一个服务器可以接管中继。

答案2

除了使用 Apache,您还可以在 Web 服务器上使用 Iptables 按照以下方式获取此信息:

  1. 删除与 Web 服务器的新连接 (tcp-SYN)
  2. 重启网络服务器
  3. 重新接受所有连接

由于防火墙会默默地丢弃新连接,因此反向代理将继续向 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 的优雅重启即可。它已经具有这些属性

  • 一个现有连接可以完成的正在进行的请求
  • 新的连接将在监听积压中停留一秒钟左右

相关内容