# Linux运维Day03:Nginx 反向代理(服务集群)、负载均衡、四层调度与优化

一、环境准备

1.1 虚拟机规划

  • 使用 template 模板机准备 3 台虚拟机
  • proxy 服务器 配置双网卡:
    • ens160:连接服务端,网段 192.168.8.0/24
    • ens192:连接客户端,网段 192.168.4.0/24

1.2 proxy 网卡配置

(1)添加第二块网卡(VMware 操作)
  1. 编辑虚拟机设置 → 添加 → 网络适配器 → 完成
  2. 网络连接选择 自定义(VMnet1,仅主机模式) → 确定
(2)配置 ens160(192.168.8.50/24)
bash 复制代码
[root@proxy ~]# nmcli connection modify ens160 ipv4.method manual ipv4.addresses 192.168.8.50/24 connection.autoconnect yes
[root@proxy ~]# nmcli connection up ens160
(3)配置 ens192(192.168.4.50/24)
bash 复制代码
# 查看网卡连接
[root@proxy ~]# nmcli connection show
NAME    UUID                                  TYPE      DEVICE 
???? 1  77d90f32-9878-4213-b54a-6f05a91fddd7  ethernet  ens192 
ens160  8f2b6d31-d69c-4812-9277-2ac35e534ca2  ethernet  ens160 

# 删除中文自动识别连接
[root@proxy ~]# nmcli connection delete 77d90f32-9878-4213-b54a-6f05a91fddd7

# 重新添加网卡连接
[root@proxy ~]# nmcli connection add ifname ens192 con-name ens192 type ethernet

# 配置IP
[root@proxy ~]# nmcli connection modify ens192 ipv4.method manual ipv4.addresses 192.168.4.50/24 connection.autoconnect yes

# 激活网卡
[root@proxy ~]# nmcli connection up ens192

1.3 Windows 端配置 VMnet1

  • 配置 VMnet1 虚拟网卡:192.168.4.1/24
  • 测试连通性:
powershell 复制代码
C:\Users\15790>ping 192.168.8.50
C:\Users\15790>ping 192.168.4.50

二、Nginx 反向代理

反向代理:客户端在公网,服务器在内网。代理服务端,隐藏服务器

正向代理:客户端在内网,服务器在公网。代理客户端,隐藏访问者

2.1 基础概念

  • 单点故障:架构中某节点故障导致全网瘫痪
  • 负载均衡 :多个(至少两个,没有上限)主机组建集群,提供同样的服务,缓解单个服务器的压力,提升架构的可靠性
  • 反向代理概述
    • 用户访问Nginx代理服务器,代理服务器把请求转发给后端真实服务器
    • 实现负载均衡,提升架构的可靠性
    • 提高安全性,保护内网服务器安全

Nginx 反向代理就是公网与内网之间的网络中转站 公网用户仅能访问 Nginx 的公网 IP / 域名,无法直接接触内网服务器。

Nginx 在外网接收用户请求,转发至内网业务服务;内网服务只对接 Nginx,绝不直接暴露公网。 业务处理完成后,响应数据再经由

Nginx 中转,原路返回给公网用户。

HTTP反向代理架构-实验拓扑图:

4网段类比为公网,8网段类比为内网。
工作原理:(必须理解)

对于公网的客户端来说,nginx代理就是服务端

对于nginx代理来说,内网服务器才是服务端

客户端请求到达代理,代理服务器会拆开数据包,然后再封装一个数据包发送给真正的服务器。服务器回应时,发送到代理,代理会再次拆开数据包,重新封装之后再发送给对应的客户端

(工作原理的核心就是代理的拆包和再封装的操作)

如果4.1想访问8.100,那么: 客户端全程只和 192.168.4.50 通信,完全不知道 192.168.8.100 的存在。

Nginx 在这里做了两次 "身份转换":

对客户端:自己是服务端,源 IP 是 192.168.4.50

对后端:自己是客户端,源 IP是 192.168.8.50

