Nginx性能优化的几个方法
[TOC]
小伙伴们平时使用 Nginx 是否有进行过性能优化呢?还是软件装好了就直接使用呢?
今天松哥和大伙分享几个常见的 Nginx 优化配置。
整体上来说,Nginx 的优化可以从多个层面进行:
- 系统层面
- 配置层面
- 缓存利用
- 压缩策略
- 负载均衡策略
接下来我们就来看看具体该如何做。
一 Nginx 配置优化
- 调整
worker_processes
参数,通常设置为等于服务器的 CPU 核心数。 - 调整
worker_connections
参数,以增加每个 Worker 进程可以打开的连接数。
1 | events { |
- 使用 HTTP/2 协议,利用多路复用和头部压缩等特性,提高页面加载速度。
1 | server { |
- 优化 SSL/TLS 配置,如关闭不安全的加密算法、使用 TLS 1.3 等,提高安全性和性能。
1 | ssl_protocols TLSv1.2 TLSv1.3; |
二 缓存利用
- 启用文件缓存,减少磁盘 I/O 操作。
- 使用代理缓存,缓存后端服务器的响应内容。
- 设置合理的缓存过期策略,通过
Cache-Control
和Expires
头控制浏览器缓存的有效期,减少请求次数。
1 | proxy_cache_path /data/nginx/cache levels=1:2 keys_zone=my_cache:10m max_size=10g inactive=60m use_temp_path=off; |
在上面这段配置中,proxy_cache_path
指令用于配置一个缓存区域,该区域用于存储代理请求的响应内容。这个指令通常在 http
块中使用,并且是 ngx_cache_purge
模块和 ngx_http_proxy_module
模块的一部分。
这项配置中的各参数含义如下:
/data/nginx/cache
:这是缓存文件存储的物理路径。Nginx 将在该目录下存储缓存数据。levels=1:2
:这定义了缓存文件的目录结构。在这个例子中,1:2
意味着 Nginx 将缓存文件存储在/data/nginx/cache
下的一级目录和二级目录中。1
代表第一级目录的数量(通常是 3 个,如data
、tmp
、html
),2
代表第二级目录的数量(通常是 64 个,基于 0 到 63 的数字或字母)。keys_zone=my_cache:10m
:这定义了一个共享内存区域,用于存储缓存键和元数据。my_cache
是该区域的名称,10m
表示分配的共享内存大小为 10MB。这个区域用于存储缓存的键和相关信息,以便快速检索和验证缓存的有效性。max_size=10g
:这指定了缓存区域的最大大小,单位是字节。在这个例子中,缓存区域的最大大小为 10GB。当缓存数据达到这个大小时,Nginx 将使用一种策略(通常是最近最少使用 LRU 算法)来移除旧的缓存数据,为新的缓存数据腾出空间。inactive=60m
:这定义了缓存对象在多久没有被访问后会被认为“非活跃”并可能被移除。在这个例子中,如果一个缓存对象在 60 分钟内没有被访问,它将被认为是非活跃的。这个参数有助于控制缓存中旧数据的生命周期。use_temp_path=off
:这指定了是否使用临时路径来存储缓存文件。off
表示不使用临时路径,所有的缓存文件都直接存储在指定的/data/nginx/cache
路径下。如果设置为on
,则 Nginx 会使用一个临时目录来存储缓存文件,在文件被访问后,它们会被移动到永久的缓存目录中。
三 压缩策略
- 启用 Gzip 压缩,减少数据传输量,提高响应速度。
- 根据服务器的 CPU 能力和网络条件平衡压缩级别和最小压缩大小,以达到最佳的性能。
1 | gzip on; |
各项配置的含义分别如下:
gzip on;
:启用 Gzip 压缩。当这个指令被设置为on
时,Nginx 会尝试压缩响应体并发送给客户端。gzip_vary on;
:这个指令告诉 Nginx 在响应头中添加Vary: Accept-Encoding
。这允许缓存系统(如代理或 CDN)根据客户端是否支持压缩来存储不同的响应版本。gzip_proxied any;
:这个指令允许 Nginx 对从任何代理服务器接收的响应进行压缩,无论响应是否已经被压缩。any
表示无论原始响应是否被压缩,Nginx 都会尝试再次压缩它。其他选项包括off
(不压缩任何代理的响应)和expired
(只压缩那些已经过期的代理响应)。gzip_comp_level 5;
:这个指令设置 Gzip 压缩级别。压缩级别范围从 1(最快,压缩比最低)到 9(最慢,压缩比最高)。5 是一个在速度和压缩比之间取得平衡的常用值。gzip_min_length 256;
:这个指令设置响应体的最小长度,只有当响应体大于或等于这个值时,Nginx 才会对其进行压缩。这里设置为 256 字节,意味着只有当响应体大于或等于 256 字节时,才会进行压缩。gzip_types text/plain application/xml application/json application/javascript text/css;
:这个指令指定了哪些 MIME 类型的响应应该被压缩。在这个例子中,文本、XML、JSON、JavaScript 和 CSS 类型的响应将被压缩。
四 安全性优化
- 隐藏 Nginx 版本号信息,更改源码隐藏 Nginx 软件名及版本号。
- 修改 Nginx 服务的默认用户,提高安全性。
- 配置 OCSP stapling、ssl_stapling、ssl_stapling_verify 等以增强 SSL/TLS 的安全性。
隐藏版本信息可以提高服务器的安全性,使攻击者难以通过版本信息推断出服务器可能存在的安全漏洞。
要隐藏 Nginx 版本号,有三个办法,一般来说我们使用第一种方式就可以了。
修改配置文件
在 Nginx 的配置文件中,在 http
块中添加以下配置:
1 | server_tokens off; |
这样设置后,Nginx 将不会在错误页面上显示版本号。
配置完成之后,保存配置文件并重新加载 Nginx 以应用更改:
1 | nginx -t # 测试配置文件是否正确 |
这种方法可以隐藏错误页面上的版本信息,但可能无法完全隐藏所有响应头中的版本信息 。
修改 Nginx 源码
如果想要从根源上修改 Nginx 版本信息,需要重新编译 Nginx,步骤如下:
- 修改
src/core/nginx.h
文件中的版本定义。 - 修改
src/http/ngx_http_header_filter_module.c
文件中的服务器字符串。 - 修改
src/http/ngx_http_special_response.c
文件中的错误页面底部信息。
修改完这些文件后,需要重新编译 Nginx。这样编译安装后,Nginx 的版本信息将被彻底修改 。
使用第三方模块
如果需要动态修改响应头中的版本信息,可以使用如 headers-more-nginx-module
模块。这个模块允许你动态地添加、修改或删除 Nginx 的响应头。通过这个模块,可以完全控制 Server
响应头的内容 。
选择哪种方法取决于你的具体需求和环境。
如果你只是想简单地隐藏版本信息,修改配置文件可能是最简单的方法。如果你需要更彻底地控制版本信息,可能需要考虑修改源码并重新编译 Nginx。
五 监控和日志优化
- 使用日志分析工具(如 ELK Stack、Graylog 等)来分析和可视化 Nginx 的日志数据。
- 定期维护策略,如更新 Nginx、审查配置文件、备份配置文件等。
- 使用定时任务工具(如 cron)定期清理缓存,使用 Nginx 的
proxy_cache_path
指令中的inactive
参数设置缓存的过期时间。
日志配置如下:
1 | access_log /var/log/nginx/access.log; |
六 系统层面优化
- 调整文件描述符限制(在
/etc/sysctl.conf
中设置):
1 | fs.file-max = 65535 |
- 调整 TCP 连接队列大小(在
/etc/sysctl.conf
中设置):
1 | net.core.somaxconn = 1024 |
七 故障转移优化
- 优化健康检查,调整健康检查的频率、超时时间、检查的内容等参数,以更准确地检测服务器的故障。
- 结合监控系统,实时监控服务器的健康状况、请求流量、响应时间等指标,及时发现潜在的问题,并进行预警和处理。
配置健康检查(使用第三方模块 nginx_upstream_check_module
):
1 | upstream backend { |
小伙伴们还做过哪些 Nginx 性能优化配置呢?欢迎留言讨论。