今天遇见这样一个问题,nginx默认监听端口被https请求占用,而http请求 访问项目会代理到 80端口该怎么解决那?
有一个example.com域名,在web服务器(简称web-server,假定服务器的ip为8.8.8.8)上使用nginx反向代理本地的tomcat服务(8080端口),配置信息如下:
- http {
- upstream tdt_tomcat_server {
- server 127.0.0.1:8080 weight=1 max_fails=3 fail_timeout=30s;
- }
- server {
- listen 80;
- server_name example.com *.example.com;
- location / {
- proxy_next_upstream http_502 http_504 error timeout invalid_header;
- 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://tdt_tomcat_server;
- proxy_redirect off;
- }
- }
- }
又有一台反向代理服务器(proxy-server),因为特殊原因这台服务器对外只能使用非80端口,通过这台服务器反向代理上面的web-server,配置信息如下:
- http {
- upstream tdt_web_server {
- server 8.8.8.8:80 weight=1 max_fails=3 fail_timeout=30s;
- }
- server {
- listen 9000;
- server_name example.com *.example.com;
- location / {
- proxy_next_upstream http_502 http_504 error timeout invalid_header;
- 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://tdt_web_server;
- proxy_redirect off;
- }
- }
- }
首先将example.com域名通过hosts文件绑定ip到proxy-server上面,然后访问http://example.com:9000的时候会调整到80端口上面:
[root@proxy-server ~]# curl -I http://example.com:9000/
HTTP/1.1 302 Found
Server: nginx/1.12.0
Location: http://example.com/
Google了一下查到需要将proxy_set_header Host 设置成主机+端口的形式,即将 proxy_set_header Host $host; 修改成 proxy_set_header Host $host:$server_port;
这个时候再次访问http://example.com:9000的时候就正常了,不过还有一个问题,就是当访问 http://example.com:9000/userinfo 的时候需要用户登录才能访问,这个时候系统应该自动跳转到 http://example.com:9000/login 才对,但是确是跳转到了 http://example.com/login :
[root@proxy-server ~]# curl -I http://example.com:9000/userinfo
HTTP/1.1 302 Found
Server: nginx/1.12.0
Location: http://example.com/login
但是直接访问 http://example.com:9000/login 也是正常的。一开始想到是tomcat服务器的问题,但是如果反向代理服务器直接设置成web-server上的8080端口的话则是正常的,因此断定问题出在了nginx反向代理的设置上面,后来查阅到nginx和Tomcat集成后发生的重定向问题分析和解决这篇文章,可以通过proxy_redirect进行设置,修改后的proxy-server配置信息如下:
- http {
- upstream tdt_web_server {
- server 8.8.8.8:80 weight=1 max_fails=3 fail_timeout=30s;
- }
- server {
- listen 9000;
- server_name example.com *.example.com;
- location / {
- proxy_next_upstream http_502 http_504 error timeout invalid_header;
- proxy_set_header Host $host:$server_port;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_redirect http://$host http://$host:$server_port;
- proxy_redirect off;
- }
- }
- }
这个时候再访问 http://example.com:9000/userinfo 就自动跳转到 http://example.com:9000/login 了:
[root@proxy-server ~]# curl -I http://example.com:9000/userinfo
HTTP/1.1 302 Found
Server: nginx/1.12.0
Location: http://example.com:9000/login
最后还有一个问题需要特别注意,就是web-server中nginx的配置信息中一定不要这样设置:proxy_set_header Host $host:$server_port;,而是要设置成 proxy_set_header Host $host;,即不加端口号,否则自动跳转会失败。