【运维知识进阶篇】集群架构-Nginx性能优化 (二)

本文涉及的产品
.cn 域名,1个 12个月
日志服务 SLS,月写入数据量 50GB 1个月
简介: 【运维知识进阶篇】集群架构-Nginx性能优化 (二)

四、静态资源优化

Nginx作为静态资源Web服务器,用于静态资源处理,传输非常的高效

静态资源指的是非Web服务器端运行处理而生成的文件

静态资源类型 种类
浏览器渲染 HTML、CSS、JS
图片文件 JPEG、GIF、PNG
视频文件 FLV、MP4、AVI
其他文件 TXT、DOC、PDF

1、 静态资源缓存expires

浏览器缓存设置用于提高网站性能,像新闻网站,图片一旦发布,改动的可能是非常小的,所以我们希望用户访问一次后,图片缓存在用户的浏览器上。 浏览器是有自己的缓存机制,他是基于HTTP协议缓存机制来实现的,在HTTP协议中有很多头信息,那么实现浏览器的缓存就需要依赖特殊的头信息来与服务器进行特殊的验证,如Expires(http/1.0);Cache-control(http/1.1)。

浏览器缓存过期校验机制

浏览器发送请求,检测浏览器中有缓存,检测是否过期,没有过期就从缓存中直接读取,返回给浏览器;

过期了检查有无Etag,没有的话检查有无last-Modified,没有的话向web服务器发送请求,Web服务器请求后端,缓存协商再返回给浏览器,有last-Modified则向Web服务器请求if-Modified-Since,由服务器决策,返回200或304,200则请求后端,进行缓存协商,304则直接返回给浏览器;

如果有Etag,则向Web服务器请求If-None-Match,由服务器决策,返回200或304,200则请求后端,进行缓存协商,304则直接返回给浏览器。

名词解释:

1. Last-Modified:服务器上文件的最后修改时间
2. Etag:文件标识
3. Expires:本地缓存目录中,文件过期的时间(由服务器指定具体的时间)
4. Cache-control:本地缓存目录中,文件过期的时间(由服务器指定过期的间隔时间,由于浏览器根据间隔生成具体的时间)

配置静态资源缓存expires

1. #作用:添加Cache-Control Expires头
2. Syntax: expires [modified] time;
3.         epoch | max | off;
4. Default: expires off;
5. Context: http, server, location, if in location
6. 
7. server {
8.     listen 80;
9.     server_name tets.koten.com;
10. 
11. location ~ .*\.(jpg|gif|png)$ {
12.         expires      7d;
13.     }
14. location ~ .*\.(js|css)$ {
15.         expires      30d;
16.     }
17. }
18. 
19. 
20. #取消js、css、html等静态文件缓存(如果代码没有上线,希望静态文件不被缓存)
21. location ~ .*\.(js|css|html)$ {
22. add_header Cache-Control no-store;
23. add_header Pragma no-cache;
24. }

2、sendfile静态资源高效读取

1. Syntax: sendfile on | off;
2. Default: sendfile off;
3. Context: http, server, location, if in location
4. 
5. #将多个包一次发送,大文件推荐打开,需要开启sendfile
6. Syntax: tcp_nopush on | off;
7. Default: tcp_nopush off;
8. Context: http, server, location
9. 
10. #来个包发个包不等待,适合小文件,需要开启keepalive
11. Syntax: tcp_nodelay on | off;
12. Default: tcpnodelay off;
13. Context: http, server, location

五、静态资源压缩

Nginx将响应报文发送至客户端之前启用压缩功能,然后进行传输,这能够有效地节约带宽,并提高响应至客户端的速度。

1、gzip传输压缩

1. #开启gzip传输压缩,传输前压缩,传输后解压
2. Syntax: gzip on | off;
3. Default: gzip off;
4. Context: http, server, location, if in location
5. 
6. #gzip指定压缩文件
7. Syntax: gzip_types mime-type ...;
8. Default: gzip_types text/html;
9. Context: http, server, location
10. 
11. #gzip压缩比率,加快传输,但压缩本身比较耗费服务器性能
12. Syntax: gzip_comp_level level;
13. Default:gzip_comp_level level 1;
14. Context: http, server, location
15. 
16. #gzip压缩协议版本,压缩使用在http哪个协议,主流选择1.1版本
17. Syntax: gzip_http_version 1.0 | 1.1;
18. Default:gzip_http_version 1.1;
19. Context: http, server, location
20. 
21. #静态文件压缩案例
22. [root@LB01 conf.d]# cat try.conf 
23. server {
24.     listen 80;
25.     server_name test.koten.com;
26. 
27. location ~ .*\.(jpg|png|gif) {
28.         root /code/images;
29.         #gzip on;
30.         #gzip_types image/jpeg image/gif image/png;
31.         #gzip_comp_level 2;
32.         #gzip_http_version 1.1; 
33.     }
34. location ~ .*\.(txt|xml|html|json|js|css)$ {
35.         gzip on;
36.         gzip_http_version 1.1;
37.         gzip_comp_level 1;
38.         gzip_types text/plain application/json application/x-javascript application/css application/xml text/javascript;
39.     }
40. }
41. #压缩前后观察对比,可以明显看到传输的Size大小变化

