我有一个基于 Codeigniter 3 构建的网站。这是一个典型的 nginx + php-fpm 设置。现在我需要将一些请求定向到另一个 php-fpm 池来处理。以下是配置的简化示例:
nginx 配置
测试.conf:
server {
server_name example.com;
root /var/www/ci;
index index.html index.php;
location ~* \.(ico|css|js|gif|jpe?g|png)(\?[0-9]+)?$ {
expires max;
log_not_found off;
}
# Somehow send all requests starting with /test/ to /index.php
# but use 127.0.0.1:9001 instead of the default 127.0.0.1:9000
#location /test/ {
# ...
#}
location / {
try_files $uri $uri/ /index.php;
}
location ~* \.php$ {
fastcgi_pass 127.0.0.1:9000;
include fastcgi.conf;
}
}
php-fpm 配置
www1.conf:
[www]
user = www-data
group = www-data
listen = 127.0.0.1:9000
listen.owner = www-data
listen.group = www-data
pm = dynamic
pm.max_children = 5
pm.start_servers = 2
pm.min_spare_servers = 1
pm.max_spare_servers = 3
www2.conf:
[www2]
user = www-data
group = www-data
listen = 127.0.0.1:9001
listen.owner = www-data
listen.group = www-data
pm = ondemand
pm.max_children = 5
我如何告诉 nginx 将以 开头的每个请求发送/test/
到另一个池(www2)?
例子
- http://example.com/hello/world还是应该去游泳池www1
- http://example.com/test/something应该去游泳池www2
答案1
这会将所有对 PHP 文件的请求重定向/test
到另一个池:
location ~*^/test/.+\.php$ {
fastcgi_pass 127.0.0.1:9001;
include fastcgi.conf;
}
为了覆盖使用前端控制器模式的框架,需要:
location /test {
root /path/to/webroot;
try_files $uri $uri/ /test/index.php;
}
答案2
看起来你可以使用 nginx 的地图指令来实现这一目标。
http
首先我们在块中添加一个地图nginx.conf
:
http {
# ...
map $request_uri $upstream_port {
default 9000;
"~^/test($|/)" 9001;
}
# ...
}
我们使用正则表达式来检查路径是否以 开头,/test
并根据该 开头选择 php-fpm 端口号。
接下来我们改用test.conf
这个新变量:
server {
server_name example.com;
root /var/www/ci;
index index.html index.php;
location ~* \.(ico|css|js|gif|jpe?g|png)(\?[0-9]+)?$ {
expires max;
log_not_found off;
}
location / {
try_files $uri $uri/ /index.php;
}
location ~* \.php$ {
fastcgi_pass 127.0.0.1:$upstream_port; # <-- This changed
include fastcgi.conf;
}
}
我不知道这是否会在现实世界中导致严重的性能损失,但在我的综合测试中,差异相当小。可能有更好的方法来做到这一点。