nginx反向代理

反向代理(reverse proxy)

实现动静分离,后端交给tomcat等处理

两种代理级别:

  • 7层反向代理
  • 4层反向代理,也叫负载均衡

反向代理含义:

指的是代理外网用户的请求到内部的指定的服务器,并将数据返回给用户的一种方式,这是用的比较多的一种方式。Nginx除了可以在企业提供高性能的web服务之外,另外还可以将nginx本身不具备的请求通过某种预定义的协议转发至其它服务器处理,不同的协议就是Nginx服务器与其他服务器进行通信的一种规范,主要在不同的场景使用以下模块实现不同的功能

5种代理模块:

模块 说明
ngx_http_proxy_module 将客户端的请求以http协议转发至指定服务器进行处理
ngx_http_upstream_module 用于定义为proxy_pass,fastcgi_pass,uwsgi_pass等指令引用的后端服务器分组
ngx_stream_proxy_module 将客户端的请求以tcp协议转发至指定服务器处理
ngx_http_fastcgi_module 将客户端对php的请求以fastcgi协议转发至指定服务器助理
ngx_http_uwsgi_module 将客户端对Python的请求以uwsgi协议转发至指定服务器处理

nginx代理和lvs的区别:

  • nginx代理主机是中间人,客户端请求代理机,代理机自己重新构建请求报文,发给服务器。服务器响应给代理主机,代理主机接收后,自己重新构建响应报文,发送给客户端。client到server之间,不会知对方真实面目
  • lvs是工作在四层的,只能对ip和端口做出修改,不能处理报文的内容。且直接由客户端请求服务器,或服务器直接响应客户端,报文内容没有修改过。client到server之间,知道双方真实面目

nginx的7层反向代理:

http {
	upstream name {
	...
	}
	server {
		location / {
			proxy_pass name;
		}
	
	}
}

基础反向代理(仅支持http协议):

官方文档: https://nginx.org/en/docs/http/ngx_http_proxy_module.html

配置参数:

