V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
NGINX
NGINX Trac
3rd Party Modules
Security Advisories
CHANGES
OpenResty
ngx_lua
Tengine
在线学习资源
NGINX 开发从入门到精通
NGINX Modules
ngx_echo
binghe
V2EX  ›  NGINX

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

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

    现在多个服务运行在服务器上,想要达成如下效果,但是这个 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="/assets/index.786270b3.js"></script> 的标签,
    浏览器解析到 html 的这块 script ,于是去加载这个 js ,由于这里 src 是以"/"开头,所以浏览器拼上 host 变成 http://demo.abc.com/assets/index.786270b3.js ,注意,/drive 这一层没了,
    请求再次到达服务器,由于 /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 14: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
    我是用不同域名实现的, 比较简单
    Soutxx
        20
    Soutxx  
       2022-10-23 22:58:23 +08:00
    @xiang0818 老哥,是你吗? 499
    xiang0818
        21
    xiang0818  
       2022-10-24 15:40:54 +08:00
    @Soutxx 卧槽
    Soutxx
        22
    Soutxx  
       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   ·   实用小工具   ·   1629 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 16:51 · PVG 00:51 · LAX 08:51 · JFK 11:51
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.