现在多个服务运行在服务器上,想要达成如下效果,但是这个 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
rrfeng 2022-10-20 07:09:09 +08:00 via Android
GET /assets/index.786270b3.js
你配置的三个 path 都没包含这个请求的路径。搞清楚这点就解决了。 |
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; } } |
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;” 这一句 |
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/; } } |
5
xiang0818 2022-10-20 09:52:24 +08:00
```
``` |
6
binghe OP |
7
binghe OP 哎,不小心发出去了。
------------------------------------------------------ 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 |
8
binghe OP @jifengg #3 感谢。如果是要放在现在的服务器上,好像是无法每个服务单独解析一个域名的,只能通过 nginx 反代想想办法。
|
10
jifengg 2022-10-20 12:09:37 +08:00
@binghe 没法配置独立域名,那就按照第 2 个方法改吧。
再补充一个 2.3 修改 8855 的编译配置,不清楚 8855 是啥语言的,但是一般都会有一个配置,表示这个项目即将运行在哪个目录下,比如默认可能是“/",那么这时候可以改成 “/drive/”,就能解决后面路径不对的问题了。 再提一嘴,我上面列的 1 ,2.1 ,2.2 ,2.3 ,都是一个独立的解决方案,不是解决步骤。选一个你能做的就行。 |
11
adoal 2022-10-20 12:31:57 +08:00
如 #10 所说你要配置后面的三个服务,让他们“认识到”自己应该按照运行在子路径下的情况来生成页面里的站内链接 URL 。
大部分 web 框架都可以配置一个固定的 prefix 来做这事的。甚至,如果框架支持老式 CGI 惯例的话,可以从前端传一个 header 过去让后端动态知道自己应该运行在哪个子路径下。 |
12
binghe OP @jifengg #10 该配置的话,可能也比较麻烦。目前 8855 这个项目是 go 语言写的。三个项目都不是我写的。而且项目还在更新中....
通过公网 IP 直接访问的话,路径是这样的 http://ip:port/assets/index.786270b3.js |
13
jifengg 2022-10-20 13:51:53 +08:00
@binghe 如果你的三个项目是开源项目,那不如说下是啥项目,大家直接可以看怎么配。
如果不是开源,是其他团队在开发的,那就联系他们问怎么把“/drive”传给他们。 |
14
sher17 2022-10-20 14:17:27 +08:00
二级目录这种东西,不是 nginx 的问题。个人建议 8855 这个服务单开一个端口。如果不怕影响其他服务。不妨试试:
location ~ /.*\.(js|css)?$ { proxy_pass http://127.0.0.1:8855; }#设置静态文件目录 |
15
binghe OP |
16
binghe OP |
17
ylls 2022-10-20 14:59:50 +08:00
如果是 3 楼说的那种情况的话 你可以使用 nginx 的 subs_filter 模块进行静态文件路径替换
|
18
ylls 2022-10-20 15:02:53 +08:00
@ylls 具体你可以在终端里面使用 curl 命令直接访问网页 看看返回的网页静态文件路径 如果是 /开头 那就需要进行替换一下
看日志 你是访问 http://demo.abc.com/drive/后 nginx 报这个错误 那么和 3 楼说的情况是一致的,如果你无法修改对应的服务器上的内容 那么就可以使用 nginx 的 subs_filter 模块进行修改返回的内容 |
19
sch1111878 2022-10-20 15:52:38 +08:00
我是用不同域名实现的, 比较简单
|
23
lurenlym 2023-03-06 16:00:44 +08:00
|