- 首先需要了解的是当前系统瓶颈,用的是什么,跑的是什么业务。里面的服务是什么样子,每个服务最大支持多少并发。
- 可以通过查看当前 CPU 负荷,内存使用率,来做简单判断。
- 还可以通过操作系统的一些工具来判断当前系统性能瓶颈,如分析对应的日志,查看请求数量。
- 也可以通过 Nginx
http_stub_status_module
监控模块来查看对应的连接数,总握手次数,总请求数。
- 虽然我们是在做性能优化,但还是要熟悉业务,最终目的都是为业务服务的。
- 我们要了解每一个接口业务类型是什么样的业务,比如电子商务抢购模式,这种情况平时流量会很小,但是到了抢购时间,流量一下子就会猛涨。也要了解系统层级结构,每一层在中间层做的是代理还是动静分离,还是后台进行直接服务。
对相关的系统瓶颈及现状有了一定的了解之后,就可以根据影响性能方面做一个全体的评估和优化。
- 网络(网络流量、是否有丢包,网络的稳定性都会影响用户请求)
- 系统(系统负载、内存使用率、系统的稳定性、硬件磁盘是否有损坏)
- 服务(连接优化、内核性能优化、http服务请求优化都可以在nginx中根据业务来进行设置)
- 程序(接口性能、处理请求速度、每个程序的执行效率)
- 数据库、底层服务
上面列举出来每一级都会有关联,也会影响整体性能,但是我们更加主要关注的是 Nginx 服务这一层。
- 在 Linux/Unix 操作系统中一切皆文件,我们的设备是文件,文件是文件,文件夹也是文件。当我们用户每发起一次请求,就会产生一个文件句柄。
文件句柄可以简单的理解为文件句柄就是一个索引
- 文件句柄会随着请求量的增多,进程调用频繁增加,那么产生的文件句柄也就会越多。
- 系统默认对文件句柄是有限制的,不可能会让一个进程无限制的调用句柄。因为系统资源是有限的,操作系统默认使用的文件句柄是1024个句柄。
修改方式
- 系统全局性修改
- 用户局部性修改
- 进程局部性修改
[root@localhost ~]# vim /etc/security/limits.conf
#* soft core 0
#* hard rss 10000
#@student hard nproc 20
#@faculty soft nproc 20
#@faculty hard nproc 50
#ftp hard nproc 0
#@student - maxlogins 4
//root只是针对root这个用户来限制,soft只是发提醒,操作系统不会强制限制,一般的站点设置为一万左右就ok了
root soft nofile 65535
root hard nofile 65535
// *代表通配符 所有的用户
* soft nofile 25535 //用户可打开的文件描述符的最大数(软限制)
* hard nofile 25535 //hard硬控制,到达设定值后,操作系统会采取机制对当前进程进行限制,这个时候请求就会受到影响
* soft nproc 65535 //单个用户可用的最大进程数量(软限制)
* hard nproc 65535 //单个用户可用的最大进程数量(硬限制)
可以看到root
和*
,root
代表是 root 用户,*
代表的是所有用户,后面的数字就是文件句柄大小。
[root@localhost ~]# vim /etc/nginx/nginx.conf
user nginx; #运行 Nginx 的用户。可以修改
worker_processes 1;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
worker_rlimit_nofile 65535; #进程限制,配置 Nginx worker 进程最大打开文件数
events {
worker_connections 1024; #一个 worker 进程的并发
}
...
worker_rlimit_nofile
是在进程上面进行限制。
#ulimit 命令,用于查看系统限制的值
# -a 显示目前资源限制的设定。
# -n <文件数目> 指定同一时间最多可开启的文件数。
1、ulimit -a 显示系统资源的设置
core file size (blocks, -c) 0
data seg size (kbytes, -d) unlimited
scheduling priority (-e) 0
file size (blocks, -f) unlimited
pending signals (-i) 63154
max locked memory (kbytes, -l) 64
max memory size (kbytes, -m) unlimited
open files (-n) 1024 #默认用户可以打开文件的最大数量
pipe size (512 bytes, -p) 8
POSIX message queues (bytes, -q) 819200
real-time priority (-r) 0
stack size (kbytes, -s) 8192
cpu time (seconds, -t) unlimited
max user processes (-u) 63154
virtual memory (kbytes, -v) unlimited
file locks (-x) unlimited
2、ulimit -n 65535 #临时修改打开句柄数
CPU 的亲和能够使 Nginx 对于不同的 work 工作进程绑定到不同的 CPU 上面去。能够减少在 work 间不断切换 CPU ,来减少性能损耗。
首先要明确物理 CPU 个数、核数、逻辑 CPU 数的概念
1、物理 CPU 数:主板上实际插入的 CPU 数量,可以数不重复的 physical id 有几个(physical id)
2、 CPU 核数:单块 CPU 上面能处理数据的芯片组的数量,如双核、四核等 ( CPU cores)
3、逻辑 CPU 数:一般情况下,逻辑 CPU =物理CPU个数×每颗核数.
//查看物理 CPU 数量
[root@localhost ~]# cat /proc/cpuinfo | grep "physical id" | sort|uniq | wc -l
2
//查看每个 CPU 的核心数
[root@localhost ~]# cat /proc/cpuinfo|grep "cpu cores"|uniq
cpu cores : 1
//查看 CPU 使用率
[root@localhost ~]# top 回车后按 1
%Cpu0 : 0.0 us, 0.0 sy, 0.0 ni,100.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
%Cpu1 : 0.0 us, 0.0 sy, 0.0 ni,100.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
//配置 worker_processes (指的是逻辑 CPU 个数)
[root@localhost ~]# vim /etc/nginx/nginx.conf
//将刚才查看到自己 CPU * CPU 核心就是 worker_processes
worker_processes 2; //根据自己 CPU 核心数配置;或者直接可以设置为auto
//配置nginx进程绑定到对应的cpu,通过下面命令查看nginx进程配置在哪个核上
[root@localhost ~]# ps -eo pid,args,psr |grep [n]ginx
//-e 显示所有进程
//-o 自定义输出格式
//pid 进程ID
//args 进程启动命令行
//psr 进程状态
[root@localhost ~]# ps -eo pid,args,psr |grep [n]ginx
953 nginx: master process /usr/ 1
954 nginx: worker process 0
955 nginx: worker process 1
在 Nginx 1.9版本之后,程序帮我们自动绑定了 CPU
将 work 的进程绑定到不同的 CPU 核数上,尽可能的减少进程间的切换,指的是 CPU 从一个进程切换到另一个进程,绑定后可以提升处理请求速度和性能
#设置进程与 CPU 的亲和性自动分配权重
worker_cpu_affinity auto;
#将 Nginx 进程设置为普通用户,为了安全考虑
user nginx;
#当前启动的 worker 进程,官方建议是与系统核心数一致
worker_processes auto;
#将work进程绑定到每个 CPU 的核数上
worker_cpu_affinity auto; # CPU 亲缘性/亲和性
#日志配置成warn
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
#针对 Nginx 句柄的文件限制,配置 Nginx worker 进程最大打开文件数> worker_connections 值
worker_rlimit_nofile 65535;
#事件模型
events {
#使用 epoll 内核模型
use epoll;
#每一个进程可以处理多少个连接,如果是多核可以将连接数调高 worker_processes * 1024
worker_connections 2048;
}
http {
server_tokens off; #隐藏 Nginx 的版本号
include /etc/nginx/mime.types;
default_type application/octet-stream;
charset utf-8; #设置字符集,服务端返回给客户端报文的时候, Nginx 强行将报文转码为utf-8
#设置日志输出格式,根据自己的情况设置
log_format main '$http_user_agent' '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for" '
'"$args" "$request_uri"';
access_log /var/log/nginx/access.log main;
sendfile on; #用于开启文件高效传输模式,一般设置为 on ,若 Nginx 是用来进行磁盘IO负载应用时,可以设置为 off ,降低系统负载
tcp_nopush on; #减少网络报文段数量,当有数据时,先别着急发送, 确保数据包已经装满数据, 避免了网络拥塞
tcp_nodelay on; #提高I/O性能,确保数据尽快发送, 提高可数据传输效率
keepalive_timeout 65; #设置长连接的超时时间,请求完成之后还要保持连接多久.
open_file_cache max=35535 inactive=20s #这个将为打开文件指定缓存,默认是没有启用的,max 指定缓存数量,建议和打开文件数一致,inactive 是指经过多长时间文件没被请求后删除缓存。
########
#Gzip module
gzip on; #文件压缩默认可以打开.告诉 Nginx 采用 gzip 压缩的形式发送数据。这将会减少发送的数据量。
gzip_disable "MSIE [1-6]\."; #对于有些浏览器不能识别压缩,需要过滤如ie6
gzip_min_length 1k; #允许压缩的最小字节数
gzip_http_version 1.1; #设置识别 http 协议版本,默认是 1.1
gzip_types text/css text/xml application/javascript #用来指定压缩的类型,‘text/html’类型总是会被压缩。
include /etc/nginx/conf.d/*.conf;
}