华子目录
nginx反向代理功能
反向代理
:reverse proxy
,指的是代理外网用户的请求
到内部的指定的服务器
,并将数据
返回给用户
的一种方式
,这是用的比较多
的一种方式
Nginx
除了可以在企业
提供高性能
的web服务
之外,另外还可以将nginx
本身不具备的请求
通过某种预定义的协议
转发至其它服务器处理
,不同的协议
就是Nginx服务器
与其他服务器
进行通信
的一种规范
,主要在不同的场景
使用以下模块
实现不同的功能:
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协议转发至指定服务器处理
逻辑调用关系:
访问逻辑图:
同构代理
:用户
不需要其他程序
的参与
,直接
通过http协议
或者tcp协议
访问后端服务器
异构代理
:用户
访问资源
时需要经过处理后
才能返回
,比如php,python等等
,这种访问资源
需要经过处理
才能被访问
http反向代理
官方文档:
https://nginx.org/en/docs/http/ngx_http_proxy_module.html
反向代理配置参数
proxy_pass
用来设置将客户端请求转发给的后端服务器的主机,
- 可以是
主机名:端口
、IP地址:端口
- 也可以
代理
到预先设置
的主机群组
,需要模块ngx_http_upstream_module
支持proxy_hide_header field
用于nginx作为反向代理的时候,在返回给客户端http响应时,隐藏后端服务器相应头部的信息,可以设置在http,server或location块
bash
#示例: 隐藏后端服务器ETag首部字段
location /web {
index index.html;
proxy_pass http://10.0.0.18:8080/;
proxy_hide_header ETag;
}
proxy_pass_header field
透传,默认nginx在响应报文中不传递后端服务器的首部字段Date, Server, X-Pad, X-Accel等参数,如果要传递的话则要使用proxy_pass_header field声明将后端服务器返回的值传递给客户端
field 首部字段大小不敏感
bash
#示例:透传后端服务器的Server和Date首部给客户端,同时不再响应报中显示前端服务器的Server字段
proxy_pass_header Server;
proxy_pass_header Date;
proxy_pass_request_body on | off
是否向后端服务器发送HTTP实体部分,可以设置在http,server或location块,默认即为开启
proxy_pass_request_headers on | off
是否将客户端的请求头部转发给后端服务器,可以设置在http,server或location块,默认即为开启
proxy_set_header
可更改或添加客户端的请求头部信息内容并转发至后端服务器,比如在后端服务器想要获取客户端的真实IP的时候,就要更改每一个报文的头部
bash
#示例:
location ~ /web {
proxy_pass http://172.25.254.20:80;
proxy_hide_header ETag;
proxy_pass_header Server;
proxy_pass_request_body on;
proxy_pass_request_headers on;
proxy_set_header X-Forwarded-For $remote_addr;
}
proxy_connect_timeout time
配置nginx服务器与后端服务器尝试建立连接的超时时间,默认为60秒
bash
#用法如下:proxy_connect_timeout 60s;
#60s为自定义nginx与后端服务器建立连接的超时时间,超时会返回客户端504响应码
proxy_read_timeout time
配置nginx服务器向后端服务器或服务器组发起read请求后,等待的超时时间,默认60s
proxy_send_timeout time
配置nginx项后端服务器或服务器组发起write请求后,等待的超时 时间,默认60s
proxy_http_version 1.0
用于设置nginx提供代理服务的HTTP协议的版本,默认http 1.0
proxy_ignore_client_abort off
当客户端网络中断请求时,nginx服务器中断其对后端服务器的请求。即如果此项设置为on开启,则服务器、会忽略客户端中断并一直等着代理服务执行返回,如果设置为off,则客户端中断后Nginx也会中断客户端请求并立即记录499日志,默认为off
proxy_pass
的注意事项
bash
location /web {
index index.html;
proxy_pass http://172.25.254.30:8080;
}
#8080后面无uri,即无/符号,会将location后面的url加到proxy_pass指定的url后面,此行为类似于root
#proxy_pass指定的uri不带斜线将访问/web下的内容
- 如果
location
定义其uri
时使用了正则表达式
模式(包括~,~*,但不包括^~
),则proxy_pass
之后必须
不能使用uri
。即不能
有/
,用户请求
时传递的uri
将直接附加
至后端服务器
之后
bash
location /web {
index index.html;
proxy_pass http://172.25.254.30:8080/;
}
#8080后面有uri,即/符号,此行为类似于alias
#proxy_pass指定的uri带斜线等于访问http://172.25.254.30:8080/index.html
location中的proxy_pass只能有一个,不能有多个,否则会报错
案例
:反向代理
单台后端服务器
nginx服务器
:172.25.254.100
www.huazi.org
web1服务器
:172.25.254.10
bash
[root@web1 ~]# yum install httpd -y
[root@web1 ~]# echo 172.25.254.10 > /var/www/html/index.html
[root@web1 ~]# systemctl start httpd
bash
[root@nginx-node1 ~]# vim /usr/local/nginx/conf.d/vhosts.conf
server {
listen 80;
server_name www.huazi.org;
location / {
proxy_pass http://172.25.254.10:80;
}
}
[root@nginx-node1 ~]# nginx -s reload
测试:
当访问www.huazi.org
时,nginx
会将请求代理到web1
上
案例:反向代理
实现动静分离
nginx服务器
:172.25.254.100
www.huazi.org
web1服务器
:172.25.254.10
动
web2服务器
:172.25.254.20
静
bash
[root@web1 ~]# yum install php -y
[root@web1 ~]# vim /var/www/html/index.php
<?php
phpinfo();
?>
[root@web1 ~]# systemctl restart httpd
bash
[root@web2 ~]# yum install httpd -y
[root@web2 ~]# mkdir -p /var/www/html/static
[root@web2 ~]# echo static 172.25.254.20 > /var/www/html/static/index.html
[root@web2 ~]# systemctl start httpd
bash
[root@nginx-node1 ~]# vim /usr/local/nginx/conf.d/vhosts.conf
server {
listen 80;
server_name www.huazi.org;
location ~ \.php$ {
proxy_pass http://172.25.254.10:80;
}
location /static {
proxy_pass http://172.25.254.20:80;
}
}
[root@nginx-node1 ~]# nginx -s reload
测试
案例
:反向代理
的缓存功能
proxy_cache zone_name | off; 默认off
指明调用的缓存,或关闭缓存机制
zone_name
表示缓存的名称
,需要由proxy_cache_path
事先定义
proxy_cache_key string
缓存中用于"键"的内容,默认值:proxy_cache_key $scheme$proxy_host$request_uri;
proxy_cache_valid [code ...] time;
定义对特定响应码的响应内容的缓存时长,定义在http{...}中
示例:
proxy_cache_valid 200 302 10m;
对于 HTTP 响应状态码为 200(OK)和 302(Found,通常用于临时重定向)的响应,它们将被缓存,并且缓存有效期为 10 分钟(10m)
proxy_cache_path 路径
定义可用于proxy功能的缓存
proxy_cache_use_stale error | timeout | invalid_header | updating | http_500 | http_502 | http_503 | http_504 | http_403 | http_404 | off ; 默认是off
在被代理的后端服务器出现哪种情况下,可直接使用过期的缓存响应给客户端
示例
proxy_cache_use_stale error http_502 http_503;
proxy_cache_methods GET | HEAD | POST ...;
对哪些客户端请求方法对应的响应进行缓存,GET和HEAD方法总是被缓存
bash
#示例:在http配置定义缓存信息
proxy_cache_path /var/cache/nginx/proxy_cache levels=1:2:2 keys_zone=proxycache:20m inactive=120s max_size=10g;
#/var/cache/nginx/proxy_cache 定义缓存保存路径,proxy_cache会自动创建
#levels=1:2:2 定义缓存目录结构层次,1:2:2可以生成2^4x2^8x2^8=2^20=1048576个目录
#keys_zone=proxycache:20m 定义了一个名为proxycache的缓存键区域,并为其分配了20MB的内存,一般1M可存放8000个左右的key
#inactive=120s 缓存有效时间
#max_size=10g 最大磁盘占用空间,磁盘存入文件内容的缓存空间最大值
#调用缓存功能,需要定义在相应的配置段,如server{...};或者location等
proxy_cache proxycache;
proxy_cache_key $request_uri; #对指定的数据进行MD5的运算做为缓存的key
proxy_cache_valid 200 302 301 10m; #指定的状态码返回的数据缓存多长时间,10分钟
proxy_cache_valid any 1m; #除指定的状态码返回的数据以外的缓存多长时间,必须设置,否则不会缓存
非缓存场景下测压
bash
[root@web2 ~]# ab -n 1000 -c 100 http://www.huazi.org/static/index.html
准备缓存
- 在主配置文件中
bash
[root@nginx-node1 ~]# vim /usr/local/nginx/conf/nginx.conf
proxycache
名字可以自定义
bash
[root@nginx-node1 ~]# vim /usr/local/nginx/conf.d/vhosts.conf
bash
[root@nginx-node1 ~]# nginx -s reload
缓存场景下测压
bash
[root@web2 ~]# ab -n 1000 -c 100 http://www.huazi.org/static/index.html
- 发现请求
变快了
验证缓存文件
反向代理负载均衡(7层)
官方文档
: https://nginx.org/en/docs/http/ngx_http_upstream_module.html- 在
上面的案例
中Nginx
可以将客户端
的请求
转发至单台后端服务器
,但是无法转发
至特定的一组
的服务器
,而且不能对后端服务器
提供相应的服务器状态监测
Nginx
可以基于ngx_http_upstream_module模块
提供服务器分组转发、权重分配、状态监测、调度算法
等高级功能
upstream
配置参数
bash
http {
upstream name {
server ip:port [params];
......................
}
server {
location / {
proxy_pass http://name;
}
}
}
upstream中的server
支持的params
如下
bash
weight=number #设置权重,默认为1,实现类似于LVS中的WRR,WLC等
max_conns=number #给当前后端server设置最大活动链接数,默认为0表示没有限制
max_fails=number #后端服务器的下线条件,当客户端访问时,对本次调度选中的后端服务器连续进行检测多少次,如果都失败就标记为不可用,默认为1次,当客户端访问时,才会利用TCP触发对探测后端服务器健康性检查,而非周期性的探测
fail_timeout=time #后端服务器的上线条件,对已经检测到处于不可用的后端服务器,每隔此时间间隔再次进行检测是否恢复可用,如果发现可用,则将后端服务器参与调度,默认为10秒
backup #设置为备份服务器,当所有后端服务器不可用时,才会启用此备用服务器
down #标记为down状态,可以平滑下线后端服务器
resolve #当server定义的是主机名的时候,当A记录发生变化会自动应用新IP而不用重启
负载均衡算法
Nginx
支持多种负载均衡算法
,常见的包括
:
轮询
(Round Robin
):默认算法
,按照顺序
将请求
依次分发到后端服务器
权重
(Weighted Round Robin
):为每个后端服务器
设置权重
,权重高
的服务器
分配的请求
会更多
IP 哈希
(ip_hash
):根据客户端 IP
的哈希值
决定分发到哪台后端服务器
,适用于需要保持会话一致性
的场景
最少连接
(least_conn
):将请求
分配给当前连接数最少
的后端服务器
hash
(指定字段哈希
):基于指定
的请求字段
(如URL、Cookie等
)来分配请求
案例:反向代理
多台web服务器
(轮询
)
- 需要
location块
中的proxy_pass参数
和upstream块
配合使用upstream块
和server块
是同级的
bash
[root@nginx-node1 ~]# vim /usr/local/nginx/conf.d/vhosts.conf
upstream webcluster {
server 172.25.254.10:80 fail_timeout=15s max_fails=3;
server 172.25.254.20:80 fail_timeout=15s max_fails=3;
server 172.25.254.100:80 backup;
}
server {
listen 80;
server_name www.huazi.org;
location / {
proxy_pass http://webcluster;
}
}
max_fails=number
后端服务器的下线条件
,当客户端访问时,对本次调度选中的后端服务器连续进行检测多少次,如果都失败就标记为不可用
,默认为1次
,当客户端访问时,才会利用TCP触发对探测后端服务器健康性检查,而非周期性的探测
fail_timeout=time
后端服务器的上线条件
,对已经检测到处于不可用的后端服务器,每隔此时间间隔再次进行检测是否恢复可用
,如果发现可用,则将后端服务器参与调度,默认为10秒
backup关键字
意味着只有当webcluster组
中的其他所有服务器
都不可用
时,Nginx
才会向这个服务器
发送请求
bash
[root@nginx-node1 ~]# nginx -s reload
测试:
案例:反向代理
多台web服务器
(源地址hash调度
)
- 有
ip_hash
,就不能有backup
bash
[root@nginx-node1 ~]# vim /usr/local/nginx/conf.d/vhosts.conf
upstream webcluster {
ip_hash;
server 172.25.254.10:80 fail_timeout=15s max_fails=3;
server 172.25.254.20:80 fail_timeout=15s max_fails=3;
}
server {
listen 80;
server_name www.huazi.org;
location / {
proxy_pass http://webcluster;
}
}
bash
[root@nginx-node1 ~]# nginx -s reload
测试:
案例:反向代理
多台web服务器
(对uri进行hash调度
)
bash
[root@nginx-node1 ~]# vim /usr/local/nginx/conf.d/vhosts.conf
upstream webcluster {
hash $request_uri consistent;
server 172.25.254.10:80 fail_timeout=15s max_fails=3;
server 172.25.254.20:80 fail_timeout=15s max_fails=3;
}
server {
listen 80;
server_name www.huazi.org;
location / {
proxy_pass http://webcluster;
}
}
[root@nginx-node1 ~]# nginx -s reload
bash
[root@web1 ~]# mkdir -p /var/www/html/static/
[root@web1 ~]# echo 172.25.254.10 static > /var/www/html/static/index.html
案例:反向代理
多台web服务器
(对cookie值进行hash调度
)
bash
[root@nginx-node1 ~]# vim /usr/local/nginx/conf.d/vhosts.conf
upstream webcluster {
hash $cookie_huazi;
server 172.25.254.10:80 fail_timeout=15s max_fails=3;
server 172.25.254.20:80 fail_timeout=15s max_fails=3;
}
server {
listen 80;
server_name www.huazi.org;
location / {
proxy_pass http://webcluster;
}
}
[root@nginx-node1 ~]# nginx -s reload
案例:反向代理
多台web服务器
(下线
)
bash
upstream webcluster {
hash $cookie_huazi;
server 172.25.254.10:80 fail_timeout=15s max_fails=3 down;
server 172.25.254.20:80 fail_timeout=15s max_fails=3;
}
server {
listen 80;
server_name www.huazi.org;
location / {
proxy_pass http://webcluster;
}
}
[root@nginx-node1 ~]# nginx -s reload
反向代理负载均衡(4层)
bash
stream {
upstream backend {
server backend1.example.com:3306;
server backend2.example.com:3306;
}
server {
listen 3306;
proxy_pass backend;
}
}
Nginx
在1.9.0版本
开始支持tcp模式
的负载均衡
,在1.9.13版本
开始支持udp协议
的负载
,udp
主要用于DNS
的域名解析
,其配置方式
和指令
和http
代理类似
,其基于ngx_stream_proxy_module模块
实现tcp负载
,另外基于模块ngx_stream_upstream_module
实现后端服务器分组转发、权重分配、状态监测、调度算法等高级功能
- 如果
编译安装
,需要指定--with-stream
选项才能支持ngx_stream_proxy_module模块
官方文档
:https://nginx.org/en/docs/stream/ngx_stream_proxy_module.html
案例
:基于udp
的dns的负载均衡
nginx服务器
:172.25.254.100
www.huazi.org
dns1服务器
:172.25.254.10
dns2服务器
:172.25.254.20
先配置dns服务器
bash
[root@web1 ~]# yum install bind -y
[root@web1 ~]# vim /etc/named.conf
bash
[root@web1 ~]# vim /etc/named.rfc1912.zones
bash
[root@web1 ~]# cd /var/named/
[root@web1 named]# cp -a named.localhost /var/named/huazi.com.zone
[root@web1 named]# vim huazi.com.zone
bash
[root@web1 named]# systemctl start named
[root@web1 named]# dig www.huazi.com @172.25.254.10
bash
[root@web2 ~]# yum install bind -y
[root@web2 ~]# vim /etc/named.conf
bash
[root@web2 ~]# vim /etc/named.rfc1912.zones
bash
[root@web2 ~]# cd /var/named/
[root@web2 named]# cp -a named.localhost /var/named/huazi.com.zone
[root@web2 named]# vim huazi.com.zone
bash
[root@web2 named]# systemctl start named
[root@web2 named]# dig www.huazi.com @172.25.254.20
nginx配置
udp和tcp的负载均衡要写在http块之外
bash
#修改主配置文件
[root@nginx-node1 ~]# vim /usr/local/nginx/conf/nginx.conf
bash
[root@nginx-node1 ~]# mkdir -p /usr/local/nginx/tcpconf.d/
[root@nginx-node1 ~]# vim /usr/local/nginx/tcpconf.d/dns.conf
stream {
upstream dns {
server 172.25.254.10:53 fail_timeout=15s max_fails=3;
server 172.25.254.20:53 fail_timeout=15s max_fails=3;
}
server {
listen 53 udp reuseport;
proxy_timeout 20s;
proxy_pass dns;
}
}
[root@nginx-node1 ~]# nginx -s reload
测试
100
上没有dns服务
,dig
却可以指定
到100
,通过100
进行代理
案例
:基于tcp
的MySQL的负载均衡
nginx服务器
:172.25.254.100
www.huazi.org
MySQL1服务器
:172.25.254.10
MySQL2服务器
:172.25.254.20
数据库配置
bash
[root@web1 ~]# yum install mariadb-server -y
[root@web2 ~]# yum install mariadb-server -y
bash
[root@web1 ~]# vim /etc/my.cnf.d/mariadb-server.cnf
bash
[root@web2 ~]# vim /etc/my.cnf.d/mariadb-server.cnf
nginx配置
bash
[root@nginx-node1 ~]# vim /usr/local/nginx/tcpconf.d/dns.conf
bash
[root@nginx-node1 ~]# nginx -s reload
下载MySQL的客户端
bash
[root@nginx-node1 ~]# yum install mariadb -y
测试