性能优化概述
基于Nginx性能优化,那么在性能优化这一章,我们将分为如下几个方面做介绍
- 首先,我们需要了解性能优化要考虑哪些方面。
- 然后我们需要了解性能优化必须要用到的压力测试工具ab。
- 最后我需要了解系统上有哪些注意和优化的点,以及Nginx配置文件做哪些调整。
我们在性能优化工作前,我们重点需要考虑哪些方面,和了解哪些方面
- 首先需要了解我们当前系统结构和瓶颈,了解当前使用的是什么,运行的是什么业务,都有哪些服务,了解每个服务最大能支撑多大的并发,比如Nginx作为静态资源服务的并发是多少,最高的瓶颈在哪里,能支持多少pqs(每秒查询率)的访问请求等,也可以通过日志去分析请求的情况,当然也可以通过我们前面介绍到的stub_status模块查看当前的连接情况,也可以对线上的业务进行压力测试(低峰期),去了解当前这套系统能承担多少的请求和并发,已做好相应的评估,这个是我们做性能优化最先考虑的地方。
- 其次我们需要了解业务模式。虽然我们是做性能优化,但每一个优化都是为了业务所提供服务的,我们需要了解每个业务接口的类型,比如:电商网站中的抢购模式,这种情况下面,平时没什么流量,但到了抢购时间流量会突增。
我们还需要了解系统层次化的结构,比如 : 我们使用Nginx做的是代理,还是动静分离,还是后端直接服务用户,那么这个就需要我们对每一层做好相应的梳理。以便更好的服务业务。 - 最后我们需要考虑性能与安全,往往注重了性能,但是忽略了安全。往往过于注重安全,性能又会产生影响。比如 : 我们在设计防火墙功能时,检查过于严密,这样就会给性能带来影响。那么如果对于性能完全追求,却不顾服务的安全,这个也会造成很大的隐患,所以需要评估好两者的关系,把握好两者的孰重孰轻。以及整体的相关性,权衡好对应的点。
从OSI七层模型去考虑
硬件: 代理(cpu),静态(磁盘空间、IO),动态(cpu、内存)
网络: 网络是否有延迟,网卡是否有丢包
系统: 文件句柄(文件描述符)
应用: 服务与服务之间保持长连接 http1.1(开启长链接会占用端口,状态会变成TIME_WAIT) # netstat -an命令查看端口号状态
服务: Nginx静态资源服务优化
压力测试工具ab
在系统业务量没有增长之前,我们就要做好相应的准备工作,已防患业务量徒增带来的接口压力,所以对于接口压力测试就显得非常重要了。我们首先要评估好系统压力,然后是由工具检查当前系统情况,是否能满足对压力的需求。
静态资源压力测试
- 创建静态资源数据
- web01服务器
1. 修改Nginx配置文件
vim /etc/nginx/conf.d/try.conf
server {
listen 80;
server name _;
location / {
root /code;
try_files $uri @java; # $uri,输入192.168.15.7/tt.html,可以正常访问到数据 否则返回@java的数据
}
location @java {
proxy_pass http://127.0.0.1:8080; # 本地回环地址tomcat(端口号8080)
}
}
2. 创建Nginx配置文件指定的数据文件
echo "nginx ab" > /code/tt.html
3. 重启Nginx服务
systemctl restart nginx
- ab工具进行压力测试
1. 安装ab压力测试工具
yum install httpd-tools
2. ab命令使用格式及其常用的参数
ab -n10000 -c200 http://127.0.0.1/tt.html/
-n : 总的请求数
-c : 同时并发的请求数
-k : 开启长连接(http1.1)
This is ApacheBench, Version 2.3 <$Revision: 1430300 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/
Benchmarking 127.0.0.1 (be patient)
Completed 1000 requests
Completed 2000 requests
Completed 3000 requests
Completed 4000 requests
Completed 5000 requests
Completed 6000 requests
Completed 7000 requests
Completed 8000 requests
Completed 9000 requests
Completed 10000 requests
Finished 10000 requests
Server Software: nginx/1.20.0 Nginx版本
Server Hostname: 127.0.0.1 主机
Server Port: 80 端口
Document Path: /tt.html/ 路径
Document Length: 157 bytes 字节
Concurrency Level: 200 并发数200
Time taken for tests: 1.999 seconds 请求的总时间
Complete requests: 10000 总请求
Failed requests: 0 失败的请求
Write errors: 0
Non-2xx responses: 10000
Total transferred: 3090000 bytes 所以请求总共占用的字节
HTML transferred: 1570000 bytes 传输的字节
Requests per second: 5001.76 [#/sec] (mean) qps每秒能处理多少请求(这个参数是重点!!!)
Time per request: 39.986 [ms] (mean) 客户端请求服务端的时间(毫秒)
Time per request: 0.200 [ms] (mean, across all concurrent requests) 服务端每个请求处理的时间(毫秒)
Transfer rate: 1509.32 [Kbytes/sec] received 传输的速率(网络问题)
Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 10 82.9 3 1005
Processing: 5 23 9.9 19 225
Waiting: 1 20 10.5 16 224
Total: 5 33 83.0 23 1039
Percentage of the requests served within a certain time (ms)
50% 23
66% 31
75% 33
80% 34
90% 36
95% 38
98% 40
99% 42
100% 1039 (longest request)
动态资源压力测试
1. 下载tomcat软件包
wget https://mirrors.bfsu.edu.cn/apache/tomcat/tomcat-10/v10.0.6/bin/apache-tomcat-10.0.6.tar.gz
2. 解压tomcat软件包
tar -xf apache-tomcat-10.0.6.tar.gz
3. 创建tomcat动态资源
cd apache-tomcat-10.0.6/webapps/ROOT/
mv /code/tt.html ./
4. 启动tomcat程序
yum -y install java
cd /root/apache-tomcat-10.0.6/
./bin/startup.sh 启动tomcat服务
netstat -lntp 查看tomcat端口号
# tcp6 0 0 127.0.0.1:8005 :::* LISTEN 1890/java 关闭端口
# tcp6 0 0 :::8080 :::* LISTEN 1890/java 对外提供访问的端口
5. 进行ab压力测试
ab -n10000 -c200 http://127.0.0.1/tt.html/
Requests per second: 1033.30 [#/sec] (mean) qps每秒能处理多少请求(这个参数是重点!!!)
- 测试结果
我们很明显的可以感受到Nginx处理静态资源的速度明显比tomcat处理动态资源的速度要快很多
所以我们通常会用tomcat解析专门的jsp文件,Nginx通常会用来处理静态资源
了解影响性能指标
- 网络
- 网络的流量
- 网络是否丢包
- 这些会影响http的请求与调用
- 系统
- 硬件有没有磁盘损坏,磁盘速率
- 系统负载、内存、系统稳定性
- 服务
- 连接优化、请求优化
- 根据业务形态做对应的服务设置
- 程序
- 接口性能
- 处理速度
- 程序执行效率
- 数据库
- 每个服务与服务之间都或多或少有一些关联,我们需要将整个架构进行分层,找到对应系统或服务的短板,然后进行优化
系统性能优化
文件句柄,linux一切皆文件,文件句柄可以理解为就是一个索引,文件句柄会随着我们进程的调用频繁增加,系统默认文件句柄是有限制的,不能让一个进程无限的调用,所以我们需要限制每一个进程和每个服务使用多大的文件句柄,文件句柄也是必须要调整的优化参数。
文件句柄的设置方式,1.系统全局性修改。 2.用户局部性修改。 3.进程局部性修改。
- 系统层面必须要调整
查看系统设置的最大文件句柄
ulimit -n
# 65535
修改系统设置的文件句柄大小的配置文件
vim /etc/security/limits.conf
1. 系统全局性修改
# * -代表所有
* - nofile 65535
# *代表所有用户
* soft nofile 65536
* hard nofile 65536
2. 用户局部性修改
# 争对root用户,soft仅提醒,hard限制,nofile打开最大文件数
root soft nofile 65536
root hard nofile 65536
3. 进程局部性修改
vim /etc/nginx/nginx.conf
# 针对Nginx进程
worker_rlimit_nofile 65536;
使用lsof命令查看进程占用了多少个文件句柄
ps aux | grep nginx
# root 1718 0.0 0.0 46504 988 ? Ss 11:26 0:00 nginx: master process /usr/sbin/nginx -c /etc/nginx/nginx.conf
yum -y install lsof
lsof -p 1718 | wc -l # lsof -p 查看Nginx进程占用了多少个文件句柄
# 32
- 调整内核参数: 让time_wait状态重用(让占用的端口复用)
vim /etc/sysctl.conf
net.ipv4.tcp_tw_reuse = 1 # 让占用的端口复用
net.ipv4.tcp_timestamps = 1 # 时间戳
查看自定义设置的内核参数
sysctl -p
查看系统所有的内核参数
sysctl -a
Nginx代理服务优化
通常Nginx作为代理服务,负责转发用户的请求,那么在转发的过程中建议开启HTTP长连接,用户减少握手的次数,降低服务器损耗。
1. 配置Nginx代理服务使用长连接方式keepalive connections(应用层面优化)
vim /etc/nginx/conf.d/proxy.conf
upstream test {
server 172.16.1.8:80;
keepalive 32; # 长连接
keepalived_requests 100; # 设置通过一个keepalive连接提供的最大请求数100。在发出最大请求数后,将关闭连接。
keepalive_timeout 60s; # 设置超时,webserver在处理完一个请求后保持这个TCP连接的打开状态。指定每个TCP连接最多可以保持多长时间。
}
server {
...
location /http/ {
proxy_pass http://http_backend;
proxy_http_version 1.1; # 对于http协议应该指定为1.1
proxy_set_header Connection ""; # 清除"connection"头字段 , Connection: keep-alive
proxy_set_header Host $http_host; # 代理服务器匹配请求web01服务器的时候,默认加上Host头信息(域名)
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # 追加客户端ip地址以及全链路ip地址到web服务器记录日志
proxy_next_upstream error timeout http_500 http_502 http_503 http_504;
# 当Nginx虚拟服务池其中任意一台服务器返回错误码500,502,503,504等错误时,可以分配到下一台服务器程序继续处理,提高平台访问的成功率
proxy_connect_timeout 60s; # nginx代理与后端服务器连接超时时间(代理连接超时)
proxy_read_timeout 60s; # nginx代理等待后端服务器的响应时间(代理响应超时)
proxy_send_timeout 60s; # 后端服务器数据回传给nginx代理超时时间(回传数据给代理超时)
proxy_buffering on; # nginx会把后端返回的内容先放到缓冲区中,然后再返回给客户端,边收边传,不是全部接收再传给客户端
proxy_buffers_size 4k; # 设置nginx代理保存用户头信息的缓存区大小
proxy_buffers 8 8k; # 设置nginx代理缓冲区大小(8*8 = 64k)
...
}
}
2. 对于fastcgi服务器,需要设置fastcgi_keep_conn以便保持长连接
vim /etc/nginx/conf.d/zh.nana.com.conf
upstream fastcgi_backend {
server 127.0.0.1:9000;
keepalive 8; # 长连接
}
server {
...
location /fastcgi/ {
fastcgi_pass fastcgi_backend;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
# 需要解析的文件都会传给变量名SCRIPT_FILENAME,php服务端会读取该变量,解析变量里面的文件内容,解析完成再传给Nginx。
fastcgi_keep_conn on; # 开启php长连接
fastcgi_connect_timeout 60s; # 连接超时时间
include fastcgi_params;
...
}
}
注意:
- scgi和uwsgi协议没有保持长连接的概念
- 无论是proxy、fastcgi、uwsgi协议都有cache缓存的功能,开启后可加速网站访问的效率。(考虑硬件)
静态资源优化
Nginx作为静态资源web服务器,用于静态资源处理,传输非常的高效。
静态资源指的是,非Web服务器端运行处理而生成的文件
静态资源类型 | 种类
浏览器渲染 | html、css、js
图片文件 | jpeg、gif、png
视频文件 | flv、Mp4、avi
其他文件 | txt、doc、pd
1. 静态资源缓存
浏览器缓存设置用于提高网站性能,尤其是新闻网站,图片一旦发布,改动的可能是非常小的。所以我们希望能否用户访问一次后,图片缓存在用户的浏览器长时间缓存。
浏览器是有自己的缓存机制,它是基于HTTP协议缓存机制来实现的,在HTTP协议中有很多头信息,那么实现浏览器的缓存就需要依赖特殊的头信息来与服务器进行特殊的验证,如:Expires(http/1.0);Cache-control(http/1.1)。
- 浏览器无缓存
- 浏览器有缓存
浏览器缓存过期校验检查机制,原理如下:
- 浏览器请求服务器会先进行Expires、Cache-Control的检查,检查缓存是否过期,如果没有过期则直接从缓存文件中读取。
- 如果缓存过期,首先检查是否存在Etag(类似于md5进行加密的一个值,用于校验数据有没有发生变化),如果存在则会客户端会向web服务器请求If-None-Match,与Etag值进行比对,由服务器决策返回200还是304。
- 如果Etag不存在,则进行Last-Modified(文件最后修改时间)检查,客户端会向Web服务器请求If-Modified-Since,与Last-modified进行比对,由服务器决策返回200还是304。
1.1 设置文件缓存时间(响应码304)
1. 修改Nginx配置文件
vim /etc/nginx/conf.d/try.conf
server {
listen 80;
server_name _;
root /code;
location / {
index index.html;
}
location ~ \.*(png|jpg|gif|jpeg)$ {
expires 1d; # 设置静态资源缓存时间为1天
add_header test $host; # 添加头信息
}
}
2. 重启Nginx服务
systemctl restart nginx
1.2 设置静态文件不被缓存(响应码200)
1. 修改Nginx配置文件
vim /etc/nginx/conf.d/try.conf
server {
listen 80;
server_name _;
root /code;
location / {
index index.html;
}
location ~ \.*(png|jpg|gif|jpeg)$ {
add_header test $host;
add_header Cache-Control no-store;
add_header Pragma no-cache;
}
}
2. 重启Nginx服务
systemctl restart nginx
2. 静态文件资源读取
传统文件读取方式:硬件--->内核--->用户空间--->程序空间--->程序内核空间--->套接字服务
。
开启sendfile服务后:硬件--->内核--->程序内核空间--->套接字服务
。
开启sendfile服务
- Nginx主配置文件(默认开启sendfile)
vim /etc/nginx/nginx.conf
...
sendfile on;
...
将多个包一次性发送,用户提升网络传输效率,大文件推荐打开,需要先开启sendfile才行
- Nginx主配置文件
vim /etc/nginx/nginx.conf
...
sendfile on;
tcp_nopush on;
...
提高网络传输实时性,需要开启keepalive(与tcp_nopush相反,不要同时打开)
- Nginx主配置文件
vim /etc/nginx/nginx.conf
...
tcp_nodelay on;
keepalive_timeout 65;
...
3. 静态资源压缩
Nginx将响应报文发送至客户端之前启用压缩功能,然后进行传输,这能够有效的节约宽带,并提高响应至客户端的速度。
gzip压缩传输,传输前压缩,传输后浏览器解压
1. 上传一张图片
cd /code
rz -E 40x.jpg
ll -h # 查看我们上传至服务器图片的大小21K
# -rw-r--r-- 1 root root 21K Apr 3 22:12 40x.jpg
2. 查看压缩类型的文件
vim /etc/nginx/mime.types
...
image/gif gif;
image/jpeg jpeg jpg;
image/png png;
...
3. 修改Nginx配置文件
vim /etc/nginx/conf.d/try.conf
server {
listen 80;
server_name _;
root /code;
location / {
index index.html;
}
# 压缩图片
location ~ \.*(png|jpg|gif|jpeg)$ {
gzip on; # 开启压缩功能
gzip_types image/jpeg image/gif image/png; # 压缩文件的类型
gzip_comp_level 9; # 压缩的等级(压缩等级越大,压缩的空间大小越大,9是最大等级)
gzip_http_version 1.1; # 压缩http的版本
}
# 压缩文件
location ~ \.*(txt|xml|html|js|css)$ {
gzip on; # 开启压缩功能
gzip_types text/plain text/html; # 压缩文件的类型
gzip_comp_level 9; # 压缩的等级(压缩等级越大,压缩的空间大小越大,9是最大等级)
gzip_http_version 1.1; # 压缩http的版本
}
}
4. 重启Nginx服务
systemctl restart nginx
测试
- 我们在浏览器输入192.168.15.7/40x.jpg,压缩后的文件大小为18.3kb。
4. 防止资源盗链
防盗链,指的是防止资源被其他网站恶意盗用,如图所示:
基础防盗链设置思路:主要是针对客户端请求过程中所携带的一些Header信息来验证请求的合法性,比如客户端在请求的过程中都会携带referer信息(referer会告诉服务器请求从哪一个页面过来的)。优点是规则简单,配合和使用都很方便,缺点是防盗链所依赖的Referer验证信息是可以伪造的(可以通过代码对上一个请求来源页面的域名进行修改),所以通过Referer信息防盗链并非100%可靠,但是它能够限制大部分盗链的情况。
1.在盗链服务器上准备html文件,偷取Web03服务器(nana.com)网站上的图片
- web01服务器
1. 修改Nginx配置文件
vim /etc/nginx/conf.d/dl.conf
server {
listen 80;
server_name dl.com;
root /code;
location / {
index index.html index.html;
}
}
2. 创建nginx数据文件
vim /code/referer_test.html
<html>
<head>
<meta charset="utf-8">
<title>lala.com</title>
</head>
<body style="background-color:red;">
<img src="http://nana.com/a.jpg">
</body>
<html>
2. 重启Nginx服务
systemctl restart nginx
在本机添加域名解析
C:\Windows\System32\drivers\etc
在hosts文件添加域名解析(注释掉本机其他ip与域名之间的对应关系)
192.168.15.7 dl.com
2.使用浏览器能正常访问到偷链的资源
- web03服务器
1. 创建Nginx数据文件
cd /code/
rz -E a.jpg
2. 修改Nginx配置文件
vim /etc/nginx/conf.d/nana.conf
server {
listen 80;
server_name nana.com;
root /code;
location / {
index index.html index.html;
}
}
3. 重启Nginx服务
systemctl restart nginx
在本机添加域名解析
C:\Windows\System32\drivers\etc
在hosts文件添加域名解析(注释掉本机其他ip与域名之间的对应关系)
192.168.15.9 nana.com
3.在web03服务器(nana.com)上配置防盗链(返回403或者是其他图片)
- Web03服务器
1. 创建Nginx数据文件
cd /code
rz -E b.jpg
2. 修改Nginx配置文件
vim /etc/nginx/conf.d/nana.conf
server {
listen 80;
server_name nana.com;
root /code;
location / {
index index.html index.html;
}
location ~ .*\.(jpg|jpeg|gif|png)$ {
# 指定合法的来源referer(上一个页面的来源的域名),匹配成功(*.nana.com)这个变量被设置为0,匹配失败设置为1
valid_referers none blcoked *.nana.com;
if ($invalid_referer) {
# return 403;
rewrite ^(.*)$ /b.jpg break;
}
}
}
2. 重启Nginx服务
systemctl restart nginx
以上配置含义表示,所有来自*.nana.com都可以访问到当前站点的图片,如果来源域名不在这个列表中,那么$invalid_referer等于1,
在if语句中返回一个/code/b.jpg给用户,这样用户便会看到一个b.jpg的图片页面。
4.设置某些网站能够使用(盗链)资源
- web03服务器
1. 修改Nginx配置文件
vim /etc/nginx/conf.d/nana.conf
server {
listen 80;
server_name nana.com;
root /code;
location / {
index index.html index.html;
}
location ~ .*\.(jpg|jpeg|gif|png)$ {
# server_names设置哪些网站能够使用(盗链)资源
valid_referers none blcoked *.nana.com server_names dl.com ~\.google\. ~\.baidu\.;
if ($invalid_referer) {
rewrite ^(.*)$ /b.jpg break;
}
}
}
2. 重启Nginx服务
systemctl restart nginx
5. 允许跨域访问
什么是跨站访问,当我们通过浏览器访问a网站时,同时会利用ajax或其他方式,同时也请求b网站,这样的话就出现了请求一个页面,使用2个域名,这种方式对浏览器来说默认是禁止。
那么Nginx允许跨站访问与浏览器有什么关系呢,因为浏览器会读取Access-Control-Allow-Origin
的头信息,如果服务端允许,则浏览器不会进行拦截。
1.模拟跨域访问问题
- Web01服务器
1. 修改Nginx配置文件
server {
listen 80;
server_name dl.com;
root /code;
location / {
index index.html index.html;
}
}
2. 配置Nginx数据文件
vim /code/http.html
<html lang="en">
<head>
<meta charset="UTF-8">
<title>测试ajax和跨域访问</title>
<script src="https://code.jquery.com/jquery-3.1.0.min.js"></script>
</head>
<script type="text/javascript">
$(document).ready(function() {
$.ajax({
type: "GET",
url: "http://nana.com/index.html",
success: function (data) {
alert("sucessful!!!");
},
error: function () {
alert("fail!!!,刷新后重试")
}
});
});
</script>
<body>
<h1>"测试跨域访问"</h1>
</body>
</html>
3. 重启Nginx服务
systemctl restart nginx
2.设置Nginx服务允许跨域访问
- Web03服务器
1. 修改Nginx配置文件
vim /etc/nginx/conf.d/nana.conf
server {
listen 80;
server_name nana.com;
root /code;
location / {
index index.html index.html;
# 添加header头信息Access-Control-Allow-Origin,*号允许所有的域名跨域访问
add_header Access-Control-Allow-Origin *;
}
location ~ .*\.(jpg|jpeg|gif|png)$ {
valid_referers none blcoked *.nana.com server_names dl.com;
if ($invalid_referer) {
rewrite ^(.*)$ /b.jpg break;
}
}
}
2. 重启Nginx服务
systemctl restart nginx
3.跨域访问测试
6. CPU亲和配置
CPU亲和(affinity)减少进程之间不断频繁切换,减少性能损耗,其实现原理是将CPU核心和Nginx工作进程绑定方式,把每个worker进程固定对应的CPU上执行,减少切换CPU和cache miss,获得更好的性能。
1.查看当前CPU物理状态
lscpu | grep "CPU(s)"
# CPU(s): 8 总的核心数
# On-line CPU(s) list: 0-7
# NUMA node0 CPU(s): 0-7
2.将Nginx worker进程绑至不同的核心上,官方建议与cpu的核心保持一致
最佳绑定方式
1. 修改Nginx主配置文件
vim /etc/nginx/nginx.conf
...
worker_processes auto; # Nginx启动的worker进程为自动
worker_cpu_affinity auto; # 开启cpu亲和
...
3.查看nginx worker
进程绑定至对应的cpu
ps -eo pid,args,psr | grep [n]ginx # 查看Nginx进程绑定至对应的cpu
# 1851 nginx: master process /usr/ 1
# 1852 nginx: worker process 0
# 1853 nginx: worker process 1
# 1854 nginx: worker process 2
# 1855 nginx: worker process 3
# 1856 nginx: worker process 4
# 1857 nginx: worker process 5
# 1858 nginx: worker process 6
# 1859 nginx: worker process 7
Nginx主配置文件通用配置
- Nginx主配置文件
vim /etc/nginx/nginx.conf
user nginx; # nginx进程运行的用户
worker_processes auto; # nginx工作的进程数量(辅助进程自动)
worker_cpu_affinity auto; # 开启cpu亲和
error_log /var/log/nginx/error.log notice; # nginx的错误日志[警告类型及其警告以上的都记录]
pid /var/run/nginx.pid; # nginx进程运行后的进程id
worker_rlimit_nofile 35535; # 每个worker能打开的文件描述符,调整至1W以上,负荷较高建议2-3W
events {
worker_connections 10240; # 一个work进程的最大连接数,10240×[cpu核心]
use epoll; # 使用epoll的网络模型
}
http {
include /etc/nginx/mime.types; # 包含资源类型文件
default_type application/octet-stream; # 默认以下载方式传输给浏览器(前提是该资源在/etc/nginx/mime.types中无法找到)
charset utf-8; # 统一使用utf-8字符集
# 定义日志格式
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main; # 访问日志
server_tokens off; # 禁止浏览器显示nginx版本号
client_max_body_size 200m; # 文件上传大小限制调整
# 文件高效传输,静态资源服务器建议打开
sendfile on;
tcp_nopush on;
# 文件实时传输,动态资源服务建议打开,需要打开keepalived
tcp_nodelay on;
keepalive_timeout 65; # 长连接的超时时间
# gizp 压缩
gzip on; # 开启压缩功能
gzip_disable "MSIE [1-6]\."; # 微软IE1-6版本不压缩
gzip_types text/plain text/html; # 压缩文件的类型
gzip_comp_level 9; # 压缩的等级(压缩等级越大,压缩的空间大小越大,9是最大等级)
gzip_http_version 1.1; # 压缩http的版本
# 虚拟主机
include /etc/nginx/conf.d/*.conf; # 包含目录下的*.conf文件
}
Nginx安全与优化总结
- cpu亲和、worker进程数、调整每个worker进程打开的文件数
- 使用epool网络模型、调整每个worker进程的最大连接数
- 文件的高效读取sendfile、nopush
- 文件的传输实时性、nodealy
- 开启tcp长链接、以及长链接的超时时间keepalive
- 开启文件传输压缩gzip
- 开启静态文件expires缓存
- 隐藏Nginx的版本号
- 禁止通过IP地址访问,禁止恶意域名解析,只允许域名访问
- 配置防盗链 ,以及跨域访问
- 防DDOS、cc攻击、限制单IP并发连接,以及http请求
- 优雅显示nginx错误页面
- nginx加密传输https优化
- Nginx proxy_cache、fastcgi_cache、uwsgi_cache缓存
PHP服务优化
1. 环境准备
1. 修改nginx配置文件
vim /etc/nginx/conf.d/php.conf
server {
listen 80;
server_name php.nana.com;
root /code;
location / {
index index.php index.html;
}
location ~ \.php$ {
fastcgi_pass 127.0.0.1:9000;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}
2. 创建Nginx数据文件
vim /code/test.php
<?php
phpinfo();
?>
3. 重启Nginx服务和php服务
systemctl restart nginx
systemctl restart php-fpm
- 访问测试
添加域名解析
192.168.15.7 php.nana.com
浏览器输入域名http://php.nana.com/test.php,可以正常访问到页面
2. PHP服务优化
- php程序配置管理文件/etc/php.ini,主要调整日志、文件上传、禁止危险函数、关闭版本号显示等
- php解析器配置文件
vim /etc/php.ini
...
# 错误日志设置
expose_php = off # 关闭php版本信息
display_errors = Off # 屏幕不显示错误日志
error_reporting = E_ALL # 记录PHP错误日志
log_errors = On # 开启错误日志
error_log = /var/log/php_errors.log # 错误日志写入的位置
date.timezone = Asia/Shanghai # 调整时区,默认PRC
# 文件上传设置
file_uploads = On # 允许文件上传
upload_max_filesize = 500M # 允许上传文件的最大大小
post_max_size = 300M # 允许客户端单个POST请求发送的最大数据
max_file_uploads = 20 # 允许同时上传的文件的最大数量
memory_limit = 128M # 每个脚本执行的最大内存
# session会话共享
session.save_handler = redis # 开启会话保持功能
session.save_path = "tcp://172.16.1.51:6379" # 建立tcp连接的服务器ip
# php禁止危险函数执行(根据实际情况,根据开发的需求进行禁用)
disable_functions = chown,chmod,phpinfo,pfsockopen
...
- php-fpm进程管理配置文件/etc/php-fpm.conf
- php-fpm进程管理配置文件
vim /etc/php-fpm.conf # 主配置文件
# 全局配置
[global]
pid = /var/run/php-fpm/php-fpm.pid # pid文件存放的位置
error_log = /var/log/php-fpm/error.log # 错误日志存放的位置
;log_level = error # 日志级别,alert,error,warning,notice,debug
;rlimit_files = 65535 # php-fpm进程能打开的文件数
;events.mechanism = epoll # 使用epoll事件模型处理请求
include=/etc/php-fpm.d/*.conf # 导入/etc/php-fpm.d/*.conf文件目录
vim /etc/php-fpm.d/www.conf
# 进程池定义
[www] # 池名称
user = www # 进程运行的用户
group = www # 进程运行的组
;listen = /dev/shm/php-fpm.sock # 监听在本地socket文件
listen = 127.0.0.1:9000 # 监听在本地tcp的9000端口
;listen.allowed_clients = 127.0.0.1 # 允许访问FastCGI进程的IP,any不限制
pm = dynamic # 动态调节php-fpm的进程数
pm.max_children = 512 # 最大启动的php-fpm进程数
pm.start_servers = 32 # 初始启用的php-fpm进程数
pm.min_spare_servers = 32 # 最少的空闲php-fpm进程数
pm.max_spare_servers = 64 # 最大的空闲php-fpm进程数
pm.process_idle_timeout = 15s; # 空闲进程超时时间
pm.max_requests = 500 # 每一个进程能响应的请求数
;pm.status_path = /status # 开启php的状态页面(需要设置Nginx服务的location /status)
# 日志相关
;php_flag[display_errors] = off # 是否在前端显示日志
php_admin_value[error_log] = /var/log/php-fpm/www-error.log # 进程日志记录的路径
php_admin_flag[log_errors] = on # 是否开启进程启动日志
# 慢日志
;request_slowlog_timeout = 5s # php脚本执行超过5s的文件
slowlog = /var/log/php-fpm/www-slow.log # 记录至该文件中
- 开启php状态页面
1. 修改php进程管理文件
vim /etc/php-fpm.d/www.conf
pm.status_path = /status
2. 修改Nginx服务的配置文件
vim /etc/nginx/conf.d/php.conf
server {
...
location /status {
fastcgi_pass 127.0.0.1:9000;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}
- 开启php状态页面后,我们在浏览器输入
http://php.nana.com/status
,页面内容如下所示
Nginx优化总结
Nginx
硬件层面 代理比较消耗CPU、内存 静态比较消耗磁盘IO
网络层面 网络带宽大小 、传输速率、是否有丢包
系统层面 调整文件描述 timewait重用
应用层面 Nginx作为代理 keepalive长连接
服务层面 Nginx作为静态 浏览器缓存、文件传输、压缩、防盗链、跨域访问、CUP亲和
Nginx作为缓存 proxy_cache fastcgi_cache uwsgi_cache
Nginx作为安全 Nginx+lua实现waf防火墙
PHP
php.ini 错误日志记录、文件大小的调整、session会话共享的配置、禁止不必要的函数(与开发协商)
php-fpm 监听地址、进程的动态调节、日志开启
php状态 php自身监控的状态信息
php慢查询 日志文件中记录了什么时间、什么进程、运行什么文件、哪个函数、第几行达到了超时时间
Nginx通用主配置文件优化终极版
user www; # nginx用户
worker_processes auto; # 自动根据CPU核心数启动worker数量
worker_cpu_affinity auto; #开启亲和性
error_log /var/log/nginx/error.log notice; # 错误日志
pid /var/run/nginx.pid; # 指定pid文件
worker_rlimit_nofile 35535; # nginx最大打开文件句柄数
events {
use epoll; # 使用epoll网络模型
worker_connections 10240; # 每个worker处理的连接数
}
http {
include /etc/nginx/mime.types; # nginx可识别的文件类型
default_type application/octet-stream; # nginx不认识的文件类型就默认下载
# 定义日志格式
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
# 定义json格式日志
log_format json_access '{"@timestamp":"$time_iso8601",'
'"host":"$server_addr",'
'"clientip":"$remote_addr",'
'"size":$body_bytes_sent,'
'"responsetime":$request_time,'
'"upstreamtime":"$upstream_response_time",'
'"upstreamhost":"$upstream_addr",'
'"http_host":"$host",'
'"url":"$uri",'
'"domain":"$host",'
'"xff":"$http_x_forwarded_for",'
'"referer":"$http_referer",'
'"status":"$status"}';
access_log /var/log/nginx/access.log json_access; # 访问日志
server_tokens off; # 关闭显示nginx版本
client_max_body_size 200m; # 文件上传大小限制
sendfile on; # 高效传输
tcp_nopush on; # 高效传输
keepalive_timeout 65; # 长连接
gzip on; # 开启压缩
gzip_disable "MSIE [1-6]\."; # 针对IE浏览器不进行压缩
gzip_http_version 1.1; # 压缩传输版本
gzip_comp_level 2; # 压缩的等级
gzip_buffers 16 8k; # 压缩的缓冲区
gzip_min_length 1024; # 最小1024字节才开始压缩
gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript image/jpeg; #压缩的文件类型
include /etc/nginx/conf.d/*.conf; # 虚拟主机配置文件
}