Nginx性能优化

发布于 29 天前  20 次阅读


一、性能优化概述

  1. 首先我们需要了解性能优化要考虑哪些方面
  2. 然后我们需要了解性能优化必要用到的压力测试工具ab
  3. 最后我们需要了解系统上有哪些注意和优化的点,以及nginx配置文件

1.安装压力测试工具

[root@web01 ~]#yum -y install  httpd-tools

2.使用压力测试工具

[root@web01 /code]#ab -c200 -n20000 http://127.0.0.1/index.html
This is ApacheBench, Version 2.3 <$Revision: 1874286 $>
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 2000 requests
Completed 4000 requests
Completed 6000 requests
Completed 8000 requests
Completed 10000 requests
Completed 12000 requests
Completed 14000 requests
Completed 16000 requests
Completed 18000 requests
Completed 20000 requests
Finished 20000 requests


Server Software:        nginx/1.26.1	#Nginx版本号
Server Hostname:        127.0.0.1		# 压测的主机名称
Server Port:            80				 # 网站的端口号

Document Path:          /index.html		# 压测的具体资源	
Document Length:        153 bytes		# 页面总大小

Concurrency Level:      200				# 并发数
Time taken for tests:   1.683 seconds	# 处理完成的时间
Complete requests:      20000			# 总共的请求数量
Failed requests:        0				# 失败
Non-2xx responses:      20000			
Total transferred:      6060000 bytes	# 总页面的大小 包含头部数据
HTML transferred:       3060000 bytes	# 页面的大小
Requests per second:    11881.01 [#/sec] (mean)		# 吞吐量
Time per request:       16.834 [ms] (mean)		# 用户平均请求等待时间
Time per request:       0.084 [ms] (mean, across all concurrent requests)
Transfer rate:          3515.57 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    6  61.9      2    1045
Processing:     3    9  18.7      8     429
Waiting:        0    8  18.6      7     428
Total:          7   16  64.9     11    1058

Percentage of the requests served within a certain time (ms)
  50%     11
  66%     11
  75%     12
  80%     12
  90%     12
  95%     13
  98%     15
  99%     21
 100%   1058 (longest request)

二、性能优化

1.文件句柄(进程打开文件最大数量)

[root@web01 ~]#tail -1 /etc/security/limits.conf 
* - nofile 65535

2.内核参数调优

让time_wait状态重用(端口复用)
net.ipv4.tcp_tw_reuse = 1 # 开启端口复用
net.ipv4.tcp_timestamps = 0 # 禁用时间戳
	
[root@web01 ~]#sysctl -p	#可以查看我们添加的内核参数
[root@web01 ~]#sysctl -a	 #可以查看所有内核参数

端口复用引发的故障https://www.cnblogs.com/larry-luo/p/15649168.html

3.代理服务使用长连接

通常nginx作为代理服务,负责转发用户的请求,那么在转发的过程中建议开启HTTP长连接,用于减少握手次数,降低

服务器损耗。

[root@lb ~]#vim /etc/nginx/conf.d/wp.conf 
upstream web {
        server 172.16.1.7:80;
        server 172.16.1.8:80;
        keepalive 16; 
}
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回传数据至缓冲区,代理边收边传返回给客户端
proxy_buffer_size 32k;
proxy_buffers 4 128k;

4.配置静态页面缓存

静态资源类型种类
浏览器渲染HTML、CSS、JS
图片文件JPEG、GIF、PNG
视频文件FLV、Mp4、AVI
其他文件TXT、DOC、PDF、…
[root@web01 /code]#vim /etc/nginx/conf.d/a.conf 
server {
        listen  80;
        server_name test.oldboy123.com;
        root /code;
        index index.html;

        location ~ .*\.(jpg|gif|png)$ {
        expires      7d;	#设置缓存7天
        }
}

新配置的页面不希望被用户缓存,希望用户每次请求都到源站

    location ~ .*\.(js|css|html)$ {
          add_header Cache-Control no-store;
          add_header Pragma no-cache;
      }

5.文件高效传输

sendfile 参数


vim nginx.conf
...
sendfile        on;
tcp_nopush     on;		# 大文件开启此配置
tcp_nodelay on;			# 小文件开启此位置
...

6.文件gzip压缩

[root@web01 /etc/nginx/conf.d]#vim a.conf 
server {
        listen  80;
        server_name test.oldboy.com;
        root /code;
        index index.html;

        location ~ .*\.(txt|xml|html|json|js|css)$ {
                gzip on;
                gzip_http_version 1.1;
                gzip_comp_level 5;	#压缩等级
                gzip_types text/plain application/json application/x-ja
vascript application/css application/xml text/javascript;
    }
}

[root@web01 /etc/nginx/conf.d]#cat /etc/services /etc/services > /code/1.txt
[root@web01 /code]#ll -hg
total 1.6M
-rw-r--r--  1 root 1.4M Dec 19 21:37 1.txt
drwxr-xr-x 13 www  4.0K Dec 18 21:18 admin
-rw-r--r--  1 root 184K Dec 11 22:25 dog.jpg
-rw-r--r--  1 root   10 Dec 19 19:31 index.html
drwxr-xr-x  5 www  4.0K Dec 18 20:50 wordpress
drwxr-xr-x 14 www  4.0K Dec 18 20:54 zhihu

7.防盗链

1.准备盗链的服务器 WEB01
[root@web01 conf.d]# cat test.conf 
server {
        listen 80;
        server_name test.oldboy.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>oldboy.com</title>
	</head>
	<body style="background-color:pink;">
		    <center><img src="http://web.oldboy.com/daolian.jpg"/></center>
	</body>
</html>
2.准备源站WEB02
[root@web02 /code]#cat /etc/nginx/conf.d/test.conf 
server {
	listen 80;
	server_name web.oldboy.com;
	root /code;
	index index.html;
}

上传一张图片到/code
[root@web02 /code]#ll daolian.jpg 
-rw-r--r-- 1 root root 66464 Dec 19 16:09 daolian.jpg

windows hosts解析
10.0.0.7  test.oldboy.com
10.0.0.8  web.oldboy.com
3.访问网站
4.在web02上配置防盗链
[root@web02 /code]#cat /etc/nginx/conf.d/test.conf 
server {
	listen 80;
	server_name web.oldboy.com;
	root /code;
	index index.html;

	location ~ .*\.(jpg|png|gif) {
        valid_referers none blocked *.oldboy.com;
        if ( $invalid_referer ) {
            return 403; # rewrite ^(.*)$ /d.png break; 友好显示其他的页面	在/code/下准备d.png的图片
        }	
}
}

以上配置含义表示,所有来自*.oldboy.com都可以访问到当前站点的图片,如果来源域名不在这个列表中,那么

$invalid_referer等于1**,在if语句中返回一个403个客户,这样用户便会看到一个403的页面**

8.跨域请求

什么是跨域访问,当我们通过浏览器访问a网站时,同时会利用到ajax或其他方式,同时也请求b网站,这样的话就出现了请求一个页面,使用了两个域名,这种方式对浏览器来说默认是禁止的。

那Nginx语序跨站访问与浏览器有什么关系呢,因为浏览器会读取Access-Control-Allow-Origin的头信息,如果服务

端允许,则浏览器不会进行拦截。

配置跨域文件

[root@web02 /code]#vim /etc/nginx/conf.d/test.conf 
server {
        listen 80;
        server_name s.oldboy.com;
        root /code;
        index index.html;

}

[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.oldboy.com",
        success: function(data) {
                alert("sucess 成功了!!!");
        },
        error: function() {
                alert("fail!!,跨不过去啊,不让进去啊,只能...!");
        }
        });
});
</script>
        <body>
                <h1>跨域访问测试</h1>
        </body>