2.2 核心语法格式

nginx 复制代码
http {
  upstream   backend  {              #创建集群(集群名称见名知意即可)
  server   192.168.8.100:80;         #指定集群成员
  server   192.168.8.200:80;         #指定集群成员
  }
server  {                            #虚拟web主机
  listen   80;
  server_name   localhost;           #域名
  location  /  {
  ...
  proxy_pass   http://backend;       #将请求调度至 web集群(与上方集群名称一致)
  }
}
...此处省略1万字...
}

2.3 Nginx 代理算法

  • Nginx目前支持的算法
    • 轮询(默认,常用):逐一循环调度
    • weight:指定权重,权重值和访问率成正比
    • ip_hash(常用) :又叫源地址哈希,根据客户端地址分配固定的 后端服务器,解决会话保持问题
    • least_conn(最小连接数,目前仅了解):把请求分配给当前活跃连接数最少的后端服务器,适合请求耗时差异大的场景,避免某台服务器被长连接占满

2.4 集群主机状态关键字

  • max_fails:允许请求失败次数(默认1),失败达次数后暂停调度
  • fail_timeout:触发 max_fails 后,暂停调度的时间(单位:秒)
  • down:标记主机暂不参与负载均衡

2.5 实验部署(web1、web2、proxy)

  • 根据拓扑图完成下方实验
2.5.1 部署 web1(192.168.8.100)
  • web1主机均需要安装nginx服务
  • Nginx源码编译安装,将nginx-1.22.1.tar.gz上传至虚拟机web1的/root目录
bash 复制代码
[root@web1 ~]# dnf -y install gcc pcre-devel openssl-devel make  #安装依赖包
[root@web1 ~]# useradd nginx                              #创建用于用于启动服务
[root@web1 ~]# tar -xf   /root/nginx-1.22.1.tar.gz        #解压源码包
[root@web1 ~]# cd nginx-1.22.1                            #切换目录
[root@web1 nginx-1.22.1]# 
[root@web1 nginx-1.22.1]# ./configure \                   #初始化
> --prefix=/usr/local/nginx \      #指定安装目录为/usr/local/nginx
> --user=nginx \          #指定用户名(运行服务后进程的所有者)
> --group=nginx \         #指定组(运行服务后进程的组)
> --with-http_ssl_module  #支持加密功能
[root@web1 nginx-1.22.1]# make && make install      #编译 并 编译安装
[root@web1 nginx-1.22.1]# ls    /usr/local/nginx    #查看安装目录,有数据表示已安装
  • web1主机编写测试页面,内容为:web1web1
  • 启动服务,查看端口
bash 复制代码
[root@web1 ~]# echo   "web1web1"   >  /usr/local/nginx/html/index.html  #修改首页文件
[root@web1 ~]# /usr/local/nginx/sbin/nginx                #启动nginx服务
[root@web1 ~]# ss -nutlp  |  grep  :80                    #查看端口
[root@web1 ~]# curl   127.0.0.1                           #自己访问自己测试,可以看到页面
2.5.2 部署 web2(192.168.8.200)
  • web2主机均需要安装nginx服务
  • Nginx源码编译安装,将nginx-1.22.1.tar.gz上传至虚拟机web2的/root目录
bash 复制代码
[root@web2 ~]# dnf -y install gcc pcre-devel openssl-devel make  #安装依赖包
[root@web2 ~]# useradd nginx                              #创建用于用于启动服务
[root@web2 ~]# tar -xf   /root/nginx-1.22.1.tar.gz        #解压源码包
[root@web2 ~]# cd nginx-1.22.1                            #切换目录
[root@web2 nginx-1.22.1]# 
[root@web2 nginx-1.22.1]# ./configure \                   #初始化
> --prefix=/usr/local/nginx \      #指定安装目录为/usr/local/nginx
> --user=nginx \          #指定用户名(运行服务后进程的所有者)
> --group=nginx \         #指定组(运行服务后进程的组)
> --with-http_ssl_module  #支持加密功能
[root@web2 nginx-1.22.1]# make && make install      #编译 并 编译安装
[root@web2 nginx-1.22.1]# ls    /usr/local/nginx    #查看安装目录,有数据表示已安装
  • web1主机编写测试页面,内容为:web1web1
  • 启动服务,查看端口
