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 提供了一种高效的文件传输方式,减少了数据拷贝和上下文切换
  • nopushtcp_nopushTCP_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错误页面
posted @ 2025-03-21 08:55  丁志岩  阅读(34)  评论(0)    收藏  举报