</html>

在web01上配置允许跨域请求

[root@web01 /etc/nginx/conf.d]#vim a.conf 
server {
        listen 80;
        server_name test.oldboy.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,DE
LETE,OPTIONS;
        }
}

9.cpu亲和

CPU亲和(affinity)减少进程之间不断频繁切换,减少性能损耗,其实现原理是建CPU核心和Nginx工作进程绑定方式,把每个worker进程固定到对应的cpu上执行,减少切换CPU的cache miss,获得更好的性能。

[root@web01 ~]#lscpu | grep "CPU(s)"	#查看服务器cup核心数
CPU(s):                          4
On-line CPU(s) list:             0-3
NUMA node0 CPU(s):               0-3

nginx进程默认的是随机的绑定方式,有的CPU会非常繁忙,有的CPU闲置状态
[root@web01 ~]#ps -eo pid,args,psr|grep [n]ginx
  67927 nginx: master process /usr/   1
  67928 nginx: worker process         2
  67929 nginx: worker process         0
  67930 nginx: worker process         3
  67931 nginx: worker process         3

开启cpu亲和
[root@web01 ~]#head -4 /etc/nginx/nginx.conf

user  www;
worker_processes  auto;
worker_cpu_affinity auto; 		# 开启CPU的亲和
[root@web01 ~]#systemctl restart nginx 	#重启生效

[root@web01 ~]# ps -eo pid,args,psr|grep [n]ginx
  67974 nginx: master process /usr/   3
  67975 nginx: worker process         0
  67976 nginx: worker process         1
  67977 nginx: worker process         2
  67978 nginx: worker process         3

三、通用优化配置

[root@nginx ~]# cat nginx.conf
user www; # nginx进程启动用户
worker_processes auto; #与cpu核心一致即可
worker_cpu_affinity auto; # cpu亲和
error_log /var/log/nginx/error.log warn; # 错误日志
pid /run/nginx.pid;
worker_rlimit_nofile 35535; #每个work能打开的文件描述符,调整至1w以上,负荷较高建议2-3w
events {
use epoll; # 使用epoll高效网络模型
worker_connections 10240; # 限制每个进程能处理多少个连接,10240x[cpu核心]
}
http {
include mime.types;
default_type application/octet-stream;
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"';
#定义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 main; # 访问日志
server_tokens off; # 禁止浏览器显示nginx版本号
client_max_body_size 200m; # 文件上传大小限制调整
2024/12/19 12:26 Nginx性能优化
sendfile on;
tcp_nopush on;
# 文件实时传输,动态资源服务建议打开,需要打开keepalive
tcp_nodelay on;
keepalive_timeout 65;
# Gzip 压缩
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字节才进行压缩,默认值20
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;
}

四、总结

面试题: Nginx优化过哪些内容
1、CPU亲和、worker进程数、调整每个worker进程打开的文件数 # 必做

2、使用额pool网络模型、调整每个worker进程的最大连接数  默认是1024  # 必做

3、文件的高效读取sendfile、nopush  # 看需求

4、文件的传输实时性、nodealy		  # 看需求

5、开启tcp长连接,以及长连接超时时间keepalived # 配置如果有负载均衡

6、开启文件传输压缩gzip				# 看需求

7、开启静态文件expires缓存			# 看需求 静态文件缓存天数 N年

8、隐藏nginx版本号				  # 必做

9、禁止通过ip地址访问,禁止恶意域名解析,只允许域名访问	# 必做 空的主机头部 用IP地址访问业务

10、配置防盗链、以及跨域访问			# 看需求

11、防DDOS、cc攻击,限制单IP并发连接,以及http请求	# 看需求

12、优雅显示nginx错误页面		   # 看需求

13、nginx加密传输https优化		    # 必做
小棱
最后更新于 2024-12-24