bash 复制代码
[root@web2 ~]# echo   "web2web2"   >  /usr/local/nginx/html/index.html  #修改首页文件
[root@web2 ~]# /usr/local/nginx/sbin/nginx                #启动nginx服务
[root@web2 ~]# ss -nutlp  |  grep  :80                    #查看端口
[root@web2 ~]# curl   127.0.0.1                           #自己访问自己测试,可以看到页面

实际工作中,两个主机提供的页面应该是相同的,今天仅仅是为了做实验体验Nginx的反向代理,因此做两个不一样的页面

2.5.3 部署 proxy(192.168.4.50)
  • proxy主机安装部署nginx服务,proxy主机本身不做网站
  • 所以初始化时--with-http_ssl_module不是必须
  • Nginx源码编译安装,将nginx-1.22.1.tar.gz上传至虚拟机proxy的/root目录
bash 复制代码
[root@proxy ~]# dnf -y install gcc pcre-devel openssl-devel make  #安装依赖包
[root@proxy ~]# useradd nginx                        #创建用于用于启动服务
[root@proxy ~]# tar -xf   /root/nginx-1.22.1.tar.gz  #解压源码包
[root@proxy ~]# cd nginx-1.22.1                      #切换目录
[root@proxy nginx-1.22.1]# ./configure \      #初始化
> --prefix=/usr/local/nginx \                #指定安装目录为/usr/local/nginx
> --user=nginx \                             #指定用户名(运行服务后进程的所有者)
> --group=nginx \                            #指定组(运行服务后进程的组)
> --with-http_ssl_module                     #支持加密功能
[root@proxy nginx-1.22.1]# make && make install      #编译 并 编译安装
[root@proxy nginx-1.22.1]# ls    /usr/local/nginx    #查看安装目录,有数据表示已安装
  • proxy代理服务器修改nginx配置文件
    • 创建backend集群,集群成员为:web1、web2
    • 调用集群,将请求调度至backend集群
bash 复制代码
[root@proxy ~]# cp  /usr/local/nginx/conf/nginx.conf   /opt  #备份配置文件
[root@proxy ~]# vim  /usr/local/nginx/conf/nginx.conf         #修改配置文件
...此处省略1万字...
  upstream   backend  {              #创建集群backend(集群名称见名知意即可)
  server   192.168.8.100:80;         #指定集群成员
  server   192.168.8.200:80;         #指定集群成员
  #默认采用轮询算法,第一次走第一个的话,第二次一定是第二个,轮着来
  }
server  {                            #虚拟web主机
  listen   80;
  server_name   localhost;           #域名
  location  /  {
  ...
  proxy_pass   http://backend/;      #将请求调度至 web集群(与上方集群名称一致)
  }
}
...此处省略1万字...
}
[root@proxy ~]# /usr/local/nginx/sbin/nginx  #启动服务
[root@proxy ~]# ss -nutlp | grep :80         #查看端口号

