kylin-Nginx性能优化
Nginx性能优化
一、压力测试工具
在系统业务量没有增长之前,我们就要做好相应的准备工作,以防患业务量突增带来的接口压力,所以对于接口压力测试就显得非常重要了,我们首先要评估好系统压力,然后使用工具检测当前系统情况,是否能满足对应压力的需求
1.安装
[root@lb01 ~]# yum -y install httpd-tools
2.压力测试命令的使用
[root@web01 ~]# ab -n 200 -c 2 http://127.0.0.1/
#-n 要执行的请求数
#-c 请求的并发数
#-k 是否开启长连接
#执行结果说明
[root@web01 ~]# ab -n20000 -c200 http://127.0.0.1/index.html
Server Software: nginx/1.26.1 # Nginx版本号
Server Hostname: 127.0.0.1 # 压测的主机名称
Server Port: 80 # 网站的端口号
Document Path: /index.html # 压测的具体资源
Document Length: 9 bytes # 页面总大小
Concurrency Level: 200 # 并发数
Time taken for tests: 1.498 seconds # 处理完成的时间
Complete requests: 20000 # 总共的请求数量
Failed requests: 0 # 失败
Total transferred: 5140000 bytes # 总页面的大小 包含头部数据
HTML transferred: 180000 bytes # 页面的大小
Requests per second: 13352.94 [#/sec] (mean) # 吞吐量
Time per request: 14.978 [ms] (mean) # 用户平均请求等待时间
Time per request: 0.075 [ms] (mean, across all concurrent requests) #服务器平均请求等待时间
Transfer rate: 3351.28 [Kbytes/sec] received
#表示这些请求在单位时间内从服务器获取的数据长度
Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 7 25.0 3 1050
Processing: 0 6 13.6 4 216
Waiting: 0 5 12.6 3 215
Total: 0 14 28.8 8 1061
Percentage of the requests served within a certain time (ms)
50% 8
66% 11
75% 12
80% 14
90% 19
95% 37
98% 108
99% 119
100% 1061 (longest request)
二、系统性能优化
1.文件句柄(文件描述符)
- 进程打开文件最大数量
[root@web01 ~]# tail -1 /etc/security/limits.conf
* - nofile 65535
2.调整内核参数(端口重用)
- 让time_wait状态重用(端口重用)
#开启端口复用
[root@web01 ~]# tail -2 /etc/sysctl.conf
net.ipv4.tcp_tw_reuse=1 # 开启端口复用
net.ipv4.tcp_timestamps=0 # 禁用时间戳
#查看内核参数
[root@web01 ROOT]# sysctl -p #可以查看我们添加的内核参数
[root@web01 ROOT]# sysctl -a #可以查看所有内核参数
#端口复用引发的故障
https://www.cnblogs.com/larry-luo/p/15649168.html
3.Nginx处理事务模型epoll
在主配置文件,事件块中配置
events {
worker_connections 1024;
use epoll; #通常默认就是epoll
}
三、代理服务优化(使用长连接)keepalive
- 通常nginx作为代理服务,负责转发用户的请求,那么在转发的过程中建议开启HTTP长连接,用于减少握手次数,降低服务器损耗。
1.配置nginx代理服务使用长连接方式
#配置nginx代理服务使用长连接方式Nginx与客户端之间的长连接
upstream http_backend {
server 127.0.0.1:8080;
keepalive 16; #长连接
}
server {
...
location /http/ {
proxy_pass http://http_backend;
proxy_http_version 1.1; #对于http协议应该指定为1.1
proxy_set_header Connection ""; #清除“connection”头字段
proxy_next_upstream error timeout http_500 http_502 http_503 http_504; #平滑过渡
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwared-For $proxy_add_x_forwarded_for;
proxy_connect_timeout 30s; # 代理连接web超时时间
proxy_read_timeout 60s; # 代理等待web响应超时时间
proxy_send_timeout 60s; # web回传数据至代理超时时间
proxy_buffering on; # 开启代理缓冲区,web回传数据至缓冲区,代理边收边传返回给客户端
}
}
2.对于fastcgi服务器,需要设置fastcgi_keep_conn以便保持长连接
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;
fastcgi_keep_conn on;
fastcgi_connect_timeout 60s;
include fastcgi_params;
……
}
}
四、静态资源优化(缓存)
- 静态资源指的是非WEB服务器端运行处理而生成的文件
1.配置静态页面缓存expires
[root@web01 conf.d]# cat test.conf
server {
listen 80;
server_name test.dezyan.com;
root /code;
location / {
index index.html;
}
location ~ .*\.(jpg|gif|png)$ {
expires 7d;
#设置响应头Expires,告诉客户端这些类型的文件可以被缓存7天。这意味着客户端在7天内再次请求相同的图片时,可以直接从本地缓存中读取,而不需要再次从服务器获取。
}
}
2.新配置的页面不希望被用户缓存,希望用户每次请求都到源站
location ~ .*\.(js|css|html)$ {
add_header Cache-Control no-store;
add_header Pragma no-cache;
}
五、文件高效传输sendfile、nopush
sendfile提供了一种高效的文件传输方式,减少了数据拷贝和上下文切换nopush(tcp_nopush或TCP_CORK)则通过减少网络包的数量来提高传输效率。两者结合使用可以显著提升文件传输的性能- 可用在http, server, location中
vim nginx.conf
...
sendfile on;
tcp_nopush on; # 大文件开启此配置
tcp_nodelay on; # 小文件开启此位置
...
六、静态资源压缩gzip
- Nginx将响应报文发送至客户端之前启用压缩功能,然后进行传输,这能够有效地节约带宽,并提高响应至客户端的速度.
- gzip_comp_level有1~9级,级别越高,对CPU的负载要求便越高,压缩比越高,速度越慢
location ~ .*\.(txt|xml|html|json|js|css)$ {
gzip on; #启用Gzip压缩
gzip_http_version 1.1; #指定Nginx使用HTTP/1.1协议进行Gzip压缩
gzip_comp_level 5; #设置Gzip压缩级别
#定义了Nginx应该应用Gzip压缩的MIME类型
gzip_types text/plain application/json application/x-javascript application/css application/xml text/javascript;
}
七、防止资源盗链
- 防盗链,指的是防止资源被其他网站恶意盗用。
- 基础防盗链设置思路:主要是针对客户端请求过程中所携带的一些Header信息来验证请求的合法性,比如客户端在请求的过程中都会携带referer信息。
- 优点是规则简单,配置和使用都很方便,缺点是防盗链所依赖的Referer验证信息是可以伪造的,所以通过referer信息防盗链并非100%可靠,但是他能够限制大部分的盗链情况。
盗取配置示例
- 准备盗链的服务器web01
root@web01 conf.d]# cat test.conf
server {
listen 80;
server_name test.dezyan.com;
root /code;
location / {
index index.html;
}
location ~ .*\.(jpg|png|gif) {
gzip on;
gzip_types image/jpeg image/gif image/png;
gzip_comp_level 9;
gzip_http_version 1.1;
}
}
- 编写盗链前端页
[root@web01 conf.d]# cat /code/index.html
<html>
<head>
<meta charset="utf-8">
<title>dezyan.com</title>
</head>
<body style="background-color:pink;">
<center><img src="http://web.dezyan.com/daolian.jpg"/></center>
</body>
</html>
- 准备源站web02(web01要盗取的)
[root@web02 conf.d]# cat d.conf
server {
listen 80;
server_name web.dezyan.com;
root /code;
location / {
index index.html;
}
}
上传一张图片到/code
[root@web02 code]# ll daolian.jpg
-rw-r--r-- 1 root root 438692 Dec 19 11:33 daolian.jpg
windows hosts解析
10.0.0.7 test.dezyan.com
10.0.0.8 web.dezyan.com
- 访问网站测试,盗取成功
配置防盗链
- 在web02上配置防止盗链
[root@web02 conf.d]# cat d.conf
server {
listen 80;
server_name web.dezyan.com;
root /code;
location / {
index index.html;
}
location ~ .*\.(jpg|png|gif) {
#允许baidu.com引用
valid_referers none blocked *.baidu.com;
if ( $invalid_referer ) {
return 403;
}
}
}
- 设置多个允许的域名
location ~ .*\.(jpg|png|gif) {
root /data;
valid_referers none blocked *.dezyan.com server_name ~\.google\. ~\.baidu\.;
if ( $invalid_referer ) {
return 403;
}
}
###
none:表示不设置默认的有效引用页。
blocked:表示如果引用页无效,则请求将被阻止。
*.dezyan.com:表示任何.dezyan.com域下的子域都是有效的引用页。
server_name:表示当前服务器的域名也是有效的引用页。
~\.google\. 和 ~\.baidu\.:表示任何以.google.或.baidu.结尾的域名都是有效的引用页。这里的波浪线~表示正则表达式匹配,点.需要转义。
- 被禁止的域名引用我的图片,设置指定返回页面或者图片 或者html页面
[root@web02 conf.d]# cat d.conf
server {
listen 80;
server_name web.dezyan.com;
root /code;
location / {
index index.html;
}
location ~ .*\.(jpg|png|gif) {
valid_referers none blocked *.baidu.com;
if ( $invalid_referer ) {
#return 403;
rewrite ^(.*)$ /d.png break; # 在/code/下准备d.png的图片
}
}
}
八、允许跨域访问
- 什么是跨域访问,当我们通过浏览器访问a网站时,同时会利用到ajax或其他方式,同时也请求b网站,这样的话就出现了请求一个页面,使用了两个域名,这种方式对浏览器来说默认是禁止的。
1.测试默认禁止的情况
1.配置跨域文件
[root@web02 conf.d]# cat s.conf
server {
listen 80;
server_name s.dezyan.com;
location / {
root /code;
index index.html;
}
}
2.编写代码测试
[root@web02 conf.d]# cat /code/index.html
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>测试ajax和跨域访问</title>
<script src="http://libs.baidu.com/jquery/2.1.4/jquery.min.js"></script>
</head>
<script type="text/javascript">
$(document).ready(function(){
$.ajax({
type: "GET",
url: "http://test.dezyan.com",
success: function(data) {
alert("sucess 成功了!!!");
},
error: function() {
alert("fail!!,跨不过去啊,不让进去啊,只能...!");
}
});
});
</script>
<body>
<h1>跨域访问测试</h1>
</body>
</html>
4.windows 解析
10.0.0.8 s.dezyan.com
10.0.0.7 test.dezyan.com
5.直接访问测试
s.dezyan.com
会显示 fail!!,跨不过去啊,不让进去啊,只能...!
2.配置允许跨域请求
[root@web01 conf.d]# cat test.conf
server {
listen 80;
server_name test.dezyan.com;
root /code;
location / {
index index.html;
}
location ~ .*\.(html|htm)$ {
add_header Access-Control-Allow-Origin *;
add_header Access-Control-Allow-Methods GET,POST,PUT,DELETE,OPTIONS;
}
}
此时再访问s.dezyan.com
会显示 sucess 成功了!!!
九、CPU亲和配置
-
CPU亲和(affinity)减少进程之间不断频繁切换,减少性能损耗,其实现原理是建CPU核心和Nginx工作进程绑定方式,把每个worker进程固定到对应的cpu上执行,减少切换CPU的cache miss,获得更好的性能。
-
nginx进程默认的是随机的绑定方式,有的CPU会非常繁忙,有的CPU闲置状态
1.查看进程在哪个cpu上运行
[root@web01 conf.d]# lscpu | grep "CPU(s)"
CPU(s): 4
On-line CPU(s) list: 0-3
NUMA node0 CPU(s): 0-3
[root@web01 conf.d]# ps -eo pid,args,psr|grep [n]ginx
4002 nginx: master process /usr/ 0
4003 nginx: worker process 2
4004 nginx: worker process 3
4005 nginx: worker process 3
4006 nginx: worker process 1
2.在主配置文件中开启CPU的亲和
[root@web01 nginx]# head -4 nginx.conf
user www;
worker_processes auto;
worker_cpu_affinity auto; # 开启CPU的亲和
#查看核心的绑定状态
[root@web01 nginx]# ps -eo pid,args,psr|grep [n]ginx
4224 nginx: master process /usr/ 3
4225 nginx: worker process 0
4226 nginx: worker process 1
4227 nginx: worker process 2
4228 nginx: worker process 3
十、隐藏nginx版本号
在主配置文件,http模块中添加
server_tokens off;
十一、禁止通过ip地址访问;防止恶意域名解析;只允许域名访问
1.禁止通过IP地址访问:
可以直接设置一个默认的server区块,用于拦截所有直接通过IP地址发起的请求,并返回403禁止访问的状态码;
server {
listen 80 default;
return 403;
}
2.防止恶意域名解析
为了防止恶意域名解析,你可以在Nginx配置中设置一个默认的server块,用于拦截所有未知域名的请求,并返回一个错误状态码,如444(非标准状态码,用于关闭连接而不返回任何信息)或500(服务器内部错误)。
server {
listen 80 default_server;
server_name _;
return 444;
}
server {
listen 443 default_server;
server_name _;
ssl on;
return 444;
}
十二、面试题: Nginx优化过哪些内容
1.必做优化
1、CPU亲和、调整文件句柄(文件描述符)
2、事件模块配置使用epoll网络模型、调整每个worker进程的最大连接数为10240
3、开启tcp长连接,以及长连接超时时间。keepalived(有负载均衡需配置)
4、隐藏nginx版本号
5、禁止通过ip地址访问,禁止恶意域名解析,只允许域名访问
6、nginx加密传输https优化(自动将HTTP请求重定向到HTTPS即负载上设置80端转443端)
2.看需求再优化
1、文件的高效读取sendfile、nopush
2、文件的传输实时性nodealy
3、开启文件传输压缩gzip
4、开启静态文件expires缓存
5、配置防盗链、以及跨域访问
6、防DDOS、cc攻击,限制单IP并发连接,以及http请求
7、优雅显示nginx错误页面
本文来自博客园,作者:丁志岩,转载请注明原文链接:https://www.cnblogs.com/dezyan/p/18784461

浙公网安备 33010602011771号