Apache Webserver 在反向代理错误时阻止前端连接

Apache Webserver 在反向代理错误时阻止前端连接

我们遇到了一个问题,那就是位于 Apache Web 服务器前面的负载均衡器相对比较笨重。Apache Web 服务器又是应用服务器的反向代理。

当应用程序崩溃时,问题就开始了。这会导致 Apache 抛出错误代码。

问题在于,负载平衡器仅考虑从池中移除服务器的硬 TCP 错误。这意味着错误页面将通过负载平衡器发送给用户,而不是服务器直接从池中移除。

是否可以配置 Apache 以拒绝后端的 tcp 请求并出现后端错误?

答案1

Haproxy 可以根据动态条件(包括后端可用的服务器数量)拒绝 tcp 连接。配置关键字是 tcp-request connection。(下面的文档链接。)

因此,也许将 haproxy 放在 Apache 前面(我知道,我知道!三层?!?!)或者也许使用 haproxy 代替 Apache。

可能看起来像这样(未经测试):

frontend http-in
  bind *:80
  mode http
  tcp-request connection reject if nbsrv(appfarm) lt 1
  default_backend appfarm

backend appfarm
  server appsrv01 127.0.0.1:8888 check

如果你觉得有用的话,我很乐意进一步阐述一下。这是一个有趣的问题。

答案2

这可能无法与 apache httpd 本身配合使用。问题是您的应用程序失败导致 apache httpd 生成错误。只有当您实际从该应用程序请求 URL 时才会发生此错误。Apache httpd 需要 URL 来决定这是否是错误,并且要从客户端获取 URL,它需要 TCP 连接。

解决方法:您可以编写一个相当简单的脚本,读取 stdin 上的 ErrorLog 流,然后在错误开始发生时阻止来自负载均衡器(可能是 iptables)的请求。然后可以使用 ErrorLog 指令将该脚本配置为 apache httpd 错误日志的接收器。

这将禁用 apache httpd 后端服务器,但永远不会自动重新启用它。

答案3

我会将逻辑转移到负载均衡器,如果无法替换现有的负载均衡器,则在每个 Apache 服务器中安装一个小型 nginx 来代理连接。

[用户] - [负载均衡器] - [Nginx]—[阿帕奇]

通过使用nginx 作为负载均衡器或反向代理您可以访问上游响应(在您的情况下是 Apache),并且可以制定在回复最终客户端之前评估响应代码的规则:

$上游状态保存从上游服务器获得的响应的状态码。多个响应的状态码像 $upstream_addr 变量中的地址一样用逗号和冒号分隔。如果无法选择服务器,则变量保存 502(Bad Gateway)状态码。

Nginx 示例规则

如果可用,调用负载均衡器 API 来删除节点:

if ($upstream_status != 200) {
    return 301 return 301 http://loadbalance/api/remove/node;
} 

调用本地脚本(请检查安全性)来终止 Apache 并告诉用户重新加载页面(下次将使用另一个后端)。它使用ngx_http_lua_模块

if ($upstream_status != 200) {
   content_by_lua_block {
     os.execute("/bin/killapache.sh")
   } 
   return 301 https://$host$request_uri;
} 

相关内容