六、其他

1、防止资源盗链

防盗链,指的是防止资源被其他网站恶意盗用。

基础防盗链思路:主要是针对客户端请求过程中所携带的一些Header信息来验证请求的合法性,比如客户端在请求的过程中都会携带referer信息。优点是规则简单,配置和使用都很方便,缺点是防盗链所依赖的Referer验证信息是可以伪造的,所以通过referer信息防盗链并非100%可靠。

1. Syntax: valid_referers none | blocked | server_name | string ...;
2. Default: -;
3. Context: server, location
4. 
5. #none: referer来源头部为空的情况
6. #blocked: referer来源头部不为空,这些都不以http://或者https://开头
7. #server_name: 来源头部信息包含当前域名,可以正则匹配

1、在Web1上准备html文件,准备偷取Web02的图片

1. <html>
2. <head>
3. <meta charset="utf-8">
4. <title>fangdao_test</title>
5. </head>
6. <body style="background-color:pink;">
7. <center><img src="https://web.koten.com/daolian.jpg"/></center>
8. </body>
9. </html>

2、访问页面可以看到

3、在服务器上配置允许盗的站点

1. location ~ .*\.(jpg|png|gif) {
2.          root /var/www/wordpress/wp-content/extra/;
3. valid_referers none blocked *.koten.com server_name ~\.google\. ~\.baidu\.;
4. if ( $invalid_referer ) {
5. return 403;
6.         }
7. }
8. #所有来自*.koten.com都可以访问到当前站点的图片,如果来源域名不在这个列表中,那么$invalid_referer等于1,在if语句中返回一个403个客户,这样用户便会看到一个403的页面

4、配置返回图片

1. location ~ .*\.(jpg|png|gif) {
2.             root /var/www/wordpress/wp-content/extra/;
3. valid_referers none blocked *.koten.com;
4. if ( $invalid_referer ) {
5. rewrite ^(.*)$ /Picture/daolian1.gif break;
6.             }
7. }

5、这种防护并不能百分百保证资源不被盗,因为我们可以通过命令来修改来源的refer信息

1. #伪造协议头访问
2. [root@web01 code]# curl -e "https://www.baidu.com" -I http://test.koten.com/Picture/daolian.jpg
3. HTTP/1.1 403 Forbidden
4. Server: nginx
5. Date: Thu, 10 Oct 2019 09:01:05 GMT
6. Content-Type: text/html; charset=utf-8,gbk
7. Content-Length: 162
8. Connection: keep-alive
9. 
10. #伪造协议头访问
11. [root@web01 code]# curl -e "https://www.koten.com" -I http://test.koten.com/Picture/daolian.jpg
12. HTTP/1.1 200 OK
13. Server: nginx
14. Date: Thu, 10 Oct 2019 09:01:35 GMT
15. Content-Type: image/jpeg
16. Content-Length: 556417
17. Last-Modified: Thu, 10 Oct 2019 07:14:19 GMT
18. Connection: keep-alive
19. ETag: "5d9eda4b-87d81"
20. Accept-Ranges: bytes

2、允许跨域访问

跨域访问是当我们通过浏览器访问a网站时,同时会利用到ajax或其他方式,同时也请求b网站,这样的话就出现了请求一个页面,使用了两个域名,这种方式对浏览器来说默认是禁止的。因为浏览器会读取Access-Control-Allow-Origin的头信息,如果服务端允许,则浏览器不会进行拦截。

