Nginx性能优化三大件:
学习目标:
- 能够说出 Nginx 性能优化的三种方法;
- 能够说出 Nginx 的两种日志分类;
- 能够使用 Shell 统计 Nginx 日志;
- 掌握反向代理的核心配置(五行代码);
- 掌握负载均衡的配置方法;
- 了解另外一个负载均衡工具 HAProxy ;
动静分离(面试重点)
动态内容
需后端程序实时生成的数据(如PHP/Java接口返回的JSON、用户登录状态页),通常由应用服务器(如Tomcat、Node.js)处理。
静态内容
无需后端计算、可直接返回的文件(如图片、CSS/JS、字体文件),由Nginx直接高效处理。
动静分离的本质
将静态资源与动态请求分离到不同的服务或目录,通过Nginx精准路由,避免动态请求阻塞静态资源的高效传输,同时降低后端压力。
经典配置:
server {
listen 80;
server_name example.com;
# 动态请求:转发到后端应用服务器(如Tomcat/Node.js)
location /api/ {
proxy_pass http://backend_server:8080/; # 指向后端服务地址
proxy_set_header Host $host; # 传递原始请求头
}
# 静态资源:直接由Nginx从本地目录返回
location ~* \.(jpg|jpeg|png|gif|css|js|woff|woff2|ico)$ {
root /var/www/static; # 静态资源存放目录
expires 30d; # 缓存30天(可选优化)
}
# 默认动态请求(如PHP/HTML模板)
location / {
proxy_pass http://app_server:3000/; # 指向应用服务器
}
}
客户端缓存:
告知浏览器获取的信息是在某个区间时间段是有效的,基本格式:
expires 30s; //表示把数据缓存30秒
expires 30m; //表示把数据缓存30分
expires 10h; //表示把数据缓存10小时
expires 3d; //表示把数据缓存3天
禁止缓存说明:
add_header Cache-Control no-store;
案例:缓存图片/js/css文件,缓存时间为1天
location ~* \.(jpg|jpeg|gif|png|js|css)$ {
expires 1d;
#add_header Cache-Control no-store;
}
开启Gzip压缩:
传输静态资源时,先压缩再传输
压缩文件大小变小了,传输更快了。目前市场上大部分浏览器是支持GZIP的。
IE6以下支持不好,会出现乱码情况。
http://nginx.org/en/docs/http/ngx_http_gzip_module.html
压缩文件大小变小了,传输更快了。目前市场上大部分浏览器是支持GZIP的。
IE6以下支持不好,会出现乱码情况。
gzip on; # 第1行:开启Gzip压缩功能
gzip_min_length 1k; # 第2行:仅压缩大于1KB的文件(小于1KB的压缩后可能更大,不处理)
gzip_buffers 4 16k; # 第3行:压缩时使用的缓冲区数量(4个)和大小(每个16KB)
gzip_http_version 1.1; # 第4行:兼容HTTP/1.1协议(主流浏览器均支持)
gzip_comp_level 5; # 第5行:压缩级别(1-10),数字越大压缩率越高但CPU消耗越大(推荐5~6)
gzip_types text/plain
text/css
text/javascript
application/javascript
application/x-javascript
image/jpeg
image/gif
image/png
image/x-ms-bmp; # 第6行:指定要压缩的文件类型(优先压缩文本和图片)
gzip_vary on; # 第7行:在响应头中添加Vary: Accept-Encoding,帮助缓存服务器区分压缩/未压缩版本
gzip_disable "MSIE [1-6]\."; # 第8行:禁用对IE6及以下版本的Gzip(兼容性问题)
vary 是差异,多样化的意思。
gzip_vary 是 Nginx 配置中的一条指令,它用于控制是否在响应头中设置 Vary: Accept-Encoding 头部。具体来说:
gzip_vary on;:启用时,Nginx 会在响应头中加入 Vary: Accept-Encoding,表示不同的客户端可能会根据是否支持 gzip 压缩来收到不同的响应内容。这有助于缓存服务器(如 CDN)缓存压缩和未压缩的内容。
gzip_vary off;:禁用时,Nginx 不会在响应头中加入 Vary: Accept-Encoding,这意味着缓存服务器不会区分压缩与未压缩的内容。这样做通常会减少缓存的复杂性,但可能会导致某些情况缓存不一致。
| 指令 | 作用 | 推荐值/说明 |
| gzip on; | 开关Gzip功能 | 必须为 on才生效 |
| gzip_min_length 1k; | 最小压缩文件大小 | 避免小文件压缩后体积反而增大(默认20B1k,建议1k10k) |
| gzip_buffers 4 16k; | 压缩缓冲区配置 | 4个16KB的缓冲区(根据服务器内存调整) |
| gzip_http_version 1.1; | 兼容的HTTP协议版本 | 现代浏览器均支持1.1 |
| gzip_comp_level 5; | 压缩级别 | 1(最快但压缩率低)10(最慢但压缩率高),推荐56平衡性能与效果 |
| gzip_types | 指定压缩的文件MIME类型 | 优先压缩文本(如HTML/CSS/JS)、常用图片(如JPEG/PNG) |
| gzip_vary on; | 是否添加Vary头 | 帮助CDN/代理服务器正确缓存压缩与未压缩版本 |
| gzip_disable "MSIE [1-6]."; | 禁用低版本IE的Gzip | IE6对Gzip支持差,可能引发乱码 |
常见压缩类型:
文本类(.html/.css/.js)
矢量图(.svg)
部分图片(.png/.jpg,但已压缩的图片效果有限)。
总结
| 优化方向 | 核心目标 | 关键技术 | 适用场景 |
| 动静分离 | 提升资源处理效率,降低后端压力 | Nginx路由分离(动态→后端,静态→本地/CDN) | 所有Web应用(尤其是高并发场景) |
| 客户端缓存 | 减少重复传输,加速二次访问 | expires/Cache-Control控制缓存时间 | 图片、CSS/JS等长期不变的静态资源 |
| Gzip压缩 | 减小传输体积,降低带宽消耗 | gzip模块压缩文本/图片 | 文本类资源(HTML/CSS/JS)、未高度压缩的图片 |
日志分析:
nginx默认路径所在地:
编译安装:
/usr/local/nginx/logs/access.log(若编译安装时未修改路径)
包管理器dnf:
/var/log/nginx/access.log(若通过包管理器安装)。
常见日志:
错误日志
作用:用于Nginx排错
/usr/local/nginx/logs/error.log or /var/log/nginx/error.log
格式:
时间-错误等级-客户端访问url-结果faild/success-报错信息
错误等级:由低到高
debuf:开发调试
info:常见信息
notice:生产环境参数监控
warn:潜在问题
error:服务运行错误
critical:严重错误
| 级别 | 含义 | 适用场景 |
| debug | 调试信息(最详细) | 开发/排查复杂问题 |
| info | 一般性事件记录 | 跟踪运行状态 |
| notice | 重要但非错误事件 | 生产环境常规监控 |
| warn | 警告事件(不影响服务) | 潜在问题预警 |
| error | 默认级别,错误事件 | 服务异常排查 |
| crit | Critical,严重错误 | 紧急问题(如权限拒绝) |
访问日志:
cat /usr/local/nginx/logs/access.log
| 参数 | 意义 |
| $remote_addr | 客户端的ip地址(代理服务器,显示代理服务ip) |
| $remote_user | 用于记录远程客户端的用户名称(一般为“-”) |
| $time_local | 用于记录访问时间和时区 |
| $request | 用于记录请求的url以及请求方法 |
| $status | 响应状态码,例如:200成功、404页面找不到等。 |
| $body_bytes_sent | 给客户端发送的文件主体内容字节数 |
| $http_referer | 可以记录用户是从哪个链接访问过来的 |
| $http_user_agent | 用户所使用的代理(一般为浏览器) |
| $http_xforwarded_for | 可以记录客户端IP,通过代理服务器来记录客户端的ip地址 |
GoAccess轻量级日志分析
安装:
# 安装 EPEL 仓库(Extra Packages for Enterprise Linux)
dnf install epel-release -y
# 通过 EPEL 安装 GoAccess
dnf install goaccess -y
nginx.conf配置:
访问www.site1.com/site4/即可拿到监控html文件
root /var/www;
server {
listen 80;
server_name www.site1.com;
......
location /site4/ {
index report.html;
}
企业级实战(面试重点)
统计访问量最高的IP地址:
awk '{print $1}' access.log | sort | uniq -c | sort -nr
统计404错误的请求
☆ 场景背景
HTTP 404 状态码表示 “请求的资源不存在”,可能由以下原因导致:
- 用户侧问题:用户手动输入了错误的 URL、点击了过期的书签或外链。
- 业务侧问题:前端页面链接配置错误(如前端代码中的 API 地址拼写错误)、后端服务删除了文件但未更新前端引用、CDN 缓存了旧版本的无效链接。
- 攻击行为:扫描器尝试访问常见的敏感路径(如 /admin.php、/config.json),试图探测系统漏洞。
通过统计 404 错误请求,可以快速定位 “哪些资源被频繁访问但不存在”,进而修复业务逻辑或加固安全防护。
# 提取所有状态码为 404 的日志行(Nginx 默认日志格式中状态码是第9个字段)
awk '$9 == 404' /usr/local/nginx/logs/access.log
# 进阶:提取 404 请求的路径(第7个字段),统计频次并排序
awk '$9==404 {print $7}' /usr/local/nginx/logs/access.log | sort | uniq -c | sort -nr | head -n 5
统计最热门的URL
场景背景
“最热门的 URL” 反映了用户最常访问的页面或接口,是企业分析 “用户关注什么” 和 “业务重点在哪里” 的关键指标。通过统计热门 URL,可以:
- 优化资源配置:为高流量页面分配更多服务器资源(如 CDN 加速、数据库缓存)。
- 改进用户体验:分析热门页面的加载速度、跳出率(需结合其他工具),针对性优化交互设计。
- 验证业务策略:检查推广活动链接(如营销页 /promotion/2025)是否达到预期流量,或核心功能(如支付页 /checkout)是否易用。
# 提取日志中的请求路径(第7个字段),统计频次并排序,取前 10
awk '{print $7}' /usr/local/nginx/logs/access.log | sort | uniq -c | sort -nr | head -n 10
日志轮转
作用:利用Shell脚本对日志进行切割,把大的访问日志切割为一个一个小日志,方便后期存储以及查看分析
脚本实现
# vim logrotate.sh
------------------华丽的分割线-------------------
#!/bin/bash
date_info=$(date +%F-%H-%M)
mv /usr/local/nginx/logs/access.log /usr/local/nginx/logs/access.log.$date_info
/usr/local/nginx/sbin/nginx -s reload
------------------华丽的分割线-------------------
重新加载后可以重新生成新的日志
配置 crontab
# crontab -e
0 */6 * * * /bin/sh /scripts/logrotate.sh &>/dev/null
/6:每六个小时执行一次,因为写在了小时的*符号后面
分时日月周
nginx反向代理:
配置后端服务器:
[root@zero ~]# dnf install epel-release -y
[root@zero ~]# dnf install nginx -y
[root@zero ~]# vi /etc/nginx/nginx.conf
...
server {
listen 8080;
listen [::]:8080;
server_name localhost;
root /usr/share/nginx/html;
# Load configuration files for the default server block.
include /etc/nginx/default.d/*.conf;
error_page 404 /404.html;
location = /404.html {
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
}
}
...
[root@zero ~]# cat > /usr/share/nginx/html/index.html << EOF
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>后端服务器</title>
</head>
<body>
这是后端服务器。
</body>
</html>
EOF
配置代理服务器(面试重点)
在前端服务器上执行,
[root@nginx ~]# vi /usr/local/nginx/conf/nginx.conf
worker_processes auto;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
server {
listen 80;
server_name www.itheima-devops.com;
root html/itheima-devops;
location / {
proxy_pass http://192.168.88.122:8080; # 关键!指定后端服务器的IP和端口
proxy_set_header Host $host; # 传递原始请求的Host头(重要!)
proxy_set_header X-Real-IP $remote_addr; # 传递客户端真实IP(后端可通过此头获取)
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # 传递完整的代理链路IP
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
# root html;
}
}
}
nginx -t
nginx -s reload
负载均衡
四层负载均衡(tcp)
网络层面的负载均衡
用ip+port接收请求,再转发到对应的机器
七层负载均衡(http)
智能型负载均衡
根据虚拟的url地址,主机接收请求,再转向(反向代理)相应的处理服务器