一、Nginx 性能调优
1. worker_processes 工作进程最大连接数
- 每个
worker
进程的
最大连接数
。- 语法:
worker_connections 'number';
- 默认:
worker_connections 1024;
- 每个
worker
进程 都是 单线程 的进程,它们会调用 各个模块 以实现多种多样的功能。- 如果 这些模块 确认不会出现 阻塞式 的调用,那么,有多少
CPU
内核就应该配置多少个进程。- 反之,如果有可能出现 阻塞式 调用,那么需要配置稍多一些的
worker
进程。
- 例如:如果业务方面会致使 用户请求 大量读取 本地磁盘上的静态资源文件,而且服务器上的内存较小,以至于 大部分的请求 访问 静态资源文件 时,都必须读取磁盘(磁头的寻址是缓慢的),而不是内存中的磁盘缓存,那么磁盘
IO
调用可能会 阻塞 住
worker
进程少量时间,进而导致服务整体性能下降。
# `2`个工作进程
worker_processes 2;
2. worker_cpu_affinity 工作进程绑定 CPU 内核
- 绑定
worker
进程到 指定的
CPU
内核。- 语法:
worker_cpu_affinity cpumask[cpumask……];
- 假定每一个
worker
进程都是非常繁忙的,如果多个
worker
进程都在抢同一个
CPU
,那么这就会出现 同步问题。- 反之,如果每一个
worker
进程都独享一个
CPU
,就在 内核的调度 策略上实现了完全的 并发。- 注意:
worker_cpu_affinity
配置仅对
Linux
操作系统有效。
# 如:如果有`2`颗`CPU`内核,就可以进行如下配置
worker_processes 2;
worker_cpu_affinity 10 01;
# 如:如果有`4`颗`CPU`内核,就可以进行如下配置
worker_processes 4;
worker_cpu_affinity 1000 0100 0010 0001;
3. worker_priority 工作进程优先级
- 语法:
worker_priority nice;
- 默认:
worker_priority 0;
- 优先级,由 静态优先级 和 内核 根据 进程执行情况 所做的 动态调整(目前只有
±5
的调整)共同决定。
nice
值是进程的 静态优先级(它的取值范围是
-20~+19
)。
-20
是 最高优先级,
+19
是 最低优先级。
- 因此,如果用户希望 Nginx 占有更多的系统资源,那么可以把
nice
值配置得更小一些。
但不建议比 内核进程 的
nice
值(通常为
–5
)还要小。
4. worker_rlimit_nofile 工作进程可以打开的最大句柄描述符个数
- 语法:
worker_rlimit_nofile 'limit';
- 默认:空。
- 更改
worker
进程的 最大打开文件数限制。- 如果 没设置的话,这个值为 操作系统的限制。
- 设置后你的 操作系统 和 Nginx 可以处理比
ulimit -a
更多的文件。- 所以把这个值设高,这样 Nginx 就不会有
too many open files
问题了。
5. 是否打开 accept 负载均衡锁
- 语法:
accept_mutex ['on'|'off']
- 默认:
accept_mutext on;
开
accept_mutex
是
Nginx
的 负载均衡锁。
- 当某一个
worker
进程 建立的连接数量,达到
worker_connections
配置的 最大连接数 的
7/8
时。- 会大大地减小 该
worker
进程 试图建立 新
TCP
连接 的机会。
accept
锁默认是打开的。
- 如果关闭它,那么 建立
TCP
连接 的耗时会更短。- 但
worker
进程 之间的 负载 会 非常不均衡,因此
不建议关闭它
。
6. 使用 accept 锁后到真正建立连接之间的延迟时间
- 语法:
accept_mutex_delay 'Nms';
- 默认:
accept_mutex_delay 500ms;
- 在使用
accept
锁后,同一时间只有一个
worker
进程能够取到
accept
锁。- 这个
accept
锁不是 堵塞锁,如果取不到会立刻返回。- 如果只有一个
worker
进程 试图取锁而没有取到,他至少要等待
accept_mutex_delay
定义的时间才能再次试图取锁。
二、Nginx 高速缓存
Redis
采用
key-value
缓存详情页主体
html
。
1. 静态缓存
- 问题:当达到
500 QPS
的时候,很难继续压测上去。- 原因:一个详情页
html
页面平均
150kb
,那么在
500 QPS
已接近 千兆局域网宽带 极限,必须减少内网通信。
- 在
http
模块中,添加 缓存区 声明。
http {
# 指定缓存区的根路径
proxy_cache_path /data/nginx/cache_item
# 缓存层级及目录位数
# 缓存目录层级最高三层,每层`1~2`个字符表示
# 如:`1:1:2`表示`一级目录:二级目录:三级目录`
# `1`表示最后一个字符为目录名、`2`表示最后两个字符为目录名。
levels=1:1:2
# 缓存块名称及内存块大小
# 超出大小后最早的数据将会被清除
# 如:`cache_item:500m`表示声明一个名为`cache_item`大小为`500m`的缓存。
keys_zone=cache_item:500m
# 最长闲置时间(有效期)
# 如:`30d`如果一个数据被闲置`30`天将会被清除
inactive=30d
# 缓存区硬盘最大值,超出最大值闲置数据将会被清除
max_size=10g;
}
- 为
location
设定 缓存策略。
location {
# 指定缓存区,对应`http.keys_zone`中配置的缓存区
proxy_cache cache_item;
# 通过参数拼装缓存`key`
# 如:`$host$uri$is_args$args`以全路径的`md5`值做做为`key`
proxy_cache_key $host$uri$is_args$args;
# 为不同的`HTTP`状态码设置缓存有效期
proxy_cache_valid 200 304 12h;
# 总体缓存时间
expires 7d;
}
- 示例。
http {
# 缓存声明
proxy_cache_path /data/nginx/cache_qs levels=1:2 keys_zone=cache_qs:500m inactive=20d max_size=1g;
}
2. 清除缓存
- 可以采用第三方模块
ngx_cache_purge
实现。
# 下载`ngx_cache_purge`模块包(这⾥`nginx`版本为`1.6.2 purge`对应`2.0`版)
wget http://labs.frickle.com/files/ngx_cache_purge-2.3.tar.gz
# 查看已安装模块
./sbin/nginx -v
# 进⼊`Nginx`安装包⽬录,重新安装`--add-module`为模块解压的全路径
./configure --prefix=/root/svr/nginx --with-http_stub_status_module --with-http_ssl_module --
add-module=/root/svr/nginx/models/ngx_cache_purge-2.3
# 重新编译
make
# 拷⻉安装⽬录`/objs/nginx`⽂件⽤于替换原`nginx`⽂件
# 检测查看安装是否成功
nginx -t
- 清除配置。
location ~ /clear(/.*) {
# 允许访问的`IP`
allow 127.0.0.1;
allow 192.168.0.193;
# 禁⽌访问的`IP`
deny all;
# 配置清除指定缓存区和路径(与`proxy_cache_key`一致)
proxy_cache_purge cache_item $host$1$is_args$args;
}
- 测试。
- 访问生成缓存文件:
- 访问清除缓存文件:
http://www.qs.com/clear/?a=1
如果指定缓存不存在,则会报
404
错误。
三、Nginx 集群
1. keepalived 安装运行
yum install keepalived
# 配置文件`/etc/keepalived/keepalived.conf`
- 启动停止。
systemctl start keepalived.service
systemctl stop keepalived.service
systemctl restart keepalived.service
- 查看日志。
tail -f /var/log/messages