1. #编辑Nginx配置文件
2. [root@web02 code]# vim /etc/nginx/conf.d/s.conf
3. server {
4.         listen 80;
5.         server_name test.koten.com;
6. location / {
7.                 root /code;
8. index index.html;
9.         }
10. }
11. 
12. #编辑html文件
13. [root@Nginx ~]# cat /code/test.html 
14. <html lang="en">
15. <head>
16. <meta charset="UTF-8" />
17. <title>测试ajax和跨域访问</title>
18. <script src="http://libs.baidu.com/jquery/2.1.4/jquery.min.js"></script>
19. </head>
20. <script type="text/javascript">
21. $(document).ready(function(){
22.         $.ajax({
23. type: "GET",
24.         url: "http://web.koten.com",
25.         success: function(data) {
26.                 alert("成功跨域!");
27.         },
28. error: function() {
29.                 alert("跨域失败!");
30.         }
31.         });
32. });
33. </script>
34. <body>
35. <h1>跨域访问测试</h1>
36. </body>
37. </html>
38. 
39. #被关联网站配置
40. server {
41.         listen 80;
42.         server_name web.koten.com;
43.         root /code;
44. index index.html;
45.         charset utf-8;
46. 
47. location ~ .*\.(html|htm)$ {
48. add_header Access-Control-Allow-Origin *;
49. add_header Access-Control-Allow-Methods GET,POST,PUT,DELETE,OPTIONS;
50.         }
51. }

3、CPU亲和配置

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

1. #查看当前CPU物理状态
2. [root@Web01 ~]$ lscpu | grep "CPU(s)"
3. CPU(s):                8
4. On-line CPU(s) list:   0-7
5. NUMA node0 CPU(s):     0-7
6. 
7. #以上服务器有一颗物理CPU,上面有8个核心
8. 
9. #将Nginx worker进程绑定至不同的核心上,建议与CPU核心保持一致
10. 
11. # 第一种绑定组合方式(不推荐)
12. worker_processes 12;
13. worker_cpu_affinity 000000000001 000000000010 000000000100 000000001000 000000010000 000000100000 000001000000 000010000000 000100000000 001000000000 010000000000 10000000000;
14. 
15. # 第二种方式(使用较少)
16. worker_processes 2;
17. worker_cpu_affinity 101010101010 010101010101;
18. 
19. # 第三种最佳绑定方式,修改nginx启动的work进程为自动。
20. worker_processes  auto;
21. worker_cpu_affinity auto;
22. 
23. #查看Nginx worker进程绑定至对应CPU
24. [root@web01 ~]# ps -eo pid,args,psr|grep [n]ginx
25. 1242 nginx: master process /usr/   2
26. 1243 nginx: worker process         0
27. 1244 nginx: worker process         1
28. 1245 nginx: worker process         2
29. 1246 nginx: worker process         3

4、通用优化配置

