请教一下,关于 nginx 多个子目录反代的问题。 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
binghe
V2EX    NGINX

请教一下,关于 nginx 多个子目录反代的问题。

  •  
  •   binghe 2022-10-20 01:04:33 +08:00 3140 次点击
    这是一个创建于 1093 天前的主题,其中的信息可能已经有所发展或是发生改变。

    现在多个服务运行在服务器上,想要达成如下效果,但是这个 nginx 不懂怎么配置了。。。 三个服务有两个是 python 的,一个是 go 的。

    http://demo.abc.com/drive ---> http://127.0.0.1:8855 http://demo.abc.com/avg ---> http://127.0.0.1:8866 http://demo.abc.com/doc ---> http://127.0.0.1:8877 server { listen 80; server_name demo.abc.com; root /var/www/html; #注释这个后也提示错误 location /drive/ { rewrite ^/drive/(.*)$ /$1 break; #也试着这样过,不知道是不是写错了,没有效果 proxy_pass http://127.0.0.1:8855; } location /avg/ { proxy_pass http://127.0.0.1:8866; } location /doc/ { proxy_pass http://127.0.0.1:8877; } } log 日志,看日志,好像最大的问题就是这个 root 路径,如果把 root /var/www/html;这个注释掉,log 就是 /usr/share/nginx/html/assets/index.786270b3.js 这样的。 #349313: *1 open() "/var/www/html/assets/index.786270b3.js" failed (2: No such file or directory), client: 172.17.0.1, server: demo.abc.com, request: "GET /assets/index.786270b3.js HTTP/1.1", host: "demo.abc.com", referrer: "http://demo.abc.com/drive/" ```
    第 1 条附言    2022-10-20 11:51:22 +08:00
    Ubuntu 18.04.2 LTS (GNU/Linux 4.4.0-1128-aws x86_64)
    nginx version: nginx/1.14.0 (Ubuntu)
    23 条回复    2023-03-06 16:00:44 +08:00
    rrfeng
        1
    rrfeng  
       2022-10-20 07:09:09 +08:00 via Android
    GET /assets/index.786270b3.js

    你配置的三个 path 都没包含这个请求的路径。搞清楚这点就解决了。
    putyy
        2
    putyy  
       2022-10-20 08:24:34 +08:00
    location /drive/ {
    proxy_http_version 1.1;
    proxy_set_header Connection "keep-alive";
    proxy_set_header Host $http_host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    if (!-f $request_filename) {
    proxy_pass http://127.0.0.1:8855;
    }
    }
    location /avg/ {
    proxy_http_version 1.1;
    proxy_set_header Connection "keep-alive";
    proxy_set_header Host $http_host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    if (!-f $request_filename) {
    proxy_pass http://127.0.0.1: 8866;
    }
    }
    location /doc/ {
    proxy_http_version 1.1;
    proxy_set_header Connection "keep-alive";
    proxy_set_header Host $http_host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    if (!-f $request_filename) {
    proxy_pass http://127.0.0.1: 8877;
    }
    }
    jifengg
        3
    jifengg  
       2022-10-20 09:15:50 +08:00   1
    先说下原因:
    你在浏览器输入地址”http://demo.abc.com/drive/“访问,
    请求到达你的服务器,被 nginx 转发给 http://127.0.0.1:8855 ,
    你的 8855 服务返回了 html 内容,里面包含了类似一个<script src="http://www.v2ex.com/assets/index.786270b3.js"></script> 的标签,
    浏览器解析到 html 的这块 script ,于是去加载这个 js ,由于这里 src 是以"/"开头,所以浏览器拼上 host 变成 http://demo.abc.com/assets/index.786270b3.js ,注意,/dive 这一层没了,
    请求再次到达服务器,由于 /assets 你没有配置对应的 location ,就默认去 root 下查找对应文件,找不到,nginx 记录错误日志


    解决思路:
    1. [推荐] 给 8855 配置一个独立的域名,然后 ngxin 配置
    location / {
    proxy_pass http://127.0.0.1:8855;
    }

    2.修改 8855 的代码
    2.1 script 引入 js 改为相对路径的方式,类似 src="assets/index.786270b3.js",但是要注意 html 和 js 的相对路径关系;
    2.2 从 header 里获取”Host“,拼接到 src 里。这个 Host 需要 nginx 透传过来,因为不传的话,8855 的程序其实是不知道你浏览器是通过”demo.abc.com/drive“这个 host 访问到它的,方法 @putyy 给出了,就是“proxy_set_header Host $http_host;” 这一句
    xiang0818
        4
    xiang0818  
       2022-10-20 09:34:36 +08:00
    补上斜杆

    server {
    listen 80;
    server_name demo.abc.com;

    root /var/www/html; #注释这个后也提示错误

    location /drive/ {
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_pass http://127.0.0.1:8855/;
    }

    location /avg/ {
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_pass http://127.0.0.1:8866/;
    }

    location /doc/ {
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_pass http://127.0.0.1:8877/;
    }

    }
    xiang0818
        5
    xiang0818  
       2022-10-20 09:52:24 +08:00
    ```
    ```
    binghe
        6
    binghe  
    OP
       2022-10-20 11:34:52 +08:00
    @rrfeng #1 感谢,由于这个不是主业,所以搞清楚有点困难,昨天其实还去了 nginx 官网看了一会关于 proxy_pass 的,好像也没收获。


    @putyy #2 按照您的方法,我配置了一个,但还是提示一样的错误:
    binghe
        7
    binghe  
    OP
       2022-10-20 11:42:59 +08:00
    哎,不小心发出去了。
    ------------------------------------------------------
    location /drive/ {
    proxy_http_version 1.1;
    proxy_set_header Connection "keep-alive";
    proxy_set_header Host $http_host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    if (!-f $request_filename) {
    proxy_pass http://127.0.0.1:8855;
    }
    }

    -------------------------------------------------------

    错误日志:
    #408155: *1 open() "/var/www/html/assets/index.786270b3.js" failed (2: No such file or directory), client: 172.17.0.1, server: demo.abc.com, request: "GET /assets/index.786270b3.js HTTP/1.1", host: "demo.abc.com", referrer: "http://demo.abc.com/drive/"

    ----------------------------------------------------------

    浏览器控制台的错误是这样的:
    GET http://demo.abc.com/assets/index.659f4289.css net::ERR_ABORTED 404 (Not Found) (索引):53
    (匿名) @ (索引):53
    (匿名) @ (索引):55
    binghe
        8
    binghe  
    OP
       2022-10-20 11:47:58 +08:00
    @jifengg #3 感谢。如果是要放在现在的服务器上,好像是无法每个服务单独解析一个域名的,只能通过 nginx 反代想想办法。
    binghe
        9
    binghe  
    OP
       2022-10-20 11:50:27 +08:00
    @xiang0818 #4 好像用这个代码,错误的内容和#2 是一样的。

    我其实前面自己已经各种瞎搞瞎测试两天了都没搞定
    jifengg
        10
    jifengg  
       2022-10-20 12:09:37 +08:00
    @binghe 没法配置独立域名,那就按照第 2 个方法改吧。
    再补充一个

    2.3 修改 8855 的编译配置,不清楚 8855 是啥语言的,但是一般都会有一个配置,表示这个项目即将运行在哪个目录下,比如默认可能是“/",那么这时候可以改成 “/drive/”,就能解决后面路径不对的问题了。

    再提一嘴,我上面列的 1 ,2.1 ,2.2 ,2.3 ,都是一个独立的解决方案,不是解决步骤。选一个你能做的就行。
    adoal
        11
    adoal  
       2022-10-20 12:31:57 +08:00
    如 #10 所说你要配置后面的三个服务,让他们“认识到”自己应该按照运行在子路径下的情况来生成页面里的站内链接 URL 。
    大部分 web 框架都可以配置一个固定的 prefix 来做这事的。甚至,如果框架支持老式 CGI 惯例的话,可以从前端传一个 header 过去让后端动态知道自己应该运行在哪个子路径下。
    binghe
        12
    binghe  
    OP
       2022-10-20 13:35:05 +08:00
    @jifengg #10 该配置的话,可能也比较麻烦。目前 8855 这个项目是 go 语言写的。三个项目都不是我写的。而且项目还在更新中....

    通过公网 IP 直接访问的话,路径是这样的 http://ip:port/assets/index.786270b3.js
    jifengg
        13
    jifengg  
       2022-10-20 13:51:53 +08:00
    @binghe 如果你的三个项目是开源项目,那不如说下是啥项目,大家直接可以看怎么配。
    如果不是开源,是其他团队在开发的,那就联系他们问怎么把“/drive”传给他们。
    sher17
        14
    sher17  
       2022-10-20 14:17:27 +08:00
    二级目录这种东西,不是 nginx 的问题。个人建议 8855 这个服务单开一个端口。如果不怕影响其他服务。不妨试试:
    location ~ /.*\.(js|css)?$ {
    proxy_pass http://127.0.0.1:8855;

    }#设置静态文件目录
    binghe
        15
    binghe  
    OP
       2022-10-20 4:28:20 +08:00
    对不起,各位,我犯了个大错,有个环境没说清楚。目前是网络环境大致是这样的。


    binghe
        16
    binghe  
    OP
       2022-10-20 14:32:32 +08:00
    @jifengg #13 如果像#14 说的不是 nginx 的问题,那可能就没办法了。或者我这里在问问开发团队那边能不能帮忙解决。
    @sher17 #14 我昨天有测试了差不多一样的写法。就是反代一个项目。
    ylls
        17
    ylls  
       2022-10-20 14:59:50 +08:00
    如果是 3 楼说的那种情况的话 你可以使用 nginx 的 subs_filter 模块进行静态文件路径替换
    ylls
        18
    ylls  
       2022-10-20 15:02:53 +08:00
    @ylls 具体你可以在终端里面使用 curl 命令直接访问网页 看看返回的网页静态文件路径 如果是 /开头 那就需要进行替换一下

    看日志 你是访问 http://demo.abc.com/drive/后 nginx 报这个错误 那么和 3 楼说的情况是一致的,如果你无法修改对应的服务器上的内容 那么就可以使用 nginx 的 subs_filter 模块进行修改返回的内容
    sch1111878
        19
    sch1111878  
       2022-10-20 15:52:38 +08:00
    我是用不同域名实现的, 比较简单
    doget
        20
    doget  
       2022-10-23 22:58:23 +08:00
    @xiang0818 老哥,是你吗? 499
    xiang0818
        21
    xiang0818  
       2022-10-24 15:40:54 +08:00
    @Soutxx 卧槽
    doget
        22
    doget  
       2022-10-24 17:18:17 +08:00 via Android
    @xiang0818 自己加我,cG9zdGhp
    lurenlym
        23
    lurenlym  
       2023-03-06 16:00:44 +08:00
    https://github.com/RobinLinus/snapdrop
    大佬们看看开源项目这个前端怎么解析带路径的,我想域名 www.example.com/snap 来访问这个项目
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     4998 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 36ms UTC 09:38 PVG 17:38 LAX 02:38 JFK 05:38
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86