我想将 Apache 2 设置为反向代理,使用基于名称的虚拟主机来决定如何将请求路由到后端服务器。很简单。
问题是这些后端服务器可以动态添加和删除。我的第一个想法是以编程方式重写 Apache 配置文件,并在apachectl graceful
后端服务器每次启动或关闭时调用。这似乎不是正确的解决方案。有什么更好的方法可以实现这一点?
我需要能够将名称处理顺利地转移到不同的后端服务器。例如,Backend-Server-A 可能正在处理对 example.com 的请求。监控进程可能会认为 Backend-Server-A 已过时(内存使用量过大、有新版本的服务器代码来处理 example.com 等)。监控进程启动 Backend-Server-B,它将很快处理对 example.com 的请求。Apache 应该将对 example.com 的任何新请求定向到 Backend-Server-B,但允许 Backend-Server-A 当前正在处理的任何待处理请求在我的监控进程关闭 Backend-Server-A 之前完成。
(笔记: 我最初发布于在 Stack Overflow 上。)
答案1
唯一想到的是使用 RewriteMap 脚本,该脚本将通过 P 标志到 RewriteRule 来决定要转到哪台机器,例如
#!/usr/bin/perl
#This is /usr/bin/requestdistributor.pl
$| = 1; # Turn off buffering
while (<STDIN>) {
print distributeRequest($_);
}
sub distributeRequest {
my $request = shift;
#do whatever you have to do to find the proper machine for the request,
#return the complete URL with a trailing newline
}
然后在 Apache 配置文件中
RewriteMap distributeRequests prg:/usr/bin/requestdistributor.pl
RewriteRule (.*) ${distributeRequests:$1} [P]
#Setup the reverse proxying for all machines, use the proper URLs
ProxyPassReverse / http://machine1
ProxyPassReverse / http://machine2
#and so on...
ProxyPassReverse / http://machineN
注意事项:由于未经测试,因此可能存在一些缺陷,添加新服务器时必须添加新的 ProxyPassReverse(并执行优雅操作),现在我想想,根据应用程序的具体情况,您甚至可能不需要 ProxyPassReverse 行。因此,请测试一下,并告诉我们它是否有效(或无效)。
答案2
答案3
这实际上应该是对“RewriteMap”脚本的评论,但显然我的评论有点“毫无意义”......
如果您使用的是较新版本的 Apache,则可以使用 RewriteMap 和 mod_dbd 的“dbd”选项来实现 Vinko 的建议,以查询简单的 sqlite3 数据库并管理“正在进行的”查找。
不过,没有什么比内存查找更好的了,我曾在实时服务上使用过自动优雅重新配置,效果很好,但我猜这是优雅重启频率和 apache 启动时的影响的问题。我们必须避免的主要是任何基于 DNS 查找(例如使用域的 vhost 配置)的操作,因为 DNS 查找超时可能会导致延迟,传入队列可能会填满,从而导致中断,而不是短暂的暂停。
与往常一样,对几个解决方案进行负载测试,看看有什么区别。