1. [root@nginx ~]# cat nginx.conf
2. user www;                   # nginx进程启动用户
3. worker_processes auto;      #与cpu核心一致即可
4. worker_cpu_affinity auto;   # cpu亲和
5. 
6. error_log /var/log/nginx/error.log warn;    # 错误日志
7. pid /run/nginx.pid;
8. worker_rlimit_nofile 35535;     #每个work能打开的文件描述符,调整至1w以上,负荷较高建议2-3w
9. 
10. events {
11. use epoll;                  # 使用epoll高效网络模型
12.     worker_connections 10240;   # 限制每个进程能处理多少个连接,10240x[cpu核心]
13. }
14. 
15. http {
16.     include             mime.types;
17. default_type        application/octet-stream;
18.     charset utf-8;      # 统一使用utf-8字符集
19. 
20.     # 定义日志格式
21.     log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
22. '$status $body_bytes_sent "$http_referer" '
23. '"$http_user_agent" "$http_x_forwarded_for"';
24. 
25.     #定义json日志格式              
26.     log_format json_access '{"@timestamp":"$time_iso8601",'
27. '"host":"$server_addr",'
28. '"clientip":"$remote_addr",'
29. '"size":$body_bytes_sent,'
30. '"responsetime":$request_time,'
31. '"upstreamtime":"$upstream_response_time",'
32. '"upstreamhost":"$upstream_addr",'
33. '"http_host":"$host",'
34. '"url":"$uri",'
35. '"domain":"$host",'
36. '"xff":"$http_x_forwarded_for",'
37. '"referer":"$http_referer",'
38. '"status":"$status"}';
39. 
40. access_log  /var/log/nginx/access.log  main;    # 访问日志
41. 
42.     server_tokens off;  # 禁止浏览器显示nginx版本号
43.     client_max_body_size 200m;  # 文件上传大小限制调整
44. 
45.     # 文件高效传输,静态资源服务器建议打开
46.     sendfile            on;
47.     tcp_nopush          on;
48.     # 文件实时传输,动态资源服务建议打开,需要打开keepalive
49.     tcp_nodelay         on;
50.     keepalive_timeout   65;
51. 
52.     # Gzip 压缩
53.     gzip on;
54.     gzip_disable "MSIE [1-6]\.";    #针对IE浏览器不进行压缩
55.     gzip_http_version 1.1;
56.     gzip_comp_level 2;      #压缩级别
57.     gzip_buffers 16 8k;     #压缩的缓冲区
58.     gzip_min_length 1024;   #文件大于1024字节才进行压缩,默认值20
59.     gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript image/jpeg;
60. 
61.     # 虚拟主机
62.     include /etc/nginx/conf.d/*.conf;
63. }

Nginx性能优化总结

1、CPU亲和、worker进程数、调整每个worker进程打开的文件数

2、使用EPOOL网络模型、调整每个worker进程的最大连接数

3、文件的高效读取sendfile、no铺设

4、文件传输实时性、nodealy

5、开启tcp长连接,以及长连接超时时间keepalived

6、开启文件传输压缩gzip

7、开启静态文件expires缓存

8、隐藏Nginx版本号

9、禁止通过ip地址访问,禁止恶意域名解析,只允许域名访问

10、配置防盗链、以及跨域访问

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

12、建立Nginx错误页面

13、Nginx加密传输https优化

14、Nginx proxy_cache、fastcgi_cache、uwsgi_cache缓存,第三方工具(squid、varnish)


我是koten,10年运维经验,持续分享运维干货,感谢大家的阅读和关注!

目录
相关文章
|
15天前
|
弹性计算 运维 Serverless
卓越效能,极简运维,体验Serverless高可用架构,完成任务可领取转轮日历!
卓越效能,极简运维,体验Serverless高可用架构,完成任务可领取转轮日历!
|
1月前
|
运维 监控 安全
自动化运维的利剑:Ansible在现代IT架构中的应用
在数字化浪潮中,企业对IT系统的敏捷性和可靠性要求日益提高。Ansible,一种简单但强大的自动化运维工具,正成为现代IT架构中不可或缺的一部分。它通过声明式编程语言YAM,简化了系统配置、应用部署和任务自动化的过程,显著提升了运维效率和准确性。本文将深入探讨Ansible的核心特性、应用场景以及如何有效整合进现有IT环境,为读者揭示其在自动化运维中的实用价值和未来发展潜力。
|
6天前
|
存储 负载均衡 监控
揭秘 Elasticsearch 集群架构,解锁大数据处理神器
Elasticsearch 是一个强大的分布式搜索和分析引擎,广泛应用于大数据处理、实时搜索和分析。本文深入探讨了 Elasticsearch 集群的架构和特性,包括高可用性和负载均衡,以及主节点、数据节点、协调节点和 Ingest 节点的角色和功能。
22 0
|
1月前
|
运维 Devops 应用服务中间件
自动化运维的利剑:Ansible在现代IT架构中的应用
【10月更文挑战第42天】本文旨在揭示自动化运维工具Ansible如何革新现代IT架构,通过简化配置管理和部署流程,提升效率和可靠性。我们将探索Ansible的核心功能、语言特性以及其在DevOps文化中的角色。文章还将展示如何借助Ansible构建模块化和可重用的配置代码,实现快速迭代与部署,并确保系统一致性。通过阅读本文,运维人员将了解如何利用Ansible优化日常任务,加速产品上线速度,同时提高系统的稳健性。
42 5
|
1月前
|
存储 缓存 NoSQL
【赵渝强老师】Memcached集群的架构
Memcached 是一个高性能的分布式内存对象缓存系统,通过在内存中维护一个巨大的 Hash 表来存储各种格式的数据,如图像、视频、文件及数据库检索结果等。它主要用于减轻数据库压力,提高网站系统的性能。Memcached 不支持数据持久化,因此仅作为缓存技术使用。其数据分布式存储由客户端应用程序实现,而非服务端。
【赵渝强老师】Memcached集群的架构
|
1月前
|
调度 Docker 容器
【赵渝强老师】Docker Swarm集群的体系架构
Docker Swarm自1.12.0版本起集成至Docker引擎,无需单独安装。它内置服务发现功能,支持跨多服务器或宿主机创建容器,形成集群提供服务。相比之下,Docker Compose仅限于单个宿主机。Docker Swarm采用主从架构,Swarm Manager负责管理和调度集群中的容器资源,用户通过其接口发送指令,Swarm Node根据指令创建容器运行应用。
|
监控 应用服务中间件 nginx
|
1月前
|
缓存 应用服务中间件 网络安全
Nginx中配置HTTP2协议的方法
Nginx中配置HTTP2协议的方法
95 7
|
2月前
|
应用服务中间件 BI nginx
Nginx的location配置详解
【10月更文挑战第16天】Nginx的location配置详解