一、环境准备
1.1 虚拟机规划
- 使用 template 模板机准备 3 台虚拟机
- proxy 服务器 配置双网卡:
- ens160:连接服务端,网段 192.168.8.0/24
- ens192:连接客户端,网段 192.168.4.0/24
1.2 proxy 网卡配置
(1)添加第二块网卡(VMware 操作)
- 编辑虚拟机设置 → 添加 → 网络适配器 → 完成
- 网络连接选择 自定义(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 #重新加载配置文件
- Windows客户端访问测试:http://192.168.8.100/status
(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并发量