Nginx反向代理

Nginx反向代理

Nginx反向代理相关问题

2020-11-18 13:06:41

最近遇到挺多nginx反代的出现的问题,还是因为自己会的不多,目前都解决了,记录一下方便日后查看。

1.cookie路径问题

Cookie是由服务器端生成,发送给User-Agent,浏览器会将Cookie的key/value保存到某个目录下的文本文件内,下次请求同一网站时就发送该Cookie给服务器

说明

如果你一个tomcat的项目(项目名叫one接口是login),监听的是8080 应该是请求一个http://1.1.1.1:8080/one/login这样的地址,此时你的uri就是/one
cookie也会记着这个地址。如果你用nginx如下反代了内网的这个tomcat,让用户请求的地址变成了http://1.1.1.1/two/login 。tomcat实际收到的是nginx的http://127.0.0.1:8080/one/请求,所以cookie绑定的地址就是/one,但是用户的是/two 路径不一样浏览器就不会接受这个cookie 登录也就失败了。

server {
        listen       80;
	...
	location /two {
		proxy_pass   http://127.0.0.1:8080/one/;
	}
}

这里的例子是nginx反代更改了路径,如果你的nginx反代并没有更改路径 只是改了IP或者端口,就和这个没有关系了。就像下面这样是没有事情的:

server {
        listen       80;
	...
	location /one {
		proxy_pass   http://127.0.0.1:8080/one/;
	}
}

解决方案

使用nginx内定的命令,转换一下cookie路径:

server {
        listen       80;
	...
	location /two {
		proxy_pass   http://127.0.0.1:8080/one/;
		proxy_cookie_path  /one /two;		\\这里前面写匹配路径,后面写更改后的最终路径,就是用户浏览器上的。
	}
}

2.下划线转义问题

Token是服务端生成的一串字符串,以作客户端进行请求的一个令牌,当第一次登录后,服务器生成一个Token便将此Token返回给客户端,以后客户端只需带上这个Token前来请求数据即可,无需再次带上用户名和密码。[1]

原因:

由于某些项目的token的命名携带下划线_,nginx反代的时候认为是不合法的,就不处理了。

解决方案:

在nginx中添加underscores_in_headers on;proxy_pass_request_headers on;
如下

server {
        listen       80;
	underscores_in_headers on;
	...
	location /two {
		proxy_pass_request_headers on;
		proxy_pass   http://127.0.0.1:8080/one/;
	}
}

3.预检请求问题

"预检"请求(preflight),在正式通讯前会先发送一个类型为'OPTIONS'的请求,服务器收到"预检"请求以后,检查了Origin、Access-Control-Request-Method和Access-Control-Request-Headers字段以后,确认允许跨源请求,就可以做出回应。如果能正常返回,则会开始下一步请求。如果不行就会返回400系列错误。

解决方案:

因此,为了使Nginx可以处理delete等非简单请求,Nginx需要作出相应的改变,更改配置如下

location / {
    # 完成浏览器的"预检"请求
        if ($request_method = 'OPTIONS') {
        add_header Access-Control-Allow-Origin *;
        add_header Access-Control-Allow-Credentials true;
        add_header Access-Control-Allow-Methods 'GET, POST, PUT, DELETE, OPTIONS';
        add_header 'Access-Control-Allow-Headers' 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
        return 204;
        }
	proxy_pass   http://127.0.0.1:8080/one/;

4.数据太大,反代缓存问题

资料参考[2]

Nginx提供缓存功能,在用户请求的时候会先从nginx这里返回一些数据,达到限额的时候才会去请求正在的后端服务器获取数据。

说明

有些时候,比如频繁的调用一个获取天气的接口。因为天气不可能每分每秒都会变化,所以可以适用缓存。但是后端服务器不够强大,没调一次接口,后端就去调一次数据库,当请求多起来的时候就会出现异常,或者长时间未响应。

解决方法

在nginx中添加如下配置:


http {
    ...
    # 设置缓存的路径和其他参数
    # proxy_cache_path path [levels=levels] keys_zone=name:size [inactive=time] [max_size=size] [loader_files=number] [loader_sleep=time] [loader_threshold=time];
    # 缓存路径 /data/nginx/cache 缓存结构为 2 层,即该路径下会有 2 层子目录,缓存文件会保存在最下层子目录
    # 缓存的 key 会保存在名为 web_cache 的内存区域,该内存区域大小为 50 m
    # 10 分钟内缓存没有被访问就会过期
    # 缓存文件最多占用 1g 空间
    proxy_cache_path /data/nginx/cache levels=1:2 keys_zone=web_cache:50m inactive=10m max_size=1g;
    # proxy_cache_path 指令必须在 include 指令之前
    include vhosts/*.conf;
    ...
server {
        listen       80;
	underscores_in_headers on;
	...
	location /two {
		proxy_pass_request_headers on;
		proxy_pass   http://127.0.0.1:8080/one/;
	# 缓存使用前面定义的内存区域
	proxy_cache web_cache;
	proxy_ignore_headers   Expires Set-Cookie;
	# 对于 200 和 304 的响应码进行缓存,过期时间为 2 分钟,这会覆盖前面定义的 10 分钟过期时间
	proxy_cache_valid 200 304 2m;
	# 设置缓存的 key,这里用到了 nginx 的内嵌变量,表示用整个 url 作 key
	proxy_cache_key  $scheme$proxy_host$request_uri;
		}
	}
}

5.负载均衡登录状态 ip 问题

说明

有些时候需要用nginx做负载均衡,但是后端都是需要提供登录验证的,当一个用户请求nginx地址,登录被分配到节点1服务器上,如果他点了一下其他功能,nginx收到这个请求有给他分配到节点2上面了,节点2上面没有用户的登录状态信息,就会报错,导致功能无法实现有的还给跳回登录页。追踪导致业务无法走通。

解决方案

在负载均衡服务器池中添加ip_hash;[3]命令配置以客户端地址为判断,将这个IP的请求都分配到一个节点上。

upstream backend {
    ip_hash;

    server backend1.example.com;
    server backend2.example.com;
    server backend3.example.com down;
    server backend4.example.com;
}

声明

原文:https://ahaly.cc:86/archives/nginx-pass

作者:https://www.ahaly.cc

联系:liu.liuy@qq.com

资料参考:

Module ngx_http_proxy_module
Module ngx_http_core_module
关于Nginx反向代理时headers无效的问题 - 知乎
解决nginx proxy_pass反向代理cookie,session丢失的问题_youngboy的博客-CSDN博客
Nginx invalid token(token若是带下划线)_leonin12的博客-CSDN博客
前端通过Nginx反向代理解决跨域问题 - ddlove - 博客园


  1. 什么是token - 简书 ↩︎

  2. nginx反向代理缓存_li12412414的博客-CSDN博客_反向代理缓存 ↩︎

  3. Module ngx_http_upstream_module ↩︎

# nginx 

评论

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×