由于 PHP 应用程序各部分的优先级不同,这里的目标是让一个池用于一般用途,另一个池用于 URL /api/*
。为了使事情变得复杂,应用程序使用内部 URL 路由,因此无法仅通过 来区分这两种情况FilesMatch
。
我已从此开始:
<FilesMatch "\.php$">
SetHandler proxy:fcgi://127.0.0.1:9000
</FilesMatch>
<LocationMatch "^/api/">
SetHandler proxy:fcgi://127.0.0.1:9001
</LocationMatch>
这是在全局上下文中,在 VirtualHost 指令之外,因为存在多个 vhost,所有 vhost 都有相同的要求。
它不起作用,所有 URL 都由第一个池(位于 的池:9000
)处理。
您对如何创建此配置有任何想法吗?这是针对 Apache 2.4 的。
答案1
好的,用 解决了If
。显然 的翻译发生了一些有趣的事情REQUEST_URI
:在评估 时If
,它不包含我所需的内容,因此我匹配了THE_REQUEST
包含逐字 HTTP 请求的 。以下是我的解决方案:
<FilesMatch "\.php$">
# First pool, catches everything
SetHandler proxy:fcgi://127.0.0.1:9000
SetEnv PHP_POOL_ID "1"
</FilesMatch>
<If "%{THE_REQUEST} =~ m#/api/#">
# Second pool, only for certain URLs
SetHandler proxy:fcgi://127.0.0.1:9001
SetEnv PHP_POOL_ID "2"
</If>
这些SetEnv
语句仅用于调试,它们可以在日志中用于跟踪哪个池已处理请求,例如:
CustomLog "/var/log/httpd/php_pool.log" "%h %l %u %t \"%r\" %>s %b php:%{PHP_POOL_ID}e" env=PHP_POOL_ID
答案2
URL 不以 .php 结尾(据我所知,Location 匹配的就是这个),但 PHP 文件以 .php 结尾。也就是说,URL 看起来像 /api/whatever,并且通过 Rewrite 映射到 /index.php/api/whatever。
我认为这样的重写不可能实现你想要的结果。
<VirtualHost *:80>
ServerAdmin webmaster@localhost
ServerName www.example.net
DocumentRoot /vhosts/default/public_html
<Directory /vhosts/default/public_html>
DirectoryIndex index.html index.php
Options -Indexes
AllowOverride all
Order allow,deny
allow from all
</Directory>
SetEnv FCGI-PORT 9000
<LocationMatch \.php$>
SetEnv FCGI-PORT 9001
</LocationMatch>
<LocationMatch ^/api/>
SetEnv FCGI-PORT 9002
RewriteEngine On
RewriteRule (.*) /index.php?route=%{REQUEST_URI} [R=301,L]
</LocationMatch>
</VirtualHost>
一些基本测试
# curl http://www.example.net/
9000
# curl http://www.example.net/index.php
9001
# curl -I http://www.example.net/api/whatever
HTTP/1.1 301 Moved Permanently
Date: Wed, 09 Mar 2016 17:03:56 GMT
Server: Apache/2.2.15 (CentOS)
Location: http://www.example.net/index.php?route=/api/whatever
Connection: close
Content-Type: text/html; charset=iso-8859-1
# curl http://www.example.net/index.php?route=/api/whatever
9001
但如果我们评论重写规则 - 一切都按预期进行
# curl http://www.example.net/
9000
# curl http://www.example.net/index.php
9001
# curl http://www.example.net/api/
9002
# curl http://www.example.net/api/test.php
9002
尝试改变他们的顺序。
在这个特殊情况下(重写),顺序并不重要
PS index.php/test.php 只是一个简单的 php 脚本
<?php
echo $_SERVER['FCGI-PORT'];