反向代理(Reverse Proxy)方式是指以代理服务器来接受internet上的连接请求,然后将请求,发给内部网络上的服务器
并将从服务器上得到的结果返回给internet上请求连接的客户端,此时代理服务器对外就表现为一个反向代理服务器
反向代理总结就一句话:代理端代理的是服务端
正向代理 是一个位于客户端和原始服务器(origin server)之间的服务器,为了从原始服务器取得内容,客户端向代理发送一个请求并指定目标(原始服务器),然后代理向原始服务器转交请求并将获得的内容返回给客户端。客户端必须要进行一些特别的设置才能使用正向代理
反向代理中,在客户端看来,服务端就是nginx,客户端感知不到后面tomcat服务器的存在。此时nginx代理服务端。
正向代理,客户端请求的就是tomcat服务器,但是因网络不通,无法直接访问,所以中间经过nginx来访问tomcat服务器。nginx代理客户端
反向代理服务器可以隐藏源服务器的存在和特征。它充当互联网云和web服务器之间的中间层。这对于安全方面来说是很好的,特别是当您使用web托管服务时。
启动本地tomcat,访问路径为 http://172.16.25.44:8080
下面设置通过nginx来访问tomcat中的应用
上面tomcat已经占用了8080端口,所以此时需要将nginx的端口设置为8081
说明:此处需要验证8081端口是否被使用,使用lsof -i:8081。如果有内容说明8081端口已经被占用,可以尝试8082等别的端口
并且在nginx.conf中设置应用服务器的http地址
server {
listen 8081;
server_name localhost;
location / {
proxy_pass http://172.16.25.44:8080;
}
}
问题:
如果我启动tomcat加了项目名称,即tomcat中直接访问项目的url为http://172.16.25.44:8080/rsbi,此时nginx.conf中的proxy_pass应该怎么配置呢?尝试直接修改proxy_pass中的内容,即nginx.conf配置为
server {
listen 8081;
server_name localhost;
location / {
#即 ip:port/项目名称
proxy_pass http://172.16.25.44:8080/rsbi;
}
}
此时输入http://localhost:8081//访问,页面无法访问,如下图:
重定向次数太多,所以修改为
server {
listen 8081;
server_name localhost;
location / {
#直接在后面加上/frame/Frame.action
proxy_pass http://172.16.25.44:8080/rsbi/frame/Frame.action;
}
}
此时你会发现能访问成功了,但是页面如下:
页面上进入开发者模式,看下报错信息,
很多404.因为http://localhost:8081是nginx的url地址,相对路径取得不对,正确的相对路径应该是http://172.16.25.44:8080/rsbi,导致问题:
1页面中的css\js\等没能加载进来,样式不对
2页面跳转时 以http://localhost:8081/为基准来执行请求,应该是http://172.16.25.44:8080 才对
ok,主要有下面几种方案:
方案一:server中增加
location ~ .*\.(js|css|resource|fe-res|ext-res)$ {
proxy_pass http://172.16.25.44:8080/rsbi;
}
方案失败,执行nginx指令时有问题:
nginx: [emerg] "proxy_pass" cannot have URI part in location given by regular expression, or inside named location, or inside "if" statement, or inside "limit_except" block in /usr/local/etc/nginx/nginx.conf:55
方案二:server中增加:
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_redirect off
proxy_pass http://172.16.25.44:8080/rsbi/frame/Frame.action;
方案失败,上面的内容配置后 毫无效果,静态文件请求的路径还是nginx的路径,如
GET http://localhost:8081/resource/layer/layer.min.js net::ERR_ABORTED 404
上面两个解决方案都没能解决问题。
第三个方案 配置如下:
server {
listen 8081;
server_name localhost;
location / {
proxy_pass http://172.16.25.44:8080;
}
}
但是此时访问的时候,需要url中年带上项目名称rsbi,即
http://localhost:8081/rsbi/,成功。细心的你应该能发现和最上面没有项目名称的nginx的配置完全一样!!!
第四个方案解决问题:
配置如下
upstream xd-project{
#注意 此处的server只能是ip:port 不能有任何多余的http或者项目名称
server 172.16.25.44:8080;
}
server{
listen 8081;
server_name localhost;
location / {
proxy_pass http://xd-project;
}
location ~ .* {
proxy_pass http://xd-project;
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;
}
}
注意访问的路径,http://localhost:8081会访问失败,上面配置upstream的时候我们仅仅使用了ip和端口号,所以一定注意:
这里要访问的时候需要增加项目名称,即
http://localhost:8081/rsbi/
说明:第四个方案其实是负载均衡的方式,upstream中可以配置多个ip:port
总结下第三种和第四种解决方案,本质上都是配置的时候不用处理项目名称,访问的时候加上项目名称即可。如果配置的时候带着项目发布的名称,则会导致静态资源无法加载的问题。
下面给出第四种方案的完整nginx.conf
#user nobody;
worker_processes 1;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
#tcp_nopush on;
#keepalive_timeout 0;
keepalive_timeout 65;
#gzip on;
upstream xd-project{
server 172.16.25.44:8080;
}
server {
#listen 8080;
listen 8081;
server_name localhost;
#charset koi8-r;
#access_log logs/host.access.log mai
location / {
proxy_pass http://xd-project;
}
location ~ .* {
proxy_pass http://xd-project;
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;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
include servers/*;
}