(Symfony2 + nginx) 根据请求目录在上游之间拆分流量

(Symfony2 + nginx) splitting traffic between upstream based on request directory

我一直在到处寻找这个问题的答案,但没有找到任何可以帮助我解决我的具体情况的问题。我是 nginx 的新手,所以我还在慢慢适应。

我有一个 Symfony 应用程序 运行 跨两个安装了 php-fpm 的网络服务器。主服务器有 nginxphp-fpm 而第二个服务器只有 php-fpm。我希望所有到 /admin/* 的路由都通过 main_server 上游路由,其他所有不是 /admin/* 的路由都到 default_balancer 上游。

我试过各种方法都无济于事。我希望所有路由仍由 app.php 处理(静态资产除外)我只希望上游服务器根据请求 url 是否为 /admin/* 进行更改。

主服务器 URL 示例(将始终转到 main_server 并且如果 main_server 不可用则最好抛出错误而不是默认为其他服务器):

默认平衡器 URL 示例(将始终转到 default_balancer):

仅供参考:上面的 url 是在没有 /app.php 部分的情况下输入到浏览器中的,但由于 try_files 部分

这是我的 nginx conf 文件(排除了不重要的位)。

upstream default_balancer {
    server 192.168.1.1:9000 weight=5; # main server
    server 192.168.1.2:9000 weight=3 max_fails=3 fail_timeout=30s; # second server
}

upstream main_server {
    server 192.168.1.1:9000; # main server
}

server {
    listen      80;
    server_name example.local;
    rewrite     ^   https://$server_name$request_uri? permanent;
}

server {
    listen 443;
    server_name example.local;
    root /var/www/vhosts/symfony/web;

    [...]

    location / {
        # try to serve file directly, fallback to app.php
        try_files $uri /app.php$is_args$args;
    }

    location ~ ^/app\.php(/|$) {
        fastcgi_pass default_balancer;
        fastcgi_split_path_info ^(.+\.php)(/.*)$;
        include fastcgi_params;
        # When you are using symlinks to link the document root to the
        # current version of your application, you should pass the real
        # application path instead of the path to the symlink to PHP
        # FPM.
        # Otherwise, PHP's OPcache may not properly detect changes to
        # your PHP files (see https://github.com/zendtech/ZendOptimizerPlus/issues/126
        # for more information).
        fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
        fastcgi_param DOCUMENT_ROOT $realpath_root;
        # Prevents URIs that include the front controller. This will 404:
        # http://domain.tld/app.php/some-path
        # Remove the internal directive to allow URIs like this
        internal;
    }
}

额外信息:我这样做的原因是我们的设计师通过网站上的管理面板处理上传图片。因为资产由主服务器处理(安装了 nginx 并为静态资产提供服务),我认为将所有 /admin/* 路由转发到该单个服务器是最简单的。如果其他解决方案有效,我愿意接受。

您的 URL 示例与您的配置不匹配。假设您只想将以 /admin 开头的 URI 发送到 /app.php,您可以添加此块:

location ^~ /admin {
    fastcgi_pass main_server;
    include fastcgi_params;
    fastcgi_param SCRIPT_FILENAME $realpath_root/app.php;
    fastcgi_param DOCUMENT_ROOT $realpath_root;
}

如果/admin下还有静态文件,可能需要稍微复杂一点:

location ^~ /admin {
    try_files $uri @admin;
}
location @admin {
    fastcgi_pass main_server;
    include fastcgi_params;
    fastcgi_param SCRIPT_FILENAME $realpath_root/app.php;
    fastcgi_param DOCUMENT_ROOT $realpath_root;
}