如果是加密的https,那么要修改端口号:

  • upstream backend { #创建集群backend(集群名称见名知意即可) server 192.168.8.100:443; #指定集群成员 server 192.168.8.200:443; #指定集群成员 }
    • listen 443;
    • proxy_pass https://backend;
2.5.4 客户端验证(轮询效果)

什么是轮询? 轮询就是负载均衡里最基础的分发策略,指按顺序轮流把请求分配给后端服务器,按顺序 "点名",挨个处理请求,实现平均分配。

  • client客户端访问验证
  • Windows客户端访问验证,如未及时更新,则强制刷新,防止缓存
bash 复制代码
[root@client ~]# curl 192.168.4.50  #访问代理服务器,轮询访问,实现负载均衡
web1web1
[root@client ~]# curl 192.168.4.50  #访问代理服务器,轮询访问,实现负载均衡
web2web2

2.6 集群状态关键字验证

  • max_fails:允许请求失败的次数(默认为1),即失败几次不再调度
  • fail_timeout:达到max_fails的次数之后,暂停调度的时间,单位秒
  • down:表示指定的集群成员主机暂不参与负载
  • proxy主机修改配置文件,验证关键字,修改完记得重新加载nginx配置
max_fails + fail_timeout
nginx 复制代码
[root@proxy ~]# vim  /usr/local/nginx/conf/nginx.conf         #修改配置文件
...此处省略1万字...
  upstream   backend  {              #创建集群(集群名称见名知意即可)
  server   192.168.8.100:80 max_fail=2 fail_timeout=30;         #失败2次算失败,失败后30秒内不再访问
  server   192.168.8.200:80;         #指定集群成员
  }
server  {                            #虚拟web主机
  listen   80;
  server_name   localhost;           #域名
  location  /  {
  ...
  proxy_pass   http://backend;      #将请求调度至 web集群(与上方集群名称一致)
  }
}
...此处省略1万字...
}
[root@proxy ~]# /usr/local/nginx/sbin/nginx -s reload  #重新加载配置
[root@proxy ~]# ss -nutlp | grep :80         #查看端口号
  • web1停止nginx服务,模拟服务宕机
bash 复制代码
[root@web1 ~]# /usr/local/nginx/sbin/nginx -s stop    #停止nginx服务 
  • web1启动nginx服务,恢复服务
bash 复制代码
[root@client ~]# curl 192.168.4.50  #由于web1主机的nginx服务宕机,所以一直访问都是由web2提供
web2web2
[root@client ~]# curl 192.168.4.50  #由于web1主机的nginx服务宕机,所以一直访问都是由web2提供
web2web2
[root@client ~]# curl 192.168.4.50  #30秒后,两个主机开始再次轮询
web1web1
down关键字
bash 复制代码
[root@proxy ~]# vim  /usr/local/nginx/conf/nginx.conf         #修改配置文件
...此处省略1万字...
  upstream   backend  {              #创建集群(集群名称见名知意即可)
  server   192.168.8.100:80 max_fail=2 fail_timeout=30;         #失败2次算失败,失败后30秒内不再访问
  server   192.168.8.200:80 down;         #使用down关键字标记此主机暂不参与调度
  }
server  {                            #虚拟web主机
  listen   80;
  server_name   localhost;           #域名
  location  /  {
  ...
  proxy_pass   http://backend;      #将请求调度至 web集群(与上方集群名称一致)
  }
}
...此处省略1万字...
}
[root@proxy ~]# /usr/local/nginx/sbin/nginx -s reload  #重新加载配置
[root@proxy ~]# ss -nutlp | grep :80         #查看端口号
  • 客户端访问测试
bash 复制代码
[root@client ~]# curl 192.168.4.50  #由于web2主机的不参与调度,所以一直访问都是由web1提供
web1web1
[root@client ~]# curl 192.168.4.50  #由于web2主机的不参与调度,所以一直访问都是由web1提供
web1web1

2.7 Nginx算法验证(weight,ip_hash)

(1)权重算法(weight)
  • weight:指定权重,权重值和访问率成正比
  • 增加权重,实现真正的负载均衡
nginx 复制代码
[root@proxy ~]# vim  /usr/local/nginx/conf/nginx.conf         #修改配置文件
...此处省略1万字...
  upstream   backend  {              #创建集群(集群名称见名知意即可)
  server   192.168.8.100:80 weight=2;         #权重设置为2
  server   192.168.8.200:80 weight=1;         #权重设置为1
  }
