Running multiple PHP-FPM pools on Apache for different URLs?

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.

0
задан 9 March 2016 в 16:14
2 ответа

Хорошо, решил это с помощью 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
0
ответ дан 5 December 2019 в 10:40

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'];
0
ответ дан 5 December 2019 в 10:40

Теги

Похожие вопросы