Due to different priorities of the parts of the PHP app, the goal here is to have one pool for general usage, and another for The /api/*
URLs. To make things complicated, the app uses internal URL routing, so it's not possible to distinguish the two cases by only FilesMatch
.
I've started with this:
<FilesMatch "\.php$">
SetHandler proxy:fcgi://127.0.0.1:9000
</FilesMatch>
<LocationMatch "^/api/">
SetHandler proxy:fcgi://127.0.0.1:9001
</LocationMatch>
This is in the global context, outside VirtualHost directives as there are multiple vhosts, all with the same requirement.
It doesn't work and all URLs are handled by the first pool (the one at :9000
).
Any ideas how to create this configuration? This is for Apache 2.4.
Хорошо, решил это с помощью If
. Видимо, что-то забавное происходит с переводом REQUEST_URI
: на момент оценки Если
не содержит того, что я требовал, поэтому я сравнил 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>
SetEnvSetEnv
операторы предназначены только для отладки, их можно использовать в логах для отслеживания того, какой пул обслужил запрос, например, с:
CustomLog "/var/log/httpd/php_pool.log" "%h %l %u %t \"%r\" %>s %b php:%{PHP_POOL_ID}e" env=PHP_POOL_ID
URL-адреса не заканчиваются на .php-адреса (AFAIK - это то, что совпадает с Location-адресами), но PHP-файлы заканчиваются. Т.е. URL выглядит как /api/weverever, и отображается Rewrite в /index.php/api/weverever.
Я думаю, что с такими переписями невозможно получить то, что вы хотите.
<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
Попробуйте изменить их порядок.
В данном конкретном случае (с переписыванием) порядок не имеет значения
P.S. index.php/test.php - это всего лишь простой php скрипт
<?php
echo $_SERVER['FCGI-PORT'];