server  {                            #虚拟web主机
  listen   80;
  server_name   localhost;           #域名
  location  /  {
  ...
  proxy_pass   http://backend;      #将请求调度至 web集群(与上方集群名称一致)
  }
}
...此处省略1万字...
}
[root@proxy ~]# /usr/local/nginx/sbin/nginx -s reload  #重新加载配置
[root@proxy ~]# ss -nutlp | grep :80         #查看端口号
  • 客户端访问验证,此刻是有权重的轮询,web1与web2处理结果2:1
bash 复制代码
[root@client ~]# curl 192.168.4.50  
web1web1
[root@client ~]# curl 192.168.4.50  
web1web1
[root@client ~]# curl 192.168.4.50  
web2web2
(2)源地址哈希(ip_hash)
  • ip_hash :又叫源地址哈希,根据客户端地址分配固定的 后端服务器
    没写ip_hash,默认以轮询的算法
nginx 复制代码
[root@proxy ~]# vim  /usr/local/nginx/conf/nginx.conf         #修改配置文件
...此处省略1万字...
  upstream   backend  {              #创建集群(集群名称见名知意即可)
  ip_hash;                           #源地址哈希
  server   192.168.8.100:80 weight=2;         #权重设置为2
  server   192.168.8.200:80 weight=1;         #权重设置为1
  }
server  {                            #虚拟web主机
  listen   80;
  server_name   localhost;           #域名
  location  /  {
  ...
  proxy_pass   http://backend;      #将请求调度至 web集群(与上方集群名称一致)
  }
}
...此处省略1万字...
}
[root@proxy ~]# /usr/local/nginx/sbin/nginx -s reload  #重新加载配置
[root@proxy ~]# ss -nutlp | grep :80         #查看端口号
  • 客户端访问验证,源地址不变,永远都有一个服务器提供服务
bash 复制代码
[root@client ~]# curl 192.168.4.50  
web1web1
[root@client ~]# curl 192.168.4.50  
web1web1
[root@client ~]# curl 192.168.4.50  
web2web2

也就是说,如果源IP不改变,永远是同一个服务端提供服务

三、TCP/UDP 调度(四层代理)

TCP:可靠的(三次握手),面向连接的协议

UDP:非面向连接的协议

3.1 模块与升级

  • 依赖模块:ngx_stream_core_module
  • nginx从1.9版本以后开始支持此功能,编译时增加**--with-stream**开启
  • nginx升级只需要升级主程序 (主程序中定义了支持什么功能,与配置文件,网页文件,日志都无关),平滑升级、灰度发布
    升级分为:版本升级和功能升级

灰度发布:又叫金丝雀发布/平滑升级

特点:业务不停止

基本流程是:初始化增加新功能-->备份原程序-->编译-->拷贝新程序-->make upgrade 升级主程序

bash 复制代码
[root@proxy ~]# cd nginx-1.22.1          #切换目录
[root@proxy nginx-1.22.1]# ./configure \  #初始化
> --prefix=/usr/local/nginx \          #指定安装目录为/usr/local/nginx
> --user=nginx \                       #指定用户名(运行服务后进程的所有者)
> --group=nginx \                      #指定组(运行服务后进程的组)
> --with-http_ssl_module     --with-stream   #支持加密功能、支持四层代理
[root@proxy nginx-1.22.1]# mv  /usr/local/nginx/sbin/nginx /usr/local/nginx/sbin/nginx.old  #备份原程序
[root@proxy nginx-1.22.1]# make             #编译
[root@proxy nginx-1.22.1]# cp  objs/nginx   /usr/local/nginx/sbin/  #拷贝新的主程序
[root@proxy nginx-1.22.1]# make  upgrade    #升级主程序。同时,杀掉旧进程,拉起新进程。这个过程服务依旧不会断开
[root@proxy nginx-1.22.1]# /usr/local/nginx/sbin/nginx    -V   #查看主程序,已开启四层代理

