当我需要进行性能优化时,说明我们服务器无法满足日益增长的业务。性能优化是一个比较大的课题,需要从以下几个方面进行探讨
- 当前系统结构瓶颈
- 了解业务模式
- 性能与安全
当前系统结构瓶颈
首先需要了解的是当前系统瓶颈,用的是什么,跑的是什么业务。里面的服务是什么样子,每个服务最大支持多少并发。比如针对nginx而言,我们处理静态资源效率最高的瓶颈是多大?能支持多少qps访问请求?怎么得出系统当前的结构瓶颈?
可以通过查看当前cpu负荷,内存使用率,进程使用率来做简单判断。还可以通过操作系统的一些工具来判断当前系统性能瓶颈,如分析对应的日志,查看请求数量。也可以通过nginx http_stub_status_module模块来查看对应的连接数,总握手次数,总请求数。也可以对线上进行压力测试,来了解当前的系统能性能,并发数,做好性能评估。
了解业务模式
虽然我们是在做性能优化,但还是要熟悉业务,最终目的都是为业务服务的。我们要了解每一个接口业务类型是什么样的业务,比如电子商务抢购模式,这种情况平时流量会很小,但是到了抢购时间,流量一下子就会猛涨。也要了解系统层级结构,每一层在中间层做的是代理还是动静分离,还是后台进行直接服务。需要我们对业务接入层和系统层次要有一个梳理
性能与安全
性能与安全也是一个需要考虑的因素,往往大家注重性能忽略安全或注重安全又忽略性能。比如说我们在设计防火墙时,如果规则过于全面肯定会对性能方面有影响。如果对性能过于注重在安全方面肯定会留下很大隐患。所以大家要评估好两者的关系,把握好两者的孰重孰轻,以及整体的相关性。权衡好对应的点。
1.ab接口压力测试工具
ab是Apache超文本传输协议(HTTP)的性能测试工具。其设计意图是描绘当前所安装的Apache的执行性能,主要是显示你安装的Apache每秒可以处理多少个请求。
查看更多ab使用详情传送门
2.系统与nginx性能优化
大家对相关的系统瓶颈及现状有了一定的了解之后,就可以根据影响性能方面做一个全体的评估和优化。
- 网络(网络流量、是否有丢包,网络的稳定性都会影响用户请求)
- 系统(系统负载、饱和、内存使用率、系统的稳定性、硬件磁盘是否有损坏)
- 服务(连接优化、内核性能优化、http服务请求优化都可以在nginx中根据业务来进行设置)
- 程序(接口性能、处理请求速度、每个程序的执行效率)
- 数据库、底层服务
上面列举出来每一级都会有关联,也会影响整体性能,这里主要关注的是nginx服务这一层。
3.文件句柄
在linux/unix操作系统中一切皆文件,我们的设备是文件,文件是文件,文件夹也是文件。当我们用户每发起一次请求,就会产生一个文件句柄。文件句柄可以简单的理解为文件句柄就是一个索引
。文件句柄就会随着请求量的增多,进程调用频繁增加,那么产生的文件句柄也就会越多。
系统默认对文件句柄是有限制的,不可能会让一个进程无限制的调用句柄。因为系统资源是有限的,所以我们需要限制每一个服务能够使用多大的文件句柄。操作系统默认使用的文件句柄是1024个句柄。
设置方式
- 系统全局性修改
- 用户局部性修改
- 进程局部性修改
系统全局性修该和用户局部性修改
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 soft nofile 65535 #root用户
root hard nofile 65535
* soft nofile 65535 #所有用户
* hard nofile 65535
可以看到root
和*
,root代表是root用户,*代表的是所有用户,后面的数字就是文件句柄大小。大家可以根据个人业务来进行设置。
进程局部性修改
vim /etc/nginx/nginx.conf
user nginx;
worker_processes 1;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
worker_rlimit_nofile 65535; #进程限制
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
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;
#tcp_nopush on;
keepalive_timeout 65;
#gzip on;
include /etc/nginx/conf.d/*.conf;
}
worker_rlimit_nofile
是在进程上面进行限制。
4.cpu的亲和配置
cpu的亲和能够使nginx对于不同的work工作进程绑定到不同的cpu上面去。就能够减少在work间不断切换cpu,把进程通常不会在处理器之间频繁迁移,进程迁移的频率小,来减少性能损耗。nginx 亲和配置
查看当前cpu
cat /proc/cpuinfo|grep "physical id"|sort |uniq|wc -l
查看cpu是几核的
cat /proc/cpuinfo|grep "cpu cores"|uniq
查看cpu使用率
top 回车后按 1
配置worker_processes
vim /etc/nginx/nginx.conf
将刚才查看到自己cpu * cpu核心就是worker_processes
worker_processes 1; #小菜的配置很低所以都是1核
cpu亲和配置
假如小菜的配置是2cpu,每个cpu是8核。配置如下
worker_processes 16;
worker_cpu_affinity 1010101010101010 0101010101010101;
配置完成后可以通过下面命令查看nginx进程配置在哪个核上
ps -eo pid,args,psr |grep [n]ginx
在nginx 1.9版本之后,就帮我们自动绑定了cpu;
worker_cpu_affinity auto;
5.nginx通用配置优化
vim /etc/nginx/nginx.conf
#将nginx进程设置为普通用户,为了安全考虑
user nginx;
#上面配置讲过了
worker_processes 1;
worker_cpu_affinity auto;
#日志配置成warn
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
worker-rlimit-nofile 25535; #文件句柄
events {
use epoll; #事件模型
worker_connections 1024; #nginx 请求连接数,对于1核nginx能够处理1024 如果是多核可以将连接数调高 worker_processes * 1024
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
charset 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; #对静态资源的处理比较有效
#tcp_nopush on; #如果做静态资源服务器可以打开
#tcp_nodeny on; #当nginx做动态的服务时可以选择打开
keepalive_timeout 65;
########
#Gzip module
gzip on; #文件压缩默认可以打开
gzip_disable "MSIE [1-6]\."; #对于有些浏览器不能识别压缩,需要过滤如ie6
gzip_http_version 1.1;
include /etc/nginx/conf.d/*.conf;
}