学习Nginx这一篇就够了

  • 一、Nginx概述
    • 1. 什么是Nginx
    • 2.常见服务器
    • 3.什么是正向代理
  • 二、安装Nginx与运行
    • 1、去[nginx官网](http://nginx.org/) 下载对应 nginx,推荐使用稳定版本
    • 2、安装依赖环境
      • (1)安装 gcc 环境
      • (2)安装 pcre 库,用于解析正则表达式
      • (3)zlib 库和解压缩依赖
      • (4)SSL 安全的加密的套接字协议层,用于 HTTP 安全传输,也就是 https
      • (5)解压,需要注意,得到的是源码,源码需要编译后才能安装
      • (6)进入源码目录
      • (7)在 nginx目录,输入如下命令进行配置,目的是为了创建 makefile 文件
      • (8)make 编译
      • (9)进入 sbin 目录启动 nginx
      • (10)打开浏览器,访问虚拟机所处内网 ip 即可打开 nginx 默认页面,显示如下便表示安装成功
  • 三、Nginx 默认首页解析过程
    • 1.Nginx 进程模型解析
    • 2.Nginx 处理 Web 请求机制解析
      • worker 抢占机制
      • 传统服务器事件处理
    • Nginx 事件处理
    • 为什么能达到这么高并发
  • 四、nginx.conf 配置结构![在这里插入图片描述](https://img-blog.csdnimg.cn/24cfe45d55b647698a5a3b04f9852aa5.png)
  • 五、Nginx日志切割
      • 1.创建 cut_my_log.sh
      • 2.为 cut_my_log.sh 文件创建权限
      • 3.测试日志切割后的结果
    • Nginx 日志切割(定时)
      • 1、安装定时任务
      • 2、crontab -e 编辑并添加一行新的任务
      • 3、重启定时任务
      • 4、常用表达式
      • 1、安装定时任务
  • 六、Nginx 为静态资源提供服务
    • 1.Nginx 开启 gzip 压缩
    • 2.Nginx 中 location 匹配规则
    • 3.DNS解析域名
    • 4.Nginx 请求文件设置
    • 5.Nginx 的跨越
    • 6.Nginx 中配置静态资源防盗链
    • 7.root与alias
    • 8. Nginx 模块化设计
  • 七、Nginx 的集群负载均衡解析
      • 什么是单节点?
      • 什么是集群
      • Nginx集群负载均衡
      • Nginx搭建3台Tomcat集群
      • 负载均衡之轮训
    • 负载均衡之 upstream 指令参数
      • max_conns 请求最大连接数
      • slot_start 慢启动
      • down 服务器状态 表示为不可用
      • backup 备用机
      • max_fails 最大失败次数
      • fail_timeout 失败时间段
      • keepalived
      • ip_hash
        • hash 算法
      • hash 算法带来的问题
      • 一致性hash算法
      • url_hash
  • 八、Nginx 控制浏览器缓存
    • 浏览器缓存
    • Nginx缓存
    • 反向代理缓存
  • 九、使用Nginx配置SSL证书提供Https访问
    • 1.nginx中安装安装 SSL 模块
    • 2.配置 HTTPS
  • 十、动态分离的那些事儿
    • 动静分类的特点
    • 动态分离方式
    • 动态分离方式 Nginx
  • 十一、生产经验
    • Nginx 双机备份
    • 操作步骤
  • 十二、Nginx是如何做到流量限制的?
    • 1.Nginx如何限流
    • 2.配置基本的限流
    • 2.处理突发
    • 3.无延迟的排队
    • 4.高级配置示例
      • - 白名单
      • - location包含多limit_req指令
      • - 配置相关功能
      • - 发送到客户端的错误代码
      • - 指定location拒绝所有请求
  • 十三、Nginx 平滑升级
    • 一、使用 Nginx 实现平滑升级
      • 1.主进程支持的信号
      • 2.配置 Nginx 平滑升级

一、Nginx概述

1. 什么是Nginx

● Nginx是一个高性能的HTTP的反向代理web服务器,同时也提供IMAP/POP3/SMTP服务 -引用百度百科
● 主要功能是反向代理
● 通过配置文件实现集群和负载均衡
● 静态资源虚拟化

相关文章:
【LVS+KeepAlived+Nginx高可用实现方案】
【Nginx-学习nginx这一篇就够了】

2.常见服务器

MS IIS asp.net
Weblogic、Jboss 传统行业 ERP/物流/电信/金融
Tomcat、Jetty J2EE
Apache、Nginx 静态服务、反向代理
Netty 高性能服务器编程

3.什么是正向代理

客户端请求目标服务器之间的一个代理服务器
请求会先经过代理服务器,然后转发给到目标服务器,获取到内容后最后响应到客户端

二、安装Nginx与运行

1、去nginx官网 下载对应 nginx,推荐使用稳定版本

2、安装依赖环境

(1)安装 gcc 环境

yum install gcc-c++

(2)安装 pcre 库,用于解析正则表达式

yum install -y pcre pcre-devel

(3)zlib 库和解压缩依赖

yum install -y zlib zlib-devel

(4)SSL 安全的加密的套接字协议层,用于 HTTP 安全传输,也就是 https

yum install -y openssl openss-devel

(5)解压,需要注意,得到的是源码,源码需要编译后才能安装

mkdir /usr/local/nginx
tar -zxvf nginx-1.14.2.tar.gz -C /usr/local/nginx

(6)进入源码目录

cd /usr/local/nginx/nginx-1.14.2/

(7)在 nginx目录,输入如下命令进行配置,目的是为了创建 makefile 文件

./configure \
--prefix=/usr/local/nginx \
--pid-path=/var/run/nginx/nginx.pid \
--lock-path=/var/lock/nginx.lock \
--error-log-path=/var/log/nginx/error.log \
--http-log-path=/var/log/nginx/access.log \
--with-http_gzip_static_module \
--http-client-body-temp-path=/var/temp/nginx/client \
--http-proxy-temp-path=/var/temp/nginx/proxy \
--http-fastcgi-temp-path=/var/temp/nginx/fastcgi \
--http-uwsgi-temp-path=/var/temp/nginx/uwsgi \
--http-scgi-temp-path=/var/temp/nginx/scgi

也可以使用默认配置

./configure

注:\ 在命令中代表换行,用于提高可读性

配置命令

命令 释义
–prefix 指定nginx安装目录
–pid-path 指向nginx的pid
–lock-path 锁定安装文件,防止被恶意篡改或误操作
–error-log 错误日志
–http-log-path http日志
–with-http_gzip_static_module 启用gzip模块,在线实时压缩输出数据流
–http-client-body-temp-path 设定客户端请求的临时目录
–http-proxy-temp-path 设定http代理临时目录
–http-fastcgi-temp-path 设定fastcgi临时目录
–http-uwsgi-temp-path 设定uwsgi临时目录
–http-scgi-temp-path 设定scgi临时目录

(8)make 编译

make
make install

(9)进入 sbin 目录启动 nginx

./nginx

● 停止: ./nginx -s stop
● 重新加载: ./nginx -s -reload

(10)打开浏览器,访问虚拟机所处内网 ip 即可打开 nginx 默认页面,显示如下便表示安装成功


注意事项:

  1. 如果在云服务器安装,需要开启默认的 nginx 端口:80
  2. 如果在虚拟机安装,需要关闭防火墙
  3. 本地 win 或 mac 需要关闭防火墙

三、Nginx 默认首页解析过程

1.Nginx 进程模型解析

master 进程:主进程
worker 进程:工作进程
例子:管理者和员工
信号:

./nginx -s stop # 停止 nginx
./nginx -s quit # 退出 nginx
./nginx -s reload # 重新加载 nginx.conf 并启动
./nginx -t # 检查 nginx.conf 配置文件是否正确


每个进程相互独立,相互之间安全

2.Nginx 处理 Web 请求机制解析

worker 抢占机制

传统服务器事件处理

一个请求被阻塞后,就无法接收新的请求

Nginx 事件处理

一个 worker 被阻塞后,立马去处理另一个请求

为什么能达到这么高并发

  1. 抢占机制
  2. 模型 异步非阻塞 一个 worker 可以处理多个请求
  3. 多路复用器

四、nginx.conf 配置结构

nginx.conf

#user  nobody;
# 当 worker 进程执行时,他是又操作系统的每个用户区执行的,默认就是 nobody 使用 ps -ef | grep nginx 查看 nginx 进程
# 可以将 user 修改为 root 为 root 用户运行
worker_processes  1;
# worker 进程数量  cpu 有几个就设置几个,如果还有其他中间件在运行的话,可以设置为 n-1 8个cpu减一个,worker 设置为7个# ==========================================================================================
# error_log 错误日志
# 日志级别 debug[最低] info notice warn error crit[最严重]
# 在安装 nginx 时就制定了对应的日志文件夹
#error_log  logs/error.log;
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;#===========================================================================================# pid nginx 进程号,默认安装时就指定了
#pid        logs/nginx.pid;
pid /usr/local/nginx/logs/nginx.pid;# events 事件
events {# 默认使用 epolluse epoll;# 每个worker允许连接的客户端最大连接数,根据自身硬件进行配置worker_connections  1024;
}# 网络传输模块
http {# 导入外部文件,提高可读性 types 非常多include       mime.types;# 默认的 type 类型default_type  application/octet-stream;#设置body请求大小client_max_body_size 1024m; # 日志格式#log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '#                  '$status $body_bytes_sent "$http_referer" '#                  '"$http_user_agent" "$http_x_forwarded_for"';# 用户发起请求,都会记录在日志里头#access_log  logs/access.log  main;# 文件高效传输sendfile        on;# 数据包达到一定大小,在进行发送,#tcp_nopush     on;# 客户端链接服务器超时时间 默认0,这里设置的是65秒,防止占用链接过长,影响资源#keepalive_timeout  0;keepalive_timeout  65;# 压缩 html css 资源#gzip  on;# server 服务也可以通过配置文件进行导入# 服务server {# 监听端口号listen       80;# 服务器名称 127.0.0.1 或者域名server_name  localhost;# 编码#charset koi8-r;#access_log  logs/host.access.log  main;# 默认访问根目录location / {root   html;index  index.html index.htm;}# 错误页面#error_page  404              /404.html;# redirect server error pages to the static page /50x.html## 匹配相应规则,符合打开对应页面error_page   500 502 503 504  /50x.html;location = /50x.html {root   html;}}# 单独引入配置文件include imooc.conf;}

五、Nginx日志切割

现有的日志都会存在 access.log 文件中,但是随着时间的推移,这个文件的内容会越来越多,体积会越来越大,不便于运维人员查看,所以我们可以通过把
文件切割为多份不同的小文件作为日志,切割规则可以以 天 为单位,如果每天有几百G或者几个T的日志的话,则可以按需以 每半天 或者 每小时 对日志切割一

1.创建 cut_my_log.sh

#!/bin/bash
LOG_PATH="/var/log/nginx/"
RECORD_TIME=$(date -d "yesterday" +%Y-%m-%d+%H:%M)
PID=/var/run/nginx/nginx.pid
mv ${LOG_PATH}/access.log ${LOG_PATH}/access.${RECORD_TIME}.log
mv ${LOG_PATH}/error.log ${LOG_PATH}/error.${RECORD_TIME}.log
#向Nginx主进程发送信号,用于重新打开日志文件 kill -USR1 `cat $PID`

2.为 cut_my_log.sh 文件创建权限

chmod +x cut_my_log.sh

3.测试日志切割后的结果

./cut_my_log

对 access.log 进行切割,这里是切割到对应分钟,方便排查线上错误

[root@localhost nginx]# /usr/local/nginx/sbin/cut_my_log.sh
[root@localhost nginx]# ll
总用量 4
-rw-r--r--. 1 nobody root    0 3月   6 11:09 access.2022-03-05+11:10.log
-rw-r--r--. 1 nobody root 2660 3月   6 11:12 access.2022-03-05+11:13.log
-rw-r--r--. 1 nobody root    0 3月   6 11:13 access.log
-rw-r--r--. 1 nobody root    0 3月   6 11:09 error.2022-03-05+11:10.log
-rw-r--r--. 1 nobody root    0 3月   6 11:10 error.2022-03-05+11:13.log
-rw-r--r--. 1 nobody root    0 3月   6 11:13 error.log
[root@localhost nginx]#

Nginx 日志切割(定时)

使用定时任务

1、安装定时任务

yum install crontabs

2、crontab -e 编辑并添加一行新的任务

*/1 * * * * /usr/local/nginx/sbin/cut_my_log.sh

3、重启定时任务

service crond restart

附:常见定时任务命令

service crond start //启动服务
service crond stop //关闭服务
service crond restart //重启服务
service crond reload //重新载入配置
crontab -e // 编辑任务
crontab -l // 查看任务列表

定时任务表达式
Cron表达式是,分为5或6个域,每个域代表一个含义,如下所示:

星期几 年可选
取值范围 0-59 0-23 1-31 1-12 1-12 1-7

4、常用表达式

每分钟执行:

*/1 * * * *

每日凌晨(每天晚上23:59)执行:

59 23 * * *

每日凌晨1点执行:

0 1 * * *

1、安装定时任务

yum install crontabs

六、Nginx 为静态资源提供服务

1.Nginx 开启 gzip 压缩

    # 开启 gzip 压缩功能,目的,提高传输效率,节约带宽gzip  on;# 限制最小压缩,小于1字节文件不会压缩gzip_min_length 1;# 定义压缩的级别 压缩比 文件越大 压缩越多 但是cpu使用的会越多 1-9gzip_comp_level 3;# 定义压缩文件的类型gzip_types text/plain application/javascript application/x-javascript text/css application/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png  application/json;

2.Nginx 中 location 匹配规则

空格 :默认匹配,普通匹配

location / {root /home;
}

= :精确匹配

# 只能通过这个路径来访问
location = /imooc/img/face1.png {root /home;
}

~ :匹配正则表达式,不区分大小写*

location ~ \.(GIF|jpg|png|jpeg) {root /home;
}

~ :匹配正则表达式,区分大小写

# GIF 必须大写才能匹配到
location ~ \.(GIF|jpg|png|jpeg) {root /home;
}

^~ :以某个字符路径开头

# 当访问其他目录下就访问不到
location ^~ /imooc/img {root /home;
}

3.DNS解析域名


4.Nginx 请求文件设置

设置请求最大大小

http {include       mime.types;
default_type  application/octet-stream;
client_max_body_size 1024m; #设置body请求大小#log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
#                  '$status $body_bytes_sent "$http_referer" '
#                 '"$http_user_agent" "$http_x_forwarded_for" "$host" - $http_referer';#access_log  logs/access.log  main;

5.Nginx 的跨越

#允许跨域请求的域,*代表所有
add_header 'Access-Control-Allow-Origin' *;#允许带上cookie请求
add_header 'Access-Control-Allow-Credentials' 'true';#允许请求的方法,比如 GET/POST/PUT/DELETE
add_header 'Access-Control-Allow-Methods' *;#允许请求的header
add_header 'Access-Control-Allow-Headers' *;

6.Nginx 中配置静态资源防盗链

#对源站点验证 必须通过对应的域名来进行访问
valid_referers *.imooc.com;
#非法引入会进入下方判断
if ($invalid_referer) {return 404;
}

7.root与alias

假如服务器路径为:/home/imooc/files/img/face.png

  • root 路径完全匹配访问,配置为:
location /imooc) {root /home;
}

用户访问的时候请求为:url:port/imooc/files/img/face.png

  • alias 可以为你的路径做一个别名,对用户透明,配置为:
location /hello) {alias /home/imooc;
}

用户访问的时候请求为:url:port/hello/files/img/face.png,如此相当于为目录imooc做一个自定义的别名。

8. Nginx 模块化设计


七、Nginx 的集群负载均衡解析

什么是单节点?

缺点:只要一个人累了、或者说生病了,那么他就不能进行搬砖

什么是集群

Nginx集群负载均衡

请求转发给到上游服务器

单台Tomcat和两台Tomcat对比

Nginx搭建3台Tomcat集群

www.tomcats.com 接受到请求后,通过 proxy_pass 代理 tomcats 又 tomcats 来处理请求,如果z多个他会轮训的方式将请求分发到对应的服务器上

# 配置上游服务器
upstream tomcats {# 单独的一个服务用来部署Tomcatserver 192.168.128.129:8080;server 192.168.128.130:8080;server 192.168.128.131:8080;
}server {listen       94;server_name  www.tomcats.com;location / {proxy_pass http://tomcats;}}

负载均衡之轮训

例子:

权重:

upstream tomcats {# weight 默认权重是1,设置的越大,请求接收的就越多# 例如一共有3个请求,就会根据权重进行分类,两个给到129 一个给到130,权重需要根据服务器的性能进行判断,性能好,那么权重就可以设置的高server 192.168.128.129:8080 weight 2;server 192.168.128.130:8080 weight 1;
}

负载均衡之 upstream 指令参数

max_conns 请求最大连接数

官网文档:https://nginx.org/en/docs/http/ngx_http_upstream_module.html
limits the maximum number of simultaneous active connections to the proxied server (1.11.5). Default value is zero, meaning there is no limit. If the server group does not reside in the shared memory, the limitation works per each worker process.
限制与代理服务器 (1.11.5) 的同时活动连接的最大数量。 默认值为零,表示没有限制。 如果服务器组不驻留在共享内存中,则限制适用于每个工作进程。

限制每台server的连接数,用于保护避免过载,可起到限流作用。

# max_conns 最大连接数,请求执行完以后才能执行其他请求,未被处理到的请求返回502 例如 129 最大只能处理两个,超出的请求就会返回502
server 192.168.128.129:8080 weight=2 max_conns=2;

slot_start 慢启动

商业版本才有 设置多少秒后,才开始加入集群中

down 服务器状态 表示为不可用

用于标记服务节点不可用

backup 备用机

backup 表示当前服务器节点是备用机,只有在其他的服务器都宕机以后,自己才会加入到集群中,被用户访问到
注意:
backup 参数不能使用在 hash 和 random load balancing 中。

max_fails 最大失败次数

表示失败几次,则标记server已宕机,剔出上游服务。

fail_timeout 失败时间段

表示失败的重试时间

max_fails=2 fail_timeout=15s

代表在15秒内请求某一server失败达到2次后,则认为该server已经挂了或者宕机了,随后再过15秒,这15秒内不会有新的请求到达刚刚挂掉的节点上,而是会将请求给到其他运作的server,15秒后会再有新请求尝试连接挂掉的server,如果还是失败,重复上一过程,直到恢复。

keepalived

未设置之前

设置之后

keepalived : 设置长连接处理的数量
proxy_http_version :设置长连接http版本为1.1
proxy_set_header :清除connection header 信息

# 配置上游服务器
upstream tomcats {server 192.168.128.128:8080;keepalive 32;
}server {listen       94;server_name  www.tomcats.com;location / {proxy_pass http://tomcats;# 代理http版本设置为1.1proxy_http_version 1.1;# 连接报头字段应该被清除proxy_set_header Connection "";}}

ip_hash

ip_hash 可以保证用户访问可以请求到上游服务中的固定的服务器,前提是用户ip没有发生更改。
使用ip_hash的注意点:
不能把后台服务器直接移除,只能标记 down

hash 算法

取余算出应该访问那台服务器

hash 算法带来的问题

原本三台服务器正常请求

挂掉一台后,需要重新计算hash

一致性hash算法

hash计算出来后,只访问hash附近的服务器

例子:学区房 就近原则

upstream tomcats {ip_hash;server 192.168.1.173:8080;server 192.168.1.174:8080 down;server 192.168.1.175:8080;
}

url_hash

根据每次请求的url地址,hash后访问到固定的服务器节点

upstream tomcats { # url hash hash $request_uri; # 最少连接数 # least_conn server 192.168.1.173:8080; server 192.168.1.174:8080; server 192.168.1.175:8080;
}
server { listen 80; server_name www.tomcats.com; location / { proxy_pass http://tomcats; }
}

八、Nginx 控制浏览器缓存

浏览器缓存

加速用户访问,提升单个用户(浏览器访问者)体验,缓存在本地

Nginx缓存

● 缓存在nginx端,提升所有访问到nginx这一端的用户
● 提升访问上游(upstream)服务器的速度
● 用户访问仍然会产生请求流量
控制浏览器缓存:

location /files { alias /home/imooc; # expires 10s;  缓存10秒后过期# expires @22h30m; 缓存在10点30分过期 # expires -1h;  缓存一小时后过期# expires epoch;  不缺设置# expires off; 默认expires max; # 缓存永不过期
}

反向代理缓存

# proxy_cache_path 设置缓存保存的目录
# keys_zone 设置共享内存以及占用的空间大小
# max_size 设置缓存大小
# inactive 超过此时间 则缓存自动清理
# use_temp_path 关闭临时目录
proxy_cache_path /usr/local/nginx/upstream_cache keys_zone=mycache:5m max_size=1g inactive=30s use_temp_path=off;server {listen       94;server_name  www.tomcats.com;# 开启并使用缓存proxy_cache mycache;# 针对200和304状态码的缓存设置过期时间proxy_cache_valid 200 304 8h;location / {proxy_pass http://tomcats;}}

缓存目录

到达时间后自动删除

九、使用Nginx配置SSL证书提供Https访问

以http进行访问的网站,那么这个网站他是安全的

没有以https进行访问的网站,那么他是不安全的

前提域名需要自己单独去购买

小程序开发、安卓开发都是需要https

1.nginx中安装安装 SSL 模块

要在nginx中配置https,就必须安装ssl模块,也就是: http_ssl_module
● 进入到nginx的解压目录: /home/software/nginx-1.17.2
● 新增ssl模块(原来的那些模块需要保留)

./configure \
--prefix=/usr/local/nginx \
--pid-path=/var/run/nginx/nginx.pid \
--lock-path=/var/lock/nginx.lock \
--error-log-path=/var/log/nginx/error.log \
--http-log-path=/var/log/nginx/access.log \
--with-http_gzip_static_module \
--http-client-body-temp-path=/var/temp/nginx/client \
--http-proxy-temp-path=/var/temp/nginx/proxy \
--http-fastcgi-temp-path=/var/temp/nginx/fastcgi \
--http-uwsgi-temp-path=/var/temp/nginx/uwsgi \
--http-scgi-temp-path=/var/temp/nginx/scgi \
--with-http_ssl_module  # 新增了一个ssl模块,需要重新进行安装、编译编译、安装
make
make install

2.配置 HTTPS

● 把ssl证书 *.crt 和 私钥 *.key 拷贝到 /usr/local/nginx/conf 目录中
● 新增 server 监听 443 端口


server {listen       80;#listen  [::]:80;server_name xtdi.com.cn  www.xtdi.com.cn;return 301 https://$server_name$request_uri;
}server { listen 443; server_name www.imoocdsp.com; # 需要参考腾讯云、阿里云域名官方文档,改配置都是从文档拷贝过来# 开启ssl ssl on; # 配置ssl证书 ssl证书地址ssl_certificate 1_www.imoocdsp.com_bundle.crt; # 配置证书秘钥 ssl_certificate_key 2_www.imoocdsp.com.key; # ssl会话cache ssl_session_cache shared:SSL:1m; # ssl会话超时时间 ssl_session_timeout 5m; # 配置加密套件,写法遵循 openssl 标准 ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE; ssl_prefer_server_ciphers on;location / { proxy_pass http://tomcats/;}
}

配置后就可以通过 https 进行访问


十、动态分离的那些事儿

动态分离的那些事儿

动静分类的特点

● 分布式
● 前后端解耦
   ○ 前后端分开部署,发布快速便捷
● 静态归 nginx
● 接口服务化
   ○ 单独进行部署,安卓、小程序

静态数据
● css/html/images/audios
动态数据
● 得到的数据可能会和上一次不一样

动态分离方式

内容分发 CDN
根据用户地址,访问就近的服务器

例如:

动态分离方式 Nginx

使用ngxin存放静态资源

动静分离带来的问题

十一、生产经验

Nginx 双机备份

前提条件

  1. 当前服务【jar包】准备两份,一份作主服务,一份作为从服务,默认情况下请求都是访问主服务
  2. nginx中请求转发配置
 upstream pt_project-management_pool{server 172.18.101.77:9001 ;server 172.18.101.77:9002 backup;}// backup 作为备用机,如果9001服务挂掉,请求就会打到 9002 服务上,如果不标识 backup ,请求会随机打到两个中的一个// backup 表示当前服务器节点是备用机,只有在其他的服务器都宕机以后,自己才能被用户访问到

操作步骤

先将备份服务【9002】进行更新,然后重启【默认都是访问的主服务,备用服务是没人访问的】
调整nginx中配置,将 9002【备份服务】服务作为主服务,9001 设置为备用机,此时请求就会打到 9002 上

 upstream pt_project-management_pool{server 172.18.101.77:9001 backup; // 当前服务作为备用服务server 172.18.101.77:9002; // 请求到打到该服务上}

更新 9001【主服务】内容,然后重启
更改nginx中配置,将 9001 作为主服务,9002 作为备用服务,此时请求就会打到 9001 上

 upstream pt_project-management_pool{server 172.18.101.77:9001 ; // 请求打到当前服务上server 172.18.101.77:9002 backup; // 备份服务}

此过程中,用户都能调用接口,不会出现调用不了对应接口的情况

总结
切换nginx配置,先将请求打到从服务,更新主服务内容,主服务内容更新后,更改 nginx 配置转发到主服务,从服务作为备份

十二、Nginx是如何做到流量限制的?

流量限制(rate-limiting),是Nginx中一个非常实用,却经常被错误理解和错误配置的功能。我们可以用来限制用户在给定时间内HTTP请求的数量。请求,可以是一个简单网站首页的GET请求,也可以是登录表单的POST请求。

流量限制可以用作安全目的,比如可以减慢暴力密码破解的速率。通过将传入请求的速率限制为真实用户的典型值,并标识目标URL地址(通过日志),还可以用来抵御DDOS攻击。更常见的情况,该功能被用来保护上游应用服务器不被同时太多用户请求所压垮。

1.Nginx如何限流

Nginx的”流量限制”使用漏桶算法(leaky bucket algorithm),该算法在通讯和分组交换计算机网络中广泛使用,用以处理带宽有限时的突发情况。就好比,一个桶口在倒水,桶底在漏水的水桶。如果桶口倒水的速率大于桶底的漏水速率,桶里面的水将会溢出;

同样,在请求处理方面,水代表来自客户端的请求,水桶代表根据”先进先出调度算法”(FIFO)等待被处理的请求队列,桶底漏出的水代表离开缓冲区被服务器处理的请求,桶口溢出的水代表被丢弃和不被处理的请求。

2.配置基本的限流

“流量限制”配置两个主要的指令,limit_req_zone和limit_req,如下所示:

limit_req_zone $binary_remote_addr zone=mylimit:10m rate=10r/s;server {location /login/ {limit_req zone=mylimit;proxy_pass http://my_upstream;}
}

limit_req_zone指令定义了流量限制相关的参数,而limit_req指令在出现的上下文中启用流量限制(示例中,对于”/login/”的所有请求)。limit_req_zone指令通常在HTTP块中定义,使其可在多个上下文中使用,它需要以下三个参数:

Key - 定义应用限制的请求特性。示例中的Nginx变量remote_addr,占用更少的空间)
Zone - 定义用于存储每个IP地址状态以及被限制请求URL访问频率的共享内存区域。保存在内存共享区域的信息,意味着可以在Nginx的worker进程之间共享。定义分为两个部分:通过zone=keyword标识区域的名字,以及冒号后面跟区域大小。16000个IP地址的状态信息,大约需要1MB,所以示例中区域可以存储160000个IP地址。
Rate - 定义最大请求速率。在示例中,速率不能超过每秒10个请求。Nginx实际上以毫秒的粒度来跟踪请求,所以速率限制相当于每100毫秒1个请求。因为不允许”突发情况”(见下一章节),这意味着在前一个请求100毫秒内到达的请求将被拒绝。

当Nginx需要添加新条目时存储空间不足,将会删除旧条目。如果释放的空间仍不够容纳新记录,Nginx将会返回 503状态码(Service Temporarily Unavailable)。另外,为了防止内存被耗尽,Nginx每次创建新条目时,最多删除两条60秒内未使用的条目。

limit_req_zone指令设置流量限制和共享内存区域的参数,但实际上并不限制请求速率。所以需要通过添加limit_req指令,将流量限制应用在特定的location或者server块。在上面示例中,我们对/login/请求进行流量限制。

现在每个IP地址被限制为每秒只能请求10次/login/,更准确地说,在前一个请求的100毫秒内不能请求该URL。

2.处理突发

如果我们在100毫秒内接收到2个请求,怎么办?对于第二个请求,Nginx将给客户端返回状态码503。这可能并不是我们想要的结果,因为应用本质上趋向于突发性。相反地,我们希望缓冲任何超额的请求,然后及时地处理它们。我们更新下配置,在limit_req中使用burst参数:

location /login/ {limit_req zone=mylimit burst=20;proxy_pass http://my_upstream;
}

burst参数定义了超出zone指定速率的情况下(示例中的mylimit区域,速率限制在每秒10个请求,或每100毫秒一个请求),客户端还能发起多少请求。上一个请求100毫秒内到达的请求将会被放入队列,我们将队列大小设置为20。

这意味着,如果从一个给定IP地址发送21个请求,Nginx会立即将第一个请求发送到上游服务器群,然后将余下20个请求放在队列中。然后每100毫秒转发一个排队的请求,只有当传入请求使队列中排队的请求数超过20时,Nginx才会向客户端返回503。

3.无延迟的排队

配置burst参数将会使通讯更流畅,但是可能会不太实用,因为该配置会使站点看起来很慢。在上面的示例中,队列中的第20个包需要等待2秒才能被转发,此时返回给客户端的响应可能不再有用。要解决这个情况,可以在burst参数后添加nodelay参数:

location /login/ {limit_req zone=mylimit burst=20 nodelay;proxy_pass http://my_upstream;
}

使用nodelay参数,Nginx仍将根据burst参数分配队列中的位置,并应用已配置的速率限制,而不是清理队列中等待转发的请求。相反地,当一个请求到达“太早”时,只要在队列中能分配位置,Nginx将立即转发这个请求。将队列中的该位置标记为”taken”(占据),并且不会被释放以供另一个请求使用,直到一段时间后才会被释放(在这个示例中是,100毫秒后)。

假设如前所述,队列中有20个空位,从给定的IP地址发出的21个请求同时到达。Nginx会立即转发这个21个请求,并且标记队列中占据的20个位置,然后每100毫秒释放一个位置。如果是25个请求同时到达,Nginx将会立即转发其中的21个请求,标记队列中占据的20个位置,并且返回503状态码来拒绝剩下的4个请求。

现在假设,第一组请求被转发后101毫秒,另20个请求同时到达。队列中只会有一个位置被释放,所以Nginx转发一个请求并返回503状态码来拒绝其他19个请求。如果在20个新请求到达之前已经过去了501毫秒,5个位置被释放,所以Nginx立即转发5个请求并拒绝另外15个。

效果相当于每秒10个请求的“流量限制”。如果希望不限制两个请求间允许间隔的情况下实施“流量限制”,nodelay参数是很实用的。

注意:对于大部分部署,我们建议使用burst和nodelay参数来配置limit_req指令。

4.高级配置示例

通过将基本的“流量限制”与其他Nginx功能配合使用,我们可以实现更细粒度的流量限制。

- 白名单

下面这个例子将展示,如何对任何不在白名单内的请求强制执行“流量限制”:

geo $limit {default         1;10.0.0.0/8         0;192.168.0.0/64     0;
}map $limit $limit_key {0 "";1 $binary_remote_addr;
}limit_req_zone $limit_key zone=req_zone:10m rate=5r/s;server {location / {limit_req zone=req_zone burst=10 nodelay;# ...}
}

这个例子同时使用了geo和map指令。geo块将给在白名单中的IP地址对应的$limit变量分配一个值0,给其它不在白名单中的分配一个值1。然后我们使用一个映射将这些值转为key,如下:

如果变量的值是,limit_key变量将被赋值为空字符串
如果变量的值是,limit_key变量将被赋值为客户端二进制形式的IP地址 两个指令配合使用,白名单内IP地址的$limit_key变量被赋值为空字符串,不在白名单内的被赋值为客户端的IP地址。当limit_req_zone后的第一个参数是空字符串时,不会应用“流量限制”,所以白名单内的IP地址(10.0.0.0/8和192.168.0.0/24 网段内)不会被限制。其它所有IP地址都会被限制到每秒5个请求。
limit_req指令将限制应用到/的location块,允许在配置的限制上最多超过10个数据包的突发,并且不会延迟转发。

- location包含多limit_req指令

我们可以在一个location块中配置多个limit_req指令。符合给定请求的所有限制都被应用时,意味着将采用最严格的那个限制。例如,多个指令都制定了延迟,将采用最长的那个延迟。同样,请求受部分指令影响被拒绝,即使其他指令允许通过也无济于事。

扩展前面将“流量限制”应用到白名单内IP地址的例子:

http {# ...limit_req_zone $limit_key zone=req_zone:10m rate=5r/s;limit_req_zone $binary_remote_addr zone=req_zone_wl:10m rate=15r/s;server {# ...location / {limit_req zone=req_zone burst=10 nodelay;limit_req zone=req_zone_wl burst=20 nodelay;# ...}}
}

白名单内的IP地址不会匹配到第一个“流量限制”,而是会匹配到第二个req_zone_wl,并且被限制到每秒15个请求。不在白名单内的IP地址两个限制能匹配到,所以应用限制更强的那个:每秒5个请求。

- 配置相关功能

日志记录 默认情况下,Nginx会在日志中记录由于流量限制而延迟或丢弃的请求,如下所示:

2015/06/13 04:20:00 [error] 120315#0: *32086 limiting requests, excess: 1.000 by zone "mylimit", client: 192.168.1.2, server: nginx.com, <br>request: "GET / HTTP/1.0", host: "nginx.com"

日志条目中包含的字段:

  • limiting requests - 表明日志条目记录的是被“流量限制”请求
  • excess - 每毫秒超过对应“流量限制”配置的请求数量
  • zone - 定义实施“流量限制”的区域
  • client - 发起请求的客户端IP地址
  • server - 服务器IP地址或主机名
  • request - 客户端发起的实际HTTP请求
  • host - HTTP报头中host的值
    默认情况下,Nginx以error级别来记录被拒绝的请求,如上面示例中的[error]所示(Ngin以较低级别记录延时请求,一般是info级别)。如要更改Nginx的日志记录级别,需要使用limit_req_log_level指令。这里,我们将被拒绝请求的日志记录级别设置为warn:
location /login/ {limit_req zone=mylimit burst=20 nodelay;limit_req_log_level warn;proxy_pass http://my_upstream;
}

- 发送到客户端的错误代码

一般情况下,客户端超过配置的流量限制时,Nginx响应状态码为503(Service Temporarily Unavailable)。可以使用limit_req_status指令来设置为其它状态码(例如下面的444状态码):

location /login/ {limit_req zone=mylimit burst=20 nodelay;limit_req_status 444;
}

- 指定location拒绝所有请求

如果你想拒绝某个指定URL地址的所有请求,而不是仅仅对其限速,只需要在location块中配置deny all指令:

location /foo.php {deny all;
}

总结
前文已经涵盖了Nginx和Nginx Plus提供的“流量限制”的很多功能,包括为HTTP请求的不同loation设置请求速率,给“流量限制”配置burst和nodelay参数。还涵盖了针对客户端IP地址的白名单和黑名单应用不同“流量限制”的高级配置,阐述了如何去日志记录被拒绝和延时的请求。

十三、Nginx 平滑升级

一、使用 Nginx 实现平滑升级

实现原理:

  1. 在旧进程运行时,启动新的进程;
  2. 旧进程处理没有完成的请求,但不再接收新的处理请求,而是由新进程负责接收请求并进行处理;
  3. 最后通过关闭旧进程的 PID,使新的进程完全兼容。

1.主进程支持的信号

信号 作用
TERM INT 立即退出
QUIT 等工作进程结束后再退出
KILL 强制终止进程
HUP 重新加载配置文件,使用新的配置启动工作进程,并逐步关闭旧进程
USR1 重新打开日志文件
USR2 启动新的主进程,实现热升级 (后面会用到!)
WINCH 逐步关闭工作进程及工作进程支持的信息

2.配置 Nginx 平滑升级

  1. 准备软件包并查看旧版安装选项,根据自己的需求设置版本号

    wget http://nginx.org/download/nginx-1.21.6.tar.gz
    #解压到/usr/local/
    tar zxf nginx-1.21.6.tar.gz -C /usr/local/
    
  2. 安装新版本(需要注意新版本是否需要安装依赖包)

    cd /usr/local/nginx-1.21.6/
    # 注意编译这里,要和自己之前的版本一致,我这里取默认配置
    ./configure
    #make 之后不要 make install 不然会覆盖之前的文件
    make
    
  3. 备份原来的二进制文件

    mv /usr/local/nginx/sbin/nginx /usr/local/nginx/sbin/nginx-$(date +%F)
    cp objs/nginx /usr/local/nginx/sbin/
    /usr/local/nginx/sbin/nginx -t
    #查看版本信息
    /usr/local/nginx/sbin/nginx -V
    

  4. 使用信号实现热升级

    ps aux | grep nginx | grep -v grep
    kill -USR2 Nginx主进程 (master)
    
  • 向主进程发送 USR2 信号,Nginx 会启动一个新版本的 Master 进程和工作进程,和旧版本一起处理请求。

  • 关闭nginx旧进程

    kill -WINCH $(cat /usr/local/nginx/logs/nginx.pid.oldbin)           # 关闭老版本的 Worker 进程
    kill -QUIT $(cat /usr/local/nginx/logs/nginx.pid.oldbin)            # 关闭老版本的 Master 进程
    ps aux | grep nginx | grep -v grep
    /usr/local/nginx/sbin/nginx -V
    

以上就是整个热升级的过程,实际回退也是此原理,重复以上操作即可~

Nginx-学习nginx这一篇就够了、版本平滑升级相关推荐

  1. Nginx学习---Nginx的详解_【all】

    1.1. Nginx简介 1.什么是nginx nginx:静态的,开源的www软件,可以解析静态的小文件(低于1M ),支持高并发占用较发少的资源(3W并发,10个进程,内存150M),跨平台 te ...

  2. 学习javascript这一篇就够了超详细笔记(建议收藏)上

    学习javascript这一篇就够了超详细笔记(建议收藏)上 1.初识 计算机基础导读 编程语言 计算机基础 初识js 浏览器执行 js组成 js初体验-三种书写位置 js注释 js输入输出语句 2. ...

  3. 学习MyBatis3这一篇就够了

    目录 第一章 MyBatis3概述 1.1.概述 1.2.特点 1.3.对比 1.4.官网 1.5.下载 第二章 MyBatis3的增删改查 2.1.环境准备 2.2.创建工程 2.3.导入依赖 2. ...

  4. 强化学习入门这一篇就够了!!!万字长文

    强化学习 强化学习入门这一篇就够了万字长文带你明明白白学习强化学习... 强化学习入门这一篇就够了 强化学习 前言 一.概率统计知识回顾 1.1 随机变量和观测值 1.2 概率密度函数 1.3 期望 ...

  5. caffe-源码学习——只看一篇就够了

    caffe-源码学习--只看一篇就够了 网络模型 说caffe代码难懂,其实关键点在于caffe中有很多基础的数学运算代码,如果能够对掌握这些数学运算,剩下的就是推公式了. 激活函数 sigmoid ...

  6. nginx版本平滑升级(超详细)

    一.前期准备 二.开始实验 安装旧版本 安装新版本 三.可能遇到的问题 文章背景:护网期间,客户跟我说nginx有0day漏洞,需要版本升级,我寻思着我也不是运维啊,问我干嘛(你干嘛~ 哎呦~),我没 ...

  7. nginx学习之详细安装篇(二)

    1. 选择稳定版还是主线版 主线版:包含最新的功能和bug修复,但该版本可能会含有一些属于实验性的模块,同时可能会有新的bug,所以如果只是做测试使用,可以使用主线版. 稳定版:不包含最新的功能,但修 ...

  8. Nginx学习日记第五篇 -- upstream及fastcgi

    一.Nginx upstream Ngx_http_upstream_module模块可实现七层负载均衡,定义的服务器组可被proxy_pass.fastcgi_pass.uwsgi_pass.scg ...

  9. 干货!学习 Python 看这篇管够!!!

    文 | 潮汐 来源:Python 技术「ID: pythonall」 写在前面 各位朋友们大家好,时间飞逝,转眼咱们公众号运营 2 年了,这两年感谢各位忠实粉丝的陪伴,让我们能更有动力继续前行,也希望 ...

最新文章

  1. 信息化道路上,这两家龙头企业做了什么
  2. Windows和Linux下apache-artemis-2.10.0安装配置
  3. MinGW与MSVC编译的区别
  4. 【程序设计】浅析编程语言的区间为何常是左闭右开
  5. rust采南瓜按什么_怎样进行南瓜的采后处理?
  6. 项目管理:名词解释、区别联系、案例分析
  7. smtp是什么邮件的协议
  8. 电脑连无线无法访问云服务器,小编教你如何解决电脑无法连接无线网络
  9. sap 查询数据 未分离版本
  10. eclipse neon配置 maven
  11. 全局热键给截图自动加水印并win10系统通知
  12. tableau和oracle dv,比较Power BI和Tableau,好比用奔驰对比奥迪
  13. LoveChat独立部署即时通讯IM(前台后台不开源)聊天APP
  14. 3加3减!让商家好好做生意,阿里绝对是认真的!
  15. 【聚类之DBSCAN】DBSCAN实例
  16. python操作键盘输入中文_python模拟鼠标点击和键盘输入的操作
  17. 股票数据爬虫(Scrapy框架与requests-bs4-re技术路线)
  18. 打造高效敏捷的研发独立团 (2009年培训心得)
  19. 真香定律!阿里、字节跳动、京东、腾讯、小米等名企高频面试,终于搞明白了
  20. Android改变图像的饱和度 亮度和对比度

热门文章

  1. 等保-机房来访人员进出登记表
  2. 学PE文件结构之记笔记
  3. GIS从二维到三维有多远
  4. ETH研究新型透明材料涂层 防止镜片起雾的防雾涂料
  5. python爬取王者_Python爬取王者荣耀所有英雄以及高清大图
  6. 2021年通辽市高考成绩查询,2021年通辽高考状元名单公布,通辽文理科状元是谁多少分...
  7. 仿照某商城首页的源代码及效果
  8. STM32F10X CAN+TJA1050中断 接受例程详解,测试无误
  9. 园林宣传片文案撰写方法
  10. ThreadLocal源码解读 侵立删