解析:

  • 前面的重新初始化和编译的操作是为了更新源目录之中的nginx,即objs/nginx
  • 那么,为什么mv /usr/local/nginx/sbin/nginx /usr/local/nginx/sbin/nginx.old #备份原程序时服务一直没断?
    • 因为处理服务的是进程,而不是程序。虽然配置文件挪走了但是内存里的进程没掉
  • make upgrade 升级主程序的同时,还会杀掉旧进程,拉起新进程。这个过程中服务始终不会断开

3.2 四层代理配置(转发 SSH 22 端口)

3.2.1 四层代理实验架构图
  • 客户端访问proxy代理服务器,proxy主机代理web1与web2的sshd服务(Linux 远程连接服务)
3.2.2 四层代理语法

注意: 四层代理不需要写入http{}配置中

bash 复制代码
stream { #四层代理配置
	upstream sshbackend { #定义四层集群
		server 192.168.8.100:22; #定义集群成员
		server 192.168.8.200:22; #定义集群成员
		}	
server {
listen 12345; #监听端口
proxy_pass sshbackend; #将请求转发至sshbackend集群
}
}
3.2.3 配置proxy代理服务器
nginx 复制代码
[root@proxy ~]# vim  /usr/local/nginx/conf/nginx.conf         #修改配置文件
...
stream   {                       #四层代理配置
  upstream    sshbackend  {      #定义四层集群
  server   192.168.8.100:22;     #定义集群成员
  server   192.168.8.200:22;     #定义集群成员
  }
}
server  {    
  listen   12345;                 #监听端口
  proxy_pass   sshbackend;       #将请求转发至sshbackend集群
}
...
[root@proxy ~]# /usr/local/nginx/sbin/nginx  -s  reload    #重新加载nginx配置
[root@proxy ~]# ss -nutlp | grep :12345    #查看nginx已经启用12345端口

3.3 客户端访问验证

  • client反复执行命令:ssh -p 12345 192.168.4.50
  • 每次连接的都是不同的主机、web1、web2轮询
bash 复制代码
# 客户端 SSH 连接(轮询访问 web1、web2)
[root@client ~]# ssh -p 12345 192.168.4.50

输入密码的时候需要输入的是被代理的主机的密码,而不是proxy主机的密码

做无密码连接时,需要一级一级实现免密:

客户端 → 代理机 proxy:客户端生成密钥,把客户端公钥传给 proxy,实现客户端免密登代理机

代理机 proxy → 后端主机 :在 proxy 上单独生成密钥,把proxy 本机公钥传给后端服务器,实现代理免密登后端

四、Nginx 优化

4.1 常见 HTTP 状态码

常见的200,403,404,500,502

一般情况下,500是内部服务器问题,502是代理的问题

补充:451,网站因内容非法被封禁

4.2 404 错误页面优化

  • 实验以web1主机为例
nginx 复制代码
[root@web1 ~]# vim  /usr/local/nginx/conf/nginx.conf         #修改配置文件
http   {    
  fastcgi_intercept_errors on;      #开启错误页面重定向,全局配置,动态静态页面都生效
  ...
server  {    
  error_page   404  /404.html;      #404报错将请求,则打开404.html页面
  #注意:那个虚拟主机(server {})配置了这句话才生效。如果希望所有都生效,就需要在所有的虚拟web主机(所有的server {})都配置error_page
}
}
#注: fastcgi_intercept_errors on; 表示nginx会拦截php-fpm的报错,使用自定义的错误页面
[root@web1 ~]# /usr/local/nginx/sbin/nginx -s reload    #重新加载配置

注意:如果不加: fastcgi_intercept_errors on; 那么自定义的错误重定向404只会对静态页面生效

  • 创建404.html
bash 复制代码
# 创建 404 页面
[root@web1 ~]# echo "This is error page" > /usr/local/nginx/html/404.html

# 重载配置
[root@web1 ~]# /usr/local/nginx/sbin/nginx -s reload
  • Windows客户端访问一个不存在的页面,测试