proxy_pass [http://]代理;	 设置被代理的后端服务器,可以是主机名、ip:port,主机群(upstream)
	例:设置被代理主机时,没有“/”为访问:1.1.1.10:8080/web的/web目录。有带“/”时,访问/web目录为直接访问:1.1.1.10:8080
	   location /web {
		proxy_pass http://1.1.1.10:8080;
	   }

proxy_timeout 秒;			nginx的转发超时时间
proxy_set_header 字段名 首部字段;		修改、添加客户端发往服务端的请求头部,主要在日志中记录
	代理过程有四段:	报文传递
	   1、 客户端-->代理主机		不可修改报文
	   2、 代理主机-->服务器 	 可修改报文
	   3、 服务器-->代理主机 		不可修改 
	   4、 代理主机-->客户端 	可修改报文
	例: 实现服务端获取客户端真实ip
	   location /web {
		proxy_pass http://1.1.1.10:8080;
		proxy_set_header X-real-IP $remote_addr;	
		#X-real-IP是自定义首部参数名称,存放的客户端ip
	   }
	   
proxy_hide_header 响应头部字段;		隐藏服务端的响应报文字段(大小写不敏感),可设置在http、server、location中
	例: 隐藏服务端的响应报文的etag字段
	   location /web {
		proxy_pass http://1.1.1.10:8080;
		proxy_hide_header etag;
	   }

proxy_pass_header 响应首部字段;		默认隐藏后端服务器的:Date、Server、X-Pad、X-Accel等参数,如果需要把这些自动禁用的参数显示,用此声明后传递给客户端
	例:	显示服务端响应报文的server和date字段
	   proxy_pass_header date;

proxy_pass_request_body on|off;		向后端发送http实体部分,用在http、server、location,默认开启
proxy_pass_request_headers on|off;	将客户端请求头部转发给后端,用在http、server、location,默认开启
proxy_connect_timeout 秒;		nginx与后端尝试建立连接的超时时间,默认60s。超时返回504响应码
	例:
	   proxy_connect_timeout 15s;

proxy_read_timeout 秒;		nginx发起请求读取后端响应报文的等待超时时间,如果后端服务很忙,处理不过来请求,就要排队,该参数指定nginx和后端之间,重传响应报文的间隔,默认60s
proxy_send_timeout 秒;		nginx向后端发起写请求后,等待超时时间,如后端没有在时间内处理nginx发来的请求,则关闭请求连接,默认60s
	注意:real和send两项取决于后端服务器的性能水平,如果后端繁忙、客户端请求的文件很大时需要等待很久。根据生产场景配置,公司内部可以大一点,提供给用户访问时用户可能没60s的耐心(已经很长了)
	
proxy_http_version 1.0;			nginx为后端服务器提供的http协议版本,默认1.0
proxy_ignore_client_abort off|on;	当用户访问时,但因网速慢关闭了浏览器,此时请求已经发起了,默认情况下nginx会在客户端中断请求后立即中断对后端服务器的请求,并立即记录日志499响应码,默认off关闭;on为即使用户中断了请求,nginx会忽略客户端中断,一直等待后端的执行结果返回
proxy_headers_hash_bucket_size 128;	为proxy_hide_header和proxy_set_header设置缓存大小,设置nginx保存http报文头的hash表缓存上限(nginx都是开辟的一段内存空间,存放hash后的缓存,以表的形式存在)
proxy_header_hash_max_size 512;		设置proxy_header_hash_bucket_size的最大可用空间
server_names_hash_buket_size 512;	监听的每个server_name申请的hash表空间大小
server_name_hash_max_size 512;		总的服务器名称hash表最大上限

实现代理缓存功能:

缓存功能默认关闭状态,需要先动配置才能启用
定义必须在http段,其他可用于http、server、location

配置参数:

expires 时间;			缓存有效期
proxy_cache_path		定义proxy的缓存功能,用在http段
	proxy_cache_path path [levels=levels] keys_zone=name:size [inactive=time] [max_size=size] [purger=on|off] [purger_files=number] [purger_sleep=time] ...;
	常用选项解读:
	   path 		磁盘上的路径,写了以后nginx自动创建
	   keys_zone=name:size	缓存名称:内存的缓存空间大小(存hash)。存放key和元数据(如使用次数)
	   levels=1:1:2: 	目录下有几级子目录,每个目录用多少16进制的hash字符表示。每级目录用“:”隔开。1:2:2可存放100w多的目录
	   inactive=time 	缓存的有效时间(存多久)
	   max_size=size 	缓存使用磁盘空间最大值,超出后就是lru算法,最近最少使用清理
	   purger=on|off 	启用缓存修剪功能,自动清理不常用的
	   purger_files=	一次修剪多少个文件
	   purger_sleep=	每隔多久修剪一次缓存
	   use_temp_path	是否使用临时目录
	   manager_files	每次管理进程移除缓存文件的数量
	   manager_threshold	每次移除缓存文件后的间隔
	   
	例:	
	   proxy_cache_path /opt/nginx/proxy_cache levels=1:1:1 keys_zone=pcache:10m max_size=2g inactive=120s;

proxy_cache zone|off;	 使用哪个缓存区域名,默认没有开启。
proxy_cache_key string;		缓存记录哪些内容
	例:
	   #缓存整个url,定义时要考虑协议版本、域名解析、url内容(默认缓存这些)
	   proxy_cache_key $scheme$proxy_host$request_uri;

proxy_cache_methods GET HEAD;	哪些方法请求时,缓存下来
proxy_cache_min_uses 1;		请求多少次相同的内容才会缓存下来,默认是请求一次就记录
proxy_cache_valid 响应码 时间;	为不同的响应码设置缓存时间。any为所有
	注意: 当成功响应码设置时间较长时,后端的代码业务升级后需要把缓存都清掉,或者时间设短,否则容易出现依然拿缓存的旧内容响应客户端,新升级代码的不会正确显示
	例: 总体缓存配置,进行压测
	  http {
		proxy_cache_path /opt/nginx/pcache
		  levels=2:2:2
		  keys_zone=pcache:128m
		  inactive=180s
		  max_size=5g;
		  
		server {
			location /proxy {
				proxy_cache pcache;
				proxy_cache_key $request_uri;
				proxy_cache_valid 200 301 302 1h;
				proxy_cache_valid 404 1m;
				#proxy_cache_valid any 3m;
			}
		}
	  }
	例2: 缓存压测和非缓存压测
	  #准备压测文件
	  cat /var/log/message >> /opt/web/1.txt
	  cat /var/log/message >> /opt/web/proxy/2.txt
	  #第一次压测未使用缓存,总共2000请求,200个并发连接
	  ab -n 2000 -c 200 http://www.hj.com/1.txt	
	  #第二此压测,使用缓存
	  ab -n 2000 -c 200 http://www.hj.com/proxy/2.txt

proxy_cache_use_stale error | timeout | invalid_header | updating | http_500 | http_502 | http_503 | http_504 | http_403 | http_404 | http_429 | off ...;	后端服务器返回哪些状态时,nginx可用本地的缓存来响应客户端。默认不允许
	缓存的内容包含通用首部、web内容
	选项解读:	
	  error 		与后端建立连接、发送请求、读取响应头等出错时,使用缓存
	  timeout		与后端建立连接、发送请求、读取响应头等超时,使用缓存
	  updating		缓存内容过期时,由一个请求正在访问后端,试图更新缓存时,其他请求直接使用过期内容返回客户端
	  invalid_header  	服务器的响应首部出现非法首部
	  http_500		服务器响应报文是500,则使用缓存内容做响应报文发给client。其他http_...一样效果
	  off 			关闭,默认
	例: 用于服务降级,哪怕是错误的也比没有页面返回
	  proxy_cache_use_stale error http_502 http_503;

proxy_cache_lock		第一次请求时没有该缓存,nginx会去找后端主机,第二次以后访问同样的资源,会直接使用之前的缓存
proxy_cache_lock_timeout 秒;	缓存的存储时间,失效后nginx把来的请求直接给后端主机
proxy_no_cache			满足条件的响应不会被保存到缓存中

缓冲相关配置

缓冲区配置是基于每个请求分配空间,并不是整体的共享空间,可根据业务的每个请求平均数据大小分配
缓冲区去减少及时传输带来的带宽消耗

配置

proxy_buffering on;			#启用缓冲
proxy_buffers 4 64k;			#为每个请求设置缓冲区的数量和大小,默认4 4k/8k
proxy_buffer_size 16k;			#设置响应头缓冲区大小
proxy_busy_buffers_size 128k;		#后端数据没有完全响应完时,允许将busy状态的缓冲返回给客户端。配置busy状态的缓冲大小,默认为proxy_buffer_size*2
proxy_temp_file_write_size 128k;	#设置每次写数据到临时文件的大小限制
proxy_max_temp_file_size 1M;		#临时缓冲文件最大容量

添加响应报文自定义首部:

基于模块ngx_http_headers_module
实现对后端服务器响应给客户端的报文中添加指定的响应首部字段,较少使用。主要是在报文中直接显示
用于http、server、location、if

官方文档:https://nginx.org/en/docs/http/ngx_http_headers_module.html

add_header 字段名 值 [always];	
add_trailer name value [always];	添加自定义响应信息的尾部,使用较少,1.13.2以后支持
例:
location /static {
	proxy_pass http://1.1.1.10:80/;
	proxy_cache pcache;
	proxy_cache_key $request_uri;
	proxy_cache_valid 200 302 301 1h;
	proxy_cache_valid any 1m;
	proxy_set_header clientip $remote_addr;
	add_header X-via $server_addr;	#生产场景不建议公开ip
	add_header X-fqdn $server_name;	#生产场景可以公开主机名
	add_header X-cache $upstream_cache_status;	
	#允许从其他域名访问过来
	add_header Access-Control-Allow-Origin *;
}

反向代理高级功能:

http_upstream是运行在应用层的负载均衡模块。基于ngx_http_upstream_module模块,提供服务器分组转发、权重分配、状态检测、调度算法等高级功能
stream和stream_upstream是工作于3、4层的负载均衡

会话粘性相关

session sticky(会话粘性):

  • source ip: lvs的sh算法,进行ip地址绑定
  • cookie: 给http协议提供cookie,每个用户一个cookie,基于cookie绑定

session replication(会话复制):

  • 应用服务器做一个集群,会话经过组播通信,组播内的主机都是复制会话

session server:

  • 做内存级别的缓存

配置参数:

http {
	upstream 名称 { 	仅用于http段
		server 服务器1 [选项];
		server 服务器2 [选项];
		其他参数;
	}
}
选项:
weight=int;		设置权重,默认轮询算法,1
max_conns=num;		当前server的最大并发连接数(这台服务器只能处理多少个请求),默认0为无限制
max_fails=int;		tcp健康检测连续失败多少次,标记为不可用(非周期性的)。默认1次,0为关闭
fail_timeout=time 	对后端服务器的单次监测超时时间,默认为10秒
proxy_next_upstream=状态   指定在哪些检测状态下将请求转发给其他服务器,默认error、timeout
	状态:
	  error			与后端建立连接、向后端传递请求或阅读响应头时发生错误
	  timeout		与后端建立连接、向后端传递请求或阅读响应头时发生了超时
	  invalid_header	后端服务器返回空响应或无效响应
	  http_500		后端服务器返回500的响应
	  http_...		其他响应码
	  non_idempotent
	  off			禁用将请求传递给下一台服务器
backup		将主机标记为备用状态,所有server挂了,就启用
down		手动标记主机为下线状态,算法也不会调度该主机了
resolve 	当server定义的是主机名的时候,若A记录发生变化会自动应用新IP而不用重启Nginx(自动解析)
slow_start	缓慢调度。当原主机请求4000,新加入一台主机,调度时会缓慢把a主机的4000请求分配过来,一次一点的分
其他参数:
ip_hash;	源地址hash算法(地址绑定,实现会话保持)
hash key [consistent];		比ip_hash更强大的选项。基于指定请求报文中首部字段(cookie、变量)或者URI等key做hash计算来进行绑定
	consistent为使用ketama一致性hash算法,适用于后端是cache服务器(如varnish)时使用。不加时默认为取模法
	
least_conn;		最少连接调度算法,lc算法,加权重后是lvs的WLC算法
keepalive num;		当做客户端请求服务器时,不开启长连接就要消耗大量的套接字,开启长连接后,可让一个连接服务于多个请求。此处设置每个worker进程与后端服务器维持的长连接个数是多少
例:

hash建议用在缓存主机上,更加方便

upstream name {
	hash $remote_addr;	绑定客户端ip,可实现ip_hash一样的功能
	hash $cookie_name;	绑定cookie名称
	hash $cookie_sessionid;		基于cookie中的sessionid这个key进行hash调度,实现会话绑定
	hash $request_uri;	uri哈希后,与权重总数取模,根据取模后的数字对应哪个主机,但在一台主机失效时,就有雪崩效应,所有缓存失效。此方法叫:取模法、映射法
	hash $remote_addr consistent;	consistent时某服务器失效,只会丢失uri计算模的最近的两台服务器缓存,不再是全部。此方法是:一致性哈希
}
例: 基于cookie实现会话绑定
upstream web {
	hash $cookie_键;
	server 1.1.1.10 weight=2 max_fails=3 slow_start;
	keepalive 32;	#默认保持32个持久连接与1.1.1.10主机
}
server {
	...
	proxy_pass http://web;
}

nginx的4层反向代理:

运用stream模块,只能代理4层协议(ip、port),可以通过代理端口实现http、https
功能与lvs相似
在1.9.0版本开始支持tcp模式的负载均衡,在1.9.13版本开始支持udp协议的负载,udp主要用于DNS的域名解析,其配置方式和指令和http代理类似,其基于ngx_stream_proxy_module模块实现tcp负载,另外基于模块ngx_stream_upstream_module实现后端服务器分组转发、权重分配、状态监测、调度算法等高级功能
编译安装要开启--with-stream,配置时是单独的配置段

官方文档:
https://nginx.org/en/docs/stream/ngx_stream_proxy_module.html
http://nginx.org/en/docs/stream/ngx_stream_upstream_module.html

stream {
	#stream模块也有upstream参数,与http的upstream模块使用方法差不多,但两者并不是同一个东西
	upstream 代理名 {
		...
	}
}
例1: 实现ssh随机分配
stream {
	upstream sshbl {		
		server 1.1.1.10:22;
		server 1.1.1.20:22;	
		#hash $remote_addr consistent;
	}
	server {
		listen 222;
		proxy_pass sshsr;
		proxy_timeout 60s;		nginx向服务器请求、响应的超时时间。默认10s
		proxy_connect_timeout 10s;		nginx与服务器之间的尝试连接的超时时间。默认60s;
	}
}
例2: 实现web、dns的负载均衡
stream {
	upstream dns {
		server dns.hj.com:53;
		server 1.1.1.10:533;
	}
	upstream web {
		server 1.1.1.20 fail_timeout=30s max_fails=3;
		server 1.1.1.30 fail_timeout=30s max_fails=3;
	}
	
	server {
		listen 533 reuseport;
		proxy_pass dns;
	}
	server {
		listen 81;
		proxy_pass web;
		proxy_timeout 3s;
		proxy_connect_timeout 1s;
	}
}
posted @ 2022-02-13 21:32  suyanhj  阅读(499)  评论(0)    收藏  举报