目录
3.5.2.2 轮询权值(Weighted Round Robin)
2.nginx\_upstream\_check\_module模块
一.故事背景
紧接上文,上篇文章讲述了nginx的相关内容,本篇内容将把nginx剩下的内容收尾,
二.配置Nignx状态统计
1、下载vts模块
https://github.com/vozlt/nginx-module-vts
2、编译nginx
tar xf nginx-module-vts-master.zip
cd nginx-1.22.1/
./configure --prefix=/usr/local/nginx/ --add-module=/root/nginx-module-vts-master && make && make install
3、配置状态统计页面
每次刷新时,请求会加一
在经过平滑升级添加模块后(具体升级过程在下面),在nginx.conf中新加内容,并在server外加域
重启nginx,此时进入网址则会出现以下界面
三.Nginx平滑升级
1. Nginx平滑升级原理
-
在不停掉老进程的情况下,启动新进程。
-
老进程负责处理仍然没有处理完的请求,但不再接受处理请求。
-
新进程接受新请求。
-
老进程处理完所有请求,关闭所有连接后,停止。
2. Nginx信号
2.1主进程支持的信号
TERM,INT:立刻退出;
QUIT:等待工作进程结束后再退出;
KILL:强制终止进程;
HUP:重新加载配置文件,使用新的配置启动工作进程,并逐步关闭旧进程;
USR1:重新打开日志文件;
USR2:启动新的主进程,实现热升级;
WINCH:逐步关闭工作进程。
2.2 工作进程支持的信号
TERM,INT:立刻退出;
QUIT:等待请求处理结束后再退出;
USR1:重新打开日志文。
3. 平滑升级实战
3.1 Nginx添加新模块
1.先停掉服务,再将压缩包解压,再将解压完成的文件移动到/usr/local/nginx下
2.然后进行编译(要附带之前的模块,不然功能就没了),然后进行make
3.编译成功后,将原有命令进行备份
4.此时的nginx就有了新加的模块
5.检查新版本nginx是否正常
6.给nginx发送平滑迁移信号,查看nginx pid,会出现一个nginx.pid.oldbin,关闭旧的Nginx进程,结束工作进程,完成此次升级,验证Nginx是否升级成功.
3.3.2 Nginx版本升级
安装Nginx1.25.3版本
(1)下载Nginx1.25.3/1.27.3版本包
wget http://nginx.org/download/nginx-1.25.3.tar.gz
(2)安装依赖环境
(3)进行安装
(4)启动Nginx服务
(5)查看Nginx版本和模块
升级Nginx到1.27.3版本
将 nginx1.6版本进行升级(升级为Nginx1.18版本)并在不影响业务的情况下添加 SSL 和 pcre 模块。
(1)升级
(2)进行make
注意:这里不能进行,make install 操作,否则将会被覆盖,可能会影响线上业务。
(3)拷贝Nginx1.27.3版本的二进制文件到1.25.3版本
(4)启动新的主进程,实现热升级
(5)查看升级后的版本,成功升级为1.27.3
四.nginx实现灰度发布
1.基于权重的灰度发布(适合逐步验证新版本)
原理:通过upstream
模块的weight
参数分配流量比例,逐步将新版本服务器权重调高。
配置示例:
upstream backend {
server 192.168.1.100 weight=90; # 旧版本
server 192.168.1.101 weight=10; # 新版本
}
server {
listen 80;
location / {
proxy_pass http://backend;
}
}
操作步骤:
-
新版本服务器部署完成后,通过调整权重分配少量流量(如10%)。
-
验证无问题后,逐步提高新版本权重直至100%。
适用场景:简单验证新版本稳定性,无需区分用户群体。
2.基于客户端请求的灰度发布(精准控制用户群体)
1. Cookie或Header标识
原理:根据请求中的Cookie或Header值(如version=V2
)转发到特定服务器。
配置示例:
upstream stable { server 192.168.1.100; }
upstream canary { server 192.168.1.101; }
map $http_cookie $group {
~*version=V2 canary;
default stable;
}
server {
listen 80;
location / {
proxy_pass http://$group;
}
}
适用场景:A/B测试或定向邀请用户试用新功能。
2. IP地址过滤
原理:将特定IP的请求转发到新版本服务。
配置示例:
server {
listen 80;
set $backend "stable";
if ($remote_addr = "10.0.0.1") { # 允许特定IP访问新版本
set $backend "canary";
}
location / {
proxy_pass http://$backend;
}
}
适用场景:内部测试或定向开放给特定区域用户。
3.组合策略(灵活控制流量)
原理:结合权重和请求标识,优先匹配特定用户,剩余流量按比例分配。
配置示例:
map $http_cookie $group {
~*version=V2 canary;
default $default_group;
}
upstream backend {
server 192.168.71.149 weight=90;
server 192.168.71.152 weight=10;
}
server {
listen 80;
set $default_group backend;
location / {
proxy_pass http://$group;
}
}
适用场景:既有定向用户测试,又有逐步放量的需求。
4.操作注意事项
-
配置生效:修改Nginx配置后需执行
nginx -s reload
重新加载。 -
优先级:基于Cookie/Header的规则通常优先于权重分配。
-
监控与回滚:通过日志监控新版本服务状态,若异常需快速回滚配置。
5.总结
-
简单场景:优先选择权重分配,逐步验证新版本。
-
精准控制:使用Cookie/Header或IP过滤定向用户。
-
复杂需求:结合多种策略实现灵活灰度发布。
通过以上方法,可有效平衡系统稳定性和新功能验证需求。具体实现时需根据业务场景选择最合适的策略。
五.Nginx反向代理与缓存功能
1.正向代理和反向代理
1.1 正向代理概述
1.1.1 什么是正向代理
正向代理代理的是客户端
正向代理是一个位于客户端和目标服务器之间的代理服务器(中间服务器)。为了从目标服务器取得内容,客户端向代理服务器发送一个请求,并且指定目标服务器,之后代理向目标服务器转发请求,将获得的内容返回给客户端
1.1.2 正向代理的作用
-
为在防火墙内的局域网客户端提供访问Internet的途径
-
可以使用缓冲特性减少网络使用率
-
访问受地理位置限制的网络
-
使用代理后会隐藏真实的IP地址
1.1.3 正向代理的基本格式
server {
listen 192.168.71.149:80;
server_name ....;#客户端访问的域名
location / {
proxy_pass http://目标服务器地址;
}
}
1.2 反向代理概述
1.2.1 什么是反向代理
反向代理代理的是服务端
反向代理:(reverse proxy),指的是代理外网用户的请求到内部的指定的服务器,并将数据返回给用户的一种方式 客户端不直接与后端服务器进行通信,而是与反向代理服务器进行通信,隐藏了后端服务器的 IP 地址
1.2.2 反向代理可实现的功能
反向代理的主要作用是提供负载均衡和高可用性。
负载均衡:Nginx可以将传入的请求分发给多个后端服务器,以平衡服务器的负载,提高系统性能和可靠性。
缓存功能:Nginx可以缓存静态文件或动态页面,减轻服务器的负载,提高响应速度。
动静分离:将动态生成的内容(如 PHP、Python、Node.js 等)和静态资源(如 HTML、CSS、JavaScript、图片、视频等)分别存放在不同的服务器或路径上。
多站点代理:Nginx可以代理多个域名或虚拟主机,将不同的请求转发到不同的后端服务器上,实现多个站点的共享端口。
1.2.3 反向代理的可用模块
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协议转发至指定服务器处理
2.配置反向代理
#官方文档:https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_pass
2.1.1 proxy_pass
1. 完整路径转发(精确传递原始URI)
location /api/ {
proxy_pass http://192.168.71.149:8081; # 不带结尾斜杠
}
结果:
客户端请求→http://192.168.71.152/api/user
实际转发→http://192.168.71.149:8081/api/user
2. 路径剥离转发(移除 location 匹配部分)
location /static/ {
proxy_pass http://192.168.71.149/; # 带结尾斜杠
}
结果:
请求 /static/image.jpg →转发到http://192.168.71.149/image.jpg (注意:/static/被剥离)
3. 自定义路径替换
location /legacy/ {
proxy_pass http://192.168.71.149/v2/; # 添加新路径前缀
}
结果:
请求 /legacy/data → 转发到 http://192.168.71.149/v2/data
4. 变量动态转发
location /user/ {
# 根据变量动态选择后端
proxy_pass http://$arg_cluster.backend.com;
}
结果:
请求 /user/profile?cluster=eu → 转发到 http://eu.backend.com/user/profile
2.1.2 其他参数
proxy_hide_header field;
#用于nginx作为反向代理的时候,在返回给客户端http响应时,隐藏后端服务器相应头部的信息,可以设置proxy_hide_header field;proxy_pass_header field;
#默认nginx在响应报文中不传递后端服务器的首部字段Date, Server, X-Pad, X-Accel等参数,如果要传递的话则要使用 proxy_pass_header field声明将后端服务器返回的值传递给客户端#field 首部字段大小不敏感
#示例:透传后端服务器的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块,默认即为开启
3.配置实战
3.1 反向代理单台web服务器
代理服务器
真实服务端
开启http服务
添加地址映射
客户机
测试:客户机访问代理服务器
3.2 指定主机实现反向代理动静分离
因为nginx无法处理动态资源,所以要动静分离。
#代理服务器
vim /local/nginx/conf.d/pc.conf
#编辑子配置文件
location /s {
proxy_pass http://192.168.71.149;
}
location /d {
proxy_pass http://192.168.71.152;
}
nginx -t
nginx -s reload
#重新加载
#动态资源服务器
#关闭防火墙和selinux
systemctl stop firewalld
setenforce 0
#安装nginx服务
yum install -y epel-release
yum install -y nginx
systemctl start nginx
#创建动态资源目录
cd /usr/share/nginx/html
mkdir s
echo this is s > ./s/index.html
#静态资源服务器
#关闭防火墙和selinux
systemctl stop firewalld
setenforce 0
#安装服务
yum install -y epel-release
yum install -y nginx
systemctl start nginx
#创建静态资源目录
cd /usr/share/nginx/html
mkdir d
echo this is d > ./d/index.html
#客户机
#关闭防火墙和selinux
systemctl stop firewalld
setenforce 0
#动态资源
curl 192.168.71.149/s -L
#静态资源
curl 192.168.71.152/d -L
3.3 缓存功能
反向代理可以缓存静态资源。
当客户端再次请求访问相同资源时,反向代理可以直接返回缓存中的响应,无需二次请求,减少对后端服务器的请求压力,并加快响应速度。
3.4 实现反向代理客户端IP透传
3.4.1 基本原理
反向代理客户端IP透传是指在使用反向代理服务器时,将客户端的真实IP地址传递给后端服务器。
这可以通过一些特定的 如X-Forwarded-For
等HTTP 头字段来实现 头字段。
当请求经过反向代理服务器时,代理服务器会将客户端的真实IP地址添加到 XFF 头字段中,然后转发给后端服务器。
后台服务端开启main日志格式调用!!!
3.4.2 一级代理
#代理服务器
vim /usr/local/nginx/conf.d/pc.conf
#编辑子配置文件
server{
listen 192.168.71.71.151:80;
server_name www.pc.com;
root /usr/local/nginx/html/pc;
location / {
proxy_pass http://192.168.71.149;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
######
`$proxy_add_x_forwarded_for` 是一个 nginx 变量,用于获取客户端的真实 IP 地址并将其添加到请求中的 `X-Forwarded-For` 头字段中,后端服务器可以通过检查该头字段来获取请求的真实客户端 IP 地址。
开头绿色是代理地址,最后是真实地址
3.4.3 多级代理
多级和一级同理,在代理服务器再加一个代理服务器2,并让1指向2,可以提高安全性
3.5 实现反向代理负载均衡
Nginx 可以基于ngx_http_upstream_module
模块提供服务器分组转发、权重分配、状态监测、调度算法等高级功能
3.5.1 基本原理
NGINX的负载均衡原理是基于反向代理和事件驱动的机制。
当客户端发送请求时,NGINX作为反向代理服务器接收请求,并根据配置的负载均衡算法
将请求转发到后端的多个服务器上,实现负载均衡。
3.5.2 常见配置参数
#配置一个后端web服务器,配置在upstream内,至少要有一个server服务器配置。
#server支持的parameters如下:
weight=number #设置权重,默认为1,实现类似于LVS中的WRR,WLC等
max_conns=number #给当前后端server设置最大活动链接数,默认为0表示没有限制
max_fails=number #后端服务器的下线条件,当客户端访问时,对本次调度选中的后端服务器连续进行检测多少次,如果都失败就标记为不可用,默认为1次,当客户端访问时,才会利用TCP触发对探测后端服务器健康性检查,而非周期性的探测
fail_timeout=time #后端服务器的上线条件,对已经检测到处于不可用的后端服务器,每隔此时间间隔再次进行检测是否恢复可用,如果发现可用,则将后端服务器参与调度,默认为10秒
sorry server #自己不能转自己
down #标记为down状态
resolve #当server定义的是主机名的时候,当A记录发生变化会自动应用新IP而不用重启Nginx
3.5.2 调度算法
3.5.2.1 轮询(Round Robin)
每个请求按时间顺序逐一分配到不同的后端服务,如果后端某台服务器死机,自动剔除故障系统,使用户访问不受影响。
3.5.2.2 轮询权值(Weighted Round Robin)
weight的值越大分配到的访问概率越高,主要用于后端每台服务器性能不均衡的情况下。或者仅仅为在主从的情况下设置不同的权值,达到合理有效的地利用主机资源。
指定轮询几率,weight和访问比率成正比,用于后端服务器性能不均的情况。
3.5.2.3 ip_hash (source hash)
每个请求按访问IP的哈希结果分配,使来自同一个IP的访客固定访问一台后端服务器,并且可以有效解决动态网页存在的session共享问题。
每个请求按访问ip的hash结果分配,这样每个访客固定访问一个后端服务器,可以解决session的问题。
3.5.2.4 fair(第三方)
比 weight、ip_hash更加智能的负载均衡算法,fair算法可以根据页面大小和加载时间长短智能地进行负载均衡,也就是根据后端服务器的响应时间 来分配请求,响应时间短的优先分配。
Nginx本身不支持fair,如果需要这种调度算法,则必须安装upstream_fair
模块。
按后端服务器的响应时间来分配请求,响应时间短的优先分配。
3.5.2.5 url_hash(第三方)
按访问的URL的哈希结果来分配请求,使每个URL定向到一台后端服务器,可以进一步提高后端缓存服务器的效率。
Nginx本身不支持url_hash,如果需要这种调度算法,则必须安装Nginx的hash软件包。
按访问url的hash结果来分配请求,使每个url定向到同一个后端服务器,后端服务器为缓存时比较有效。
3.5.2.6 least_conn(最小连接数)
根据后端服务器的连接状况进行分配客户请求,连接最少的服务器将被有限分配客户端请求。
3.5.2.7 最少响应时间(Least Time)
根据服务器的响应时间进行选择,将请求分配给响应时间最短的服务器。
4.PHP组件安装
(1)下载相关源
(2)配置文件
改写这一段成为下面这样
(3)启动php-fpm服务,重启Nginx
(4)编写测试php文件
(5)测试php解析,登录ip地址
5. Nginx配置跨域 CORS
5.1 跨域的定义
同源策略限制了从同一个源加载的文档或脚本如何与来自另一个源的资源进行交互。这是一个用于隔离潜在恶意文件的重要安全机制。通常不允许不同源间的读操作。
5.2 同源的定义
如果两个页面的协议,端口(如果有指定)和域名都相同,则两个页面具有相同的源。
与 URL http://britz.company.com/dir/1.html的源进行对比的示例:
-
http://britz.company.com/dir2/other.html同源
-
http://britz.company.com/secure.html不同源,协议不同
-
http://britz.company.com:81/dir/etc.html不同源,端口不同
-
http://yaso.company.com/dir/otehr.html不同源,主机不同
5.3 不同源的限制
-
Web 数据层面,同源策略限制了不同源的站点读取当前站点的 Cookie 、 IndexDB 、 LocalStorage 等数据;
-
DOM 层面,同源策略限制了来自不同源的 JavaScript 脚本对当前 DOM 对象读和写的操作;
-
网络层面,同源策略限制了通过 XMLHttpRequest 等方式将站点的数据发送给不同源的站点。
5.4 Nginx 解决跨域的原理
浏览器的同源策略限制了跨域请求,但当使用 Nginx 作为代理服务器时,浏览器发送的请求实际上是发送到与前端页面同源的 Nginx 服务器。然后 Nginx 将请求转发到真正的目标服务器,目标服务器返回的响应再通过 Nginx 返回给浏览器。从浏览器的角度看,它只与同源的 Nginx 服务器进行交互,从而绕过了 CORS 限制
6.Nginx防盗链设置
6.1 什么是盗链
-
在实际生产过程中,我们线上的图片等静态资源,经常会被其他网站盗用,他们发大财的同时,成本确实我们在买单,下面来说下,如何杜绝这种行为。
-
应该说只要是静态资源都是可以防盗链的,只需要在Server字段加上几行代码即可。众所周知网站出名了后,会有各种刁民来找茬的,最常见的就是爬你网站的东西。
-
关于防盗链这里不得不提一下网页的加载顺序是先加载HTML相关的内容,然后解析HTML的内容,那些需要加载图片,那些需要加载文件,是逐步加载的,所以可以在加载静态资源的时候做防盗链的操作,例如:在加载图片的时候直接跳转去其他链接,或者直接返回404,403等错误代码,拒绝它的请求。
如何区分哪些是不正常的用户?
-
HTTP Referer是Header的一部分,当浏览器向Web服务器发送请求的时候,一般会带上Referer,告诉服务器我是从哪个页面链接过来的,服务器借此可以获得一些信息用于处理,例如防止未经允许的网站盗链图片、文件等。因此HTTP Referer头信息是可以通过程序来伪装生成的,所以通过Referer信息防盗链并非100%可靠,但是,它能够限制大部分的盗链情况.
-
比如在www.google.com 里有一个 www.baidu.com 链接,那么点击这个www.baidu.com ,它的header 信息里就有:Referer=http://www.google.com
6.2 Referer解析
-
HTTP 协议中有一个用来表示“页面或资源”来源的“请求头”,这个请求头叫做 Referer --> Referer是表示请求是从哪个网址发出的防盗链功能基于HTTP协议支持的 Referer 机制,通过Referer跟踪来源,对来源进行识别和判断
6.3 配置防盗链案例
为了模拟盗链,让192.168.71.152为网站服务站点,192.168.71.149访问192.168.71.152进行盗链。
此时访问192.168.71.149会出现,此时点击站点即可显示152的图片(图片下架了)
152设置防盗链,如果不是代理151来访问都返回403,重启后点击站点显示403
六.nginx后端节点的健康检查
1.nginx原生模块介绍
我们在使用nginx做反向代理都会使用到以下两个模块:
1、ngx_http_proxy_module
定义允许将请求传递到另一台服务器。此模块下常用指令如下:
proxy_pass
proxy_cache
proxy_connect_timeout
proxy_read_timeout
proxy_send_timeout
proxy_next_upstream
2、ngx_http_upstream_module
用于定义可由proxy_pass,fastcgi_pass等指令引用的服务器组。此模块下常用指令如下:
upstream
server
ip_hash
在使用nginx上述的两个模块由以下缺点:
1.fail_time内的失败检测,超时时间以系统设置为主,效率低,等待超时影响性能;
2.后端一旦有问题,除后端禁用的fail_time时间段,其他时间nginx会把请求转发给不健康节点的,然后再转发给别的服务器,这样以来就浪费了一次转发。
因此除了上面介绍的nginx自带模块,还有一个更专业的模块,来专门提供负载均衡器内节点的健康检查的。这个就是淘宝技术团队开发的nginx模块。
2.nginx\_upstream\_check\_module模块
借助淘宝技术团队开发的nginx模快nginx_upstream_check_module来检测后方realserver的健康状态,如果后端服务器不可用,则会将其踢出upstream,所有的请求不转发到这台服务器。当期恢复正常时,将其加入upstream。
在淘宝自己的tengine上是自带了该模块的,大家可以访问淘宝Tengine官网来获取该版本的nginx,也可以到Gitbub
如果没有使用淘宝的tengine的话,可以通过补丁的方式来添加该模块到我们自己的nginx中。
下载地址1:https://github.com/yaoweibin/nginx_upstream_check_module
下载地址2:https://download.csdn.net/download/m0_60821938/89913605
3.使用阿里巴巴的tengine实现后端节点状态检查
1.安装tengine
2.修改配置文件
upstream webs {
server 192.168.71.149:80;
server 192.168.71.152:80;
check interval=5000 rise=1 fall=3 timeout=4000 type=http default_down=false;
check_http_send "HEAD /index.html HTTP/1.0\r\n\r\n";
check_http_expect_alive http_2xx http_3xx;
}
将上述加入这里,即可开始检查
七.总结
本次补充剩余nginx的内容,在代理,反向代理那里由于应该设置3台及以上主机,但是我错误的将服务器,代理服务器设置都设置在了149上,导致在做实验时非常的混乱,文件来回更改,这些内容太容易搞混了,在做实验时要注意各个主机间的配置文件。