4.3 status 状态页面(监控)

  • status模块(--with-http_stub_status_module):此模块支持查看nginx的连接数等信息
  • web1虚拟机升级nginx支持status模块
(1)升级 Nginx(web1)
bash 复制代码
[root@web1 ~]# cd nginx-1.22.1           #切换目录
[root@web1 nginx-1.22.1]# ./configure \  #初始化
> --prefix=/usr/local/nginx \            #指定安装目录为/usr/local/nginx
> --user=nginx \                  #指定用户名(运行服务后进程的所有者)
> --group=nginx \                 #指定组(运行服务后进程的组)
> --with-http_ssl_module     --with-stream   \  #支持加密功能、支持四层代理
> --with-http_stub_status_module               #支持开启nginx状态模块  
]# mv  /usr/local/nginx/sbin/nginx  /usr/local/nginx/sbin/nginx.old  #备份原程序
[root@web1 nginx-1.22.1]# cp  objs/nginx   /usr/local/nginx/sbin/  #拷贝新的主程序
[root@web1 nginx-1.22.1]# make             #编译
[root@web1 nginx-1.22.1]# make  upgrade    #升级主程序
[root@web1 nginx-1.22.1]# /usr/local/nginx/sbin/nginx    -V   #查看主程序,已开启四层代理
(2)配置 status 页面
  • 修改nginx.conf配置文件,开启status页面
nginx 复制代码
[root@web1 ~]# vim  /usr/local/nginx/nginx.conf  #修改nginx主配置文件
server  {
  ...
  location  /status  {          #匹配用户的URL,如果访问地址包括status
  stub_status on;               #开启status页面
  allow 192.168.8.1;            #允许 192.168.8.1访问
  deny  all;                    #拒绝其他所有主机访问状态页面
  }
  ...
}
[root@web1 ~]# /usr/local/nginx/sbin/nginx -s reload  #重新加载配置文件
(3)状态参数说明
  • Active connections:当前活动连接数
  • Accepts:累计接受连接总数
  • Handled:累计处理连接总数
  • Requests:累计请求总数
  • Reading:正在读取请求头的连接数
  • Writing:正在返回响应的连接数
  • Waiting:等待响应的客户端连接数

PV(Page View):页面浏览量,即网站页面在一定时间内被访问的页面总次数,相同用户刷新相同页面也被计算一次,反映了用户对网站内容的浏览情况,可以通过访问日志得到。

UV(Unique Visitor):独立访客数,统计一定周期内,访问网站的独立用户数量,不重复计算同一用户的多次访问。可以通过访问日志或根据用户的唯一标识去重得到

PV与UV都是衡量业务活跃度的重要指标,尤其网站改版升级后,可以进行对比来判断业务情况

4.4 隐藏 Nginx 版本号

  • 每个软件都有Bug,因此版本号需要隐藏,如果未优化404错误页面,访问错误页面则可以直接看到nginx版本
  • 或者使用curl -I 访问服务器头部信息,也可以直接看到nginx版本
bash 复制代码
# 未优化前(暴露版本)
[root@web1 ~]# curl -I 192.168.8.100
HTTP/1.1 200 OK
Server: nginx/1.22.1
  • 修改nginx.conf全局配置信息,关闭显示nginx版本号
bash 复制代码
[root@web1 ~]# vim  /usr/local/nginx/conf/nginx.conf  #修改nginx配置文件
http {
  ...
  server_tokens off;              #关闭nginx版本号显示
  ...
}
[root@web1 ~]# /usr/local/nginx/sbin/nginx -s reload  #重新加载nginx配置
[root@web1 ~]# curl -I  192.168.8.100    #访问服务器的头部信息
HTTP/1.1 200 OK
Server: nginx                     #nginx版本已隐藏
...

4.5 页面压缩(gzip)

  • 修改nginx.conf全局配置信息,开启页面压缩,提高服务器相应速度
  • 每种文件格式的写法可以参见配置文件:/usr/local/nginx/conf/mime.types
