我正在运行一个正向代理,我想使用 ProxyRemote 将某些请求转发到不同的代理服务器。哪个请求发送到哪个服务器取决于许多因素(时间、负载、url、主机、用户……),并且必须由外部程序进行计算。
该过程当前通过向请求 URL 的主机添加后缀来工作,然后由 ProxyRemoteMatch 指令进行匹配。这是通过将 URL 传递给重写映射来完成的。
这个方法很好,但是我必须在配置和 DNS 中定义每个服务器。
这是一个有效的例子:
RewriteEngine on
// define an external program that contains the logic where which request should be routed to
RewriteMap balancemap prg:/home/mysite/balancemap.php
<ProxyMatch "http://.*">
RewriteEngine on
// if the route has not yet been set by suffix proxy pattern, pass the request uri and user to the mapping program and store it in an environment variable
// for example http://google.com will be rewritten to something like http://google.com.5.server.mysite.com - which means it should be routed over server number 5
RewriteCond %{HTTP_HOST} !\.([0-9]+)\.server\.mysite\.com$
RewriteCond ${balancemap:%{REQUEST_URI}#%{REMOTE_USER}} .*
RewriteRule .* - [E=BALANCEDURL:%0]
// if a new url has been calculated, rewrite to it
RewriteCond %{ENV:BALANCEDURL} .+
RewriteRule .* %{ENV:BALANCEDURL} [P]
</ProxyMatch>
// now comes the long ist of servers....
// every subdomain is mapped to the correct ip address in internal dns system
ProxyRemoteMatch .*\.1\.server\.mysite\.com.* http://1.server.mysite.com:80
ProxyRemoteMatch .*\.2\.server\.mysite\.com.* http://2.server.mysite.com:80
ProxyRemoteMatch .*\.3\.server\.mysite\.com.* http://3.server.mysite.com:80
ProxyRemoteMatch .*\.4\.server\.mysite\.com.* http://4.server.mysite.com:80
... and so on
基本上我希望的是一个支持反向引用的 ProxyRemoteDirective,如下所示:
ProxyRemoteMatch .*\.(\d+)\.server\.mysite\.com.* http://$1.server.mysite.com:80
或者我甚至可以像这样提供整个 IP:
ProxyRemoteMatch .*\.(\d+)\.(\d+)\.(\d+)\.(\d+)/.* http://$1.$2.$3.$4:80
供您参考:主机名的自定义部分在正向代理服务器上再次从 URL 中剥离。我还想通过按原样传递 URL 来摆脱它!
因此,如果 ProxyRemoteMatch 指令的第二个参数插入环境变量,它将看起来像这样:
// now our map just returns the ip of the correct remote server
RewriteCond ${balancemap:%{REQUEST_URI}#%{REMOTE_USER}} .*
RewriteRule .* - [E=REMOVESERVER:%0]
ProxyRemoteMatch .* http://%{ENV:REMOVESERVER}:80
这真是太棒了。
但不幸的是,以上方法均不起作用。
我花了一段时间才弄清楚当前的系统,现在我有大约 200 行 ProxyRemoteMatch 指令(200 个远程服务器)。但保持所有东西与 dns 和所有东西保持最新是一件很麻烦的事。
也许你也可以推荐一个替代方案?其他代理服务器软件可能也会出现同样的行为?可能是 Nginx?Squid?
因此欢迎任何想法!
仅供参考是这是一个商业项目,但我自己运营,目前并没有产生任何可观的利润。我计划将其开源,但一旦稳定,我就会用它来运行我自己的服务。
我想我也会尽快对这个问题给予悬赏。
答案1
假设以下循环(perl,但语言“yyyyy”也可以)
foreach my $i (1..200) {
print "ProxyRemoteMatch .*\\.$i\\.server\\.mysite\\.com.* http://$1.server.mysite.com:80\n";
}
打印所有冗长而重复的配置部分,何必呢?您可以使用这样的一行代码来维护整个过程。您甚至可以使用 Include 将其从配置文件中完全删除。可能在图片中引入“make”将允许您在添加/删除服务器时自动运行它。