【运维知识进阶篇】集群架构-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年运维经验,持续分享运维干货,感谢大家的阅读和关注!

目录
相关文章
|
2天前
|
人工智能 云计算 网络架构
阿里云引领智算集群网络架构的新一轮变革
11月8日~10日在江苏张家港召开的CCF ChinaNet(即中国网络大会)上,众多院士、教授和业界技术领袖齐聚一堂,畅谈网络未来的发展方向,聚焦智算集群网络的创新变革。
阿里云引领智算集群网络架构的新一轮变革
|
3天前
|
负载均衡 Dubbo 算法
集群容错架构设计
集群容错架构设计
13 1
集群容错架构设计
|
2天前
|
人工智能 运维 网络架构
阿里云引领智算集群网络架构的新一轮变革
11月8日至10日,CCF ChinaNet(中国网络大会)在江苏张家港召开,众多院士、教授和技术领袖共聚一堂,探讨网络未来发展方向。阿里云研发副总裁蔡德忠发表主题演讲,展望智算技术发展趋势,提出智算网络架构变革的新思路,发布高通量以太网协议和ENode+超节点系统规划,引起广泛关注。阿里云HPN7.0引领智算以太网生态蓬勃发展,成为业界标杆。未来,X10规模的智算集群将面临新的挑战,Ethernet将成为主流方案,推动Scale up与Scale out的融合架构,提升整体系统性能。
|
8天前
|
运维 Serverless 数据处理
Serverless架构通过提供更快的研发交付速度、降低成本、简化运维、优化资源利用、提供自动扩展能力、支持实时数据处理和快速原型开发等优势,为图像处理等计算密集型应用提供了一个高效、灵活且成本效益高的解决方案。
Serverless架构通过提供更快的研发交付速度、降低成本、简化运维、优化资源利用、提供自动扩展能力、支持实时数据处理和快速原型开发等优势,为图像处理等计算密集型应用提供了一个高效、灵活且成本效益高的解决方案。
34 1
|
12天前
|
负载均衡 应用服务中间件 nginx
基于Nginx和Consul构建自动发现的Docker服务架构——非常之详细
通过使用Nginx和Consul构建自动发现的Docker服务架构,可以显著提高服务的可用性、扩展性和管理效率。Consul实现了服务的自动注册与发现,而Nginx则通过动态配置实现了高效的反向代理与负载均衡。这种架构非常适合需要高可用性和弹性扩展的分布式系统。
18 4
|
13天前
|
负载均衡 应用服务中间件 nginx
基于Nginx和Consul构建自动发现的Docker服务架构——非常之详细
通过使用Nginx和Consul构建自动发现的Docker服务架构,可以显著提高服务的可用性、扩展性和管理效率。Consul实现了服务的自动注册与发现,而Nginx则通过动态配置实现了高效的反向代理与负载均衡。这种架构非常适合需要高可用性和弹性扩展的分布式系统。
28 3
|
23天前
|
运维 Serverless 数据处理
Serverless架构通过提供更快的研发交付速度、降低成本、简化运维、优化资源利用、提供自动扩展能力、支持实时数据处理和快速原型开发等优势,为图像处理等计算密集型应用提供了一个高效、灵活且成本效益高的解决方案。
Serverless架构通过提供更快的研发交付速度、降低成本、简化运维、优化资源利用、提供自动扩展能力、支持实时数据处理和快速原型开发等优势,为图像处理等计算密集型应用提供了一个高效、灵活且成本效益高的解决方案。
55 3
|
18小时前
|
机器学习/深度学习 运维 监控
智能运维在现代IT架构中的转型之路####
【10月更文挑战第29天】 本文旨在探讨智能运维(AIOps)如何成为现代IT架构不可或缺的一部分,通过分析其核心价值、关键技术及实践案例,揭示AIOps在提升系统稳定性、优化资源配置及加速故障响应中的关键作用。不同于传统运维模式的被动响应,智能运维强调预测性维护与自动化处理,为企业数字化转型提供强有力的技术支撑。 ####
16 0
|
7天前
|
弹性计算 Kubernetes Cloud Native
云原生架构下的微服务设计原则与实践####
本文深入探讨了在云原生环境中,微服务架构的设计原则、关键技术及实践案例。通过剖析传统单体架构面临的挑战,引出微服务作为解决方案的优势,并详细阐述了微服务设计的几大核心原则:单一职责、独立部署、弹性伸缩和服务自治。文章还介绍了容器化技术、Kubernetes等云原生工具如何助力微服务的高效实施,并通过一个实际项目案例,展示了从服务拆分到持续集成/持续部署(CI/CD)流程的完整实现路径,为读者提供了宝贵的实践经验和启发。 ####
|
4天前
|
监控 安全 应用服务中间件
微服务架构下的API网关设计策略与实践####
本文深入探讨了在微服务架构下,API网关作为系统统一入口点的设计策略、实现细节及其在实际应用中的最佳实践。不同于传统的摘要概述,本部分将直接以一段精简的代码示例作为引子,展示一个基于NGINX的简单API网关配置片段,随后引出文章的核心内容,旨在通过具体实例激发读者兴趣,快速理解API网关在微服务架构中的关键作用及实现方式。 ```nginx server { listen 80; server_name api.example.com; location / { proxy_pass http://backend_service:5000;