bash 复制代码
[root@web1 ~]# vim  /usr/local/nginx/conf/nginx.conf  #修改nginx配置文件
http {
  ...
  gzip on;  #开启页面压缩
  gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;  #对此类型文件压缩
      gzip_min_length 1k;  #小于1k的不压缩
      gzip_comp_level 6;  #压缩等级为6,速度居中,压缩比例居中
  ...
}
[root@web1 ~]# /usr/local/nginx/sbin/nginx  -s reload      #重新加载配置

4.6 并发量优化

  • 常见压力测试工具
  • ab压力测试工具
    • 命令格式: ab -c 模拟人数 -n 请求总数 地址/
  • 其他常见的压力测试工具
    • http_load、webbench、siege
bash 复制代码
[root@web1 ~]# dnf -y install httpd-tools                       #安装软件提供ab命令
[root@web1 ~]# ab  -c  2000   -n  2000   http://192.168.8.100/  #模拟2000次访问
...
socket: Too many open files (24)  #报错信息

可以看到,Nginx是有并发量的限制的,达到上限就会报错

修改配置突破限制
  • 修改nginx.conf配置文件,突破并发量限制
bash 复制代码
[root@web1 ~]# vim   /usr/local/nginx/conf/nginx.conf  #修改nginx配置文件
...
worker_processes  1;              #nginx进程数量,与CPU数量保持一致(lscpu查看cpu数量)
...
events {
    worker_connections  100000;   #每个进程处理的并发量数量修改为100000
}
...
[root@web1 ~]# /usr/local/nginx/sbin/nginx  -s  reload  #重新加载配置
ab 压力测试
  • 优化Linux内核参数(最大文件数量)
  • 永久修改内核参数,需要修改配置文件:/etc/security/limits.conf,重启生效
bash 复制代码
# 测试(2000并发,2000请求)
[root@web1 ~]# ulimit  -n                #查看文件最大连接数,默认为1024
[root@web1 ~]# ulimit -n 100000          #将内核最大文件连接数修改为100000
[root@web1 ~]# ab  -c  2000   -n  2000   http://192.168.8.100/  #模拟2000次访问

补充:永久设置最大文件数量(知晓即可,无须操作)

root@web1 \~\]# vim /etc/security/limits.conf ...此处省略1万字... * soft nofile 100000 * hard nofile 100000 ...此处省略1万字... #该配置文件分4列,分别如下: #用户或组 软限制或硬限制 需要限制的项目 限制的值 重启系统生效 ### 五、总结 * 掌握Nginx七层代理的应用及配置方式 * 掌握Nginx四层代理的应用及配置方式 * 掌握Nginx集群常用算法 * 掌握Nginx优化配置 * 404错误页面优化 * status状态页面 * 隐藏Nginx版本号 * Nginx页面压缩 * Nginx并发量

相关推荐
遇印记3 小时前
软考知识点(windows系统管理与命令)
运维·服务器·网络·windows·ddos
木雷坞3 小时前
csdn-enterpriseGitLab Runner docker pull 慢:并行流水线镜像拉取排查
运维·docker·容器·gitlab
十子木3 小时前
git 如何恢复特定版本的内容
linux·git
雪度娃娃3 小时前
Asio异步读写——简单服务器和客户端异步通信
运维·服务器·网络·c++·php
2601_953660373 小时前
File类
linux·开发语言·python
梦仔生信进阶3 小时前
【linux使用技巧】复制粘贴快捷键
linux
sbjdhjd4 小时前
02 下 | Kubernetes Pod 实战实验完全解析
linux·运维·云原生·kubernetes·podman·kubelet·kubeless
H Journey4 小时前
VMware + Linux(Ubuntu) + 桥接网络知识梳理
linux·网络·ubuntu
少年攻城狮4 小时前
阿里云系列---【申请域名并绑定到主机ip】
linux·服务器·tcp/ip·阿里云·云计算