网站性能优化

第1章 网站前端性能优化

前端近几年变化很大,各种工具,库,框架并发。虽然如此,但是网站前端性能优化的思路基本没变。
为什么前端性能如此重要?数据显示:
1)只有 10%~20%的最终用户响应时间花在了下载HTML文档上。其余的80%~90%时间花在了下载页面中的所有组件中;
2)另外一点是,优化后台需要花费比较大的成本,优化前端只需要适当地遵循一些法则会有较大的提升,相对低成本高收益。

本文是根据浏览器请求和响应的整个过程为线索,分别对每一个过程进行优化处理。

浏览器请求和响应的过程

这里写图片描述

第一步、浏览器预处理

查询Cache:读取Cache 或者发送304请求
这里写图片描述

第二步、查询DNS

优化规则–减少DNS查找
简单来说,DNS 查找就是输入域名对服务器IP地址的查找过程。DNS缓存又分为浏览器DNS缓存、操作系统DNS缓存。当你输入www.google.com的时候,浏览器会先去自身的DNS缓存里面查找有没有google服务器的IP地址;如果找不到则继续到操作系统的DNS缓存查找;如果浏览器在这两个容器都没有找到google的IP地址记录,则会向广域域名体系查找。

  • 方法1:使用DNS缓存
    浏览器DNS缓存 计算机DNS缓存 服务器DNS缓存(TTL)

  • 方法2:使用Keep-Alive特性
    当客户端的DNS缓存为空时,DNS查找的数量与Web页面中唯一主机名的数量相等。减少唯一主机名的数量就可以减少DNS查找的数量。

  • 方法3:较少的域名来减少DNS查找(2-4个主机)

  • 方法4:使用第三方DNS域名解析加速服务
    国内的一款免费DNS加速服务DNSPOD;

第三步、建立连接

优化规则– 使用内容分发网络(CDN)
CDN是一组分布在多个不同地理位置的Web服务器,由于距离用户 物理距离比较短,所以能够更加有利于用户获取到静态资源;这种服务通常需要购买,也有一些免费、通用的CDN可使用,国内的可以使用BootCDN。
PS:个人建议,启用CDN最好放在最后一步,等将站点本身的优化都做完了之后,再启用CDN可以明显的看到优化效果。(开启CDN后,由于有CDN缓存的原因,观测站点的本身的优化就不是很方便了);

  • 方法1:美国十大Internet网站和CDN服务提供商:

  • 方法2:页面静态化,取决于发布系统

  • 方法3:Ctrip使用的China-Cache和网宿

优化规则–用域名划分页面内容
按页面内容划分域名,在合适的资源服务器上存放文件

第四步、发送请求

优化规则–减少HTTP请求
一般来说,使用外链的脚本和样式表更加有利。分别把外链脚本和样式表进行合并会减少HTTP请求,以节省客户端和服务器之间的通讯次数来加快页面打开速度。但是出于开发的便利,开发的时候一般会采取模块化的方式;这时候可以在部署前采用一些前端构建工具把这些模块文件合并起来再发布。

HTTP请求30-40,合并文件,图片地图,内联图像
js文件(不超过7个)
css文件不超过4个,各频道首页和全站首页不超过3个。
目前无法解决的是allyes广告的请求数。
大量的广告和产品图片可能会造成,图片请求数很大,可能造成总请求数指标吃紧,这个只能从设计上搞定,需要权衡
目前老页面可能css和js文件请求数可能会超标

合并样式和脚本

优化规则–优化CSS Spirite
图片地图 Ctrip首页例子

优化规则–避免404错误
避免内部无效的链接

优化规则–不要使用frameset,少使用iframe
搜索引擎不友好,即使内容为空,加载也需要时间、会阻止页面加载
禁止使用iframe引入外部资源,不包括allyes广告,不包括about:blank的空页面。

第五步、等待响应

优化规则–避免重定向
以下是一个重定向的过程:
浏览器发送请求——>服务器返回302——>浏览器发送第二次请求—–>服务器返回200—>浏览器开始呈现
就是说,在重定向完毕并且HTML下载完毕之前,是没有任何东西显示给用户的

涉及服务器负载、数据查询、服务器端缓存等

第六步、接收数据

优化规则–压缩组件
HTML文档、脚本和样式表、XML和JSON的文本响应
压缩通常能将响应的数据量减少将近70%

优化规则–减小Javascript和CSS文件大小
从代码中移除不必要的字符以减少其大小,减少加载时间。

减少JavaScript 文件大小的有几种手段:

  1. 通常被广泛使用的是精简。精简就是去除JavaScript代码中的空格、注释等多余的字符,这种方式基本上没有什么缺点。
  2. 另外一种方式是混淆。混淆是在精简的基础上,把函数、变量名都用较短小的字符来替换,从而达到减少文件大小的效果。但是混淆会产生不少麻烦,很有可能会引入错误,虽然有利于防止逆向工程,当同时也增加了自己在线上环境调试的难度。
    现在普遍的做法是发布前利用 Gulp、Grunt等自动化构建工具对资源进行压缩。

优化规则–尽量缩减页面大小
页面必须小于150K(不含图片)

  • 静态文件是否gzip
  • 图片是否压缩优化过

第七步、读取Cache

优化规则–添加Expires头或Cache-Control
Expires头是用来告诉浏览器该响应的有效期,可以理解为该资源的“保质期”,在期限内可以使用该资源的缓存不需要重新请求。由于浏览器与服务器存在时钟同步问题,HTTP1.2.1还添加了Cache-Control和max-age来弥补Expires头的不足。通常用于脚本,样式表、图片等静态资源。

使用这种策略可能会遇到一个问题是,开发者可能想要在资源过期前这段时间更新它们。这时候,由于浏览器的缓存还没失效,这就需要通过更改文件名来令静态资源 强制失效。有很多种方式给静态资源打上版本号,可以一本正经地打上数字版本号,根据内容生成哈希码也行,甚至有人用π来给自己的资源打版本号。
应用于不经常变化的组件,包括脚本、样式表、Flash组件、图片

优化规则– 使用外链JavaScript和CSS
尽可能 使用外链JavaScript和CSS,因为我们目前大部分avaScript和CSS都做了Gzip和缓存技术,可以充分利用。
使用外链样式和脚本有点有:
1.可以被浏览器缓存起来;2. 组件可重用3. 可模块化;4. 能够被构建(合并压缩打版本)

第八步、处理元素

不要对image和pdf等二进制文件进行gzip压缩

第八步、渲染元素

优化规则–将样式表放在顶部
如果把样式表放在底部时,浏览器会延迟显示任何可视化组件。另外,使用 CSS 的@import 等同于把想要加载的样式放在底部,所以不建议使用。对于浏览器的渲染机制,本书并没有过多提及,只是对现象做出了描述以及提供了解决办法。

如果样式表仍然在加载,构建呈现树就是一种浪费,因为在所有样式表加载并解析完毕之前无需绘制任何东西。否则,在其准备好之前显示内容会遇到 FOUC(无样式内容的闪烁,Flash of Unstyled Content)问题。
就是说,如果不把样式表放在 中,当遇到样式时,浏览器就会阻止页面呈现,等待样式表下载完毕。

如果把样式表放在底部,在 IE 中还会产生白屏现象。总之,把样式表放进就能避免这些问题。

优化规则 – 建议将脚本放在底部
一般浏览器可以允许并行下载,取决于主机个数、带宽等(默认情况下,IE是2个而FF是8个)下载脚本时并行下载实际上是被禁用的。

脚本对页面的影响是:

  1. 阻塞对其后面内容的呈现
  2. 阻塞后面组件的下载
  3. 浏览器会在下载脚本的时候阻塞并行下载,因为需要确保脚本能够顺序执行。

关于这点,这里有一篇讲解的比较深入的文章:
JS 一定要放在 Body的最底部么?聊聊浏览器的渲染机制

但是,实际开发中有时候很难完全遵守这条准则,那只能把能够放在最后的都放在最后。

优化规则–移除重复脚本
必须为0,重复的脚本对增加HTTP 请求次数和脚本执行的时间。

优化规则 – 避免CSS表达式
使用CSS 的expression()通常会造成多次运算。影响浏览器渲染时间。实际上,需要用到CSS表达式的地方,通常能够找到其他替代方案,所以避免使用CSS表达式。

优化规则–优化图像
尽量使用GIF和PNG

尽量使用png/gif格式的图片,png的图片优先,但是必须注意如要兼容IE6,则png使用一定要注意透明问题。

图片在使用前一定要先用工具压缩优化(png、jpg)

第2章 网站后端性能优化

Web性能涉及的范围太广,但一般web开发者在程序上线以后很多都曾遇到过性能的问题。普遍表现为页面速度开始急剧变慢,正常访问时间变的很长,或则干脆给你抛出异常错误页面。这里会涉及到很多可能发生的情况,举例几个最主要发生的情况:

  • 数据库连接超过最大限制,一般表现为程序的连接池满,拒绝了与数据库的连接。
  • 数据库死锁
  • Web Server 超过最大连接数(一般在虚拟主机上才会限制)
  • 内存泄漏
  • Http连接数太多,即访问量超过了机器和软件设计正常所能提供的服务

2.1反向代理

通过反向代理来提高性能和增加安全性
  如果你的 web应用运行在单个机器上,那么这个办法会明显的提升性能:只需要换一个更快的机器,更好的处理器,更多的内存,更快的磁盘阵列,等等。然后新机器就可以更快的运行你的WordPress 服务器, Node.js 程序, Java程序,以及其它程序。(如果你的程序要访问数据库服务器,那么解决方法依然很简单:添加两个更快的机器,以及在两台电脑之间使用一个更快的链路。)
  问题是,机器速度可能并不是问题。web程序运行慢经常是因为计算机一直在不同的任务之间切换:通过成千上万的连接和用户交互,从磁盘访问文件,运行代码,等等。应用服务器可能会抖动thrashing-比如说内存不足、将内存数据交换到磁盘,以及有多个请求要等待某个任务完成,如磁盘I/O。
  你可以采取一个完全不同的方案来替代升级硬件:添加一个反向代理服务器来分担部分任务。反向代理服务器 位于运行应用的机器的前端,是用来处理网络流量的。只有反向代理服务器是直接连接到互联网的;和应用服务器的通讯都是通过一个快速的内部网络完成的。
  使用反向代理服务器可以将应用服务器从等待用户与 web程序交互解放出来,这样应用服务器就可以专注于为反向代理服务器构建网页,让其能够传输到互联网上。而应用服务器就不需要等待客户端的响应,其运行速度可以接近于优化后的性能水平。
  添加反向代理服务器还可以给你的 web服务器安装带来灵活性。比如,一个某种类型的服务器已经超载了,那么就可以轻松的添加另一个相同的服务器;如果某个机器宕机了,也可以很容易替代一个新的。
  因为反向代理带来的灵活性,所以反向代理也是一些性能加速功能的必要前提,比如

  • 负载均衡 (参见 Tip #2) – 负载均衡运行在反向代理服务器上,用来将流量均衡分配给一批应用。有了合适的负载均衡,你就可以添加应用服务器而根本不用修改应用。
  • 缓存静态文件 (参见 Tip #3) – 直接读取的文件,比如图片或者客户端代码,可以保存在反向代理服务器,然后直接发给客户端,这样就可以提高速度、分担应用服务器的负载,可以让应用运行的更快。
  • 网站安全 – 反向代理服务器可以提高网站安全性,以及快速的发现和响应攻击,保证应用服务器处于被保护状态。

NGINX 软件为用作反向代理服务器而专门设计,也包含了上述的多种功能。NGINX使用事件驱动的方式处理请求,这会比传统的服务器更加有效率。NGINX plus 添加了更多高级的反向代理特性,比如应用的健康度检查,专门用来处理请求路由、高级缓冲和相关支持。

2.2添加负载平衡

  添加一个负载均衡服务器 是一个相当简单的用来提高性能和网站安全性的的方法。与其将核心 Web服务器变得越来越大和越来越强,不如使用负载均衡将流量分配到多个服务器。即使程序写的不好,或者在扩容方面有困难,仅是使用负载均衡服务器就可以很好的提高用户体验。
  负载均衡服务器首先是一个反向代理服务器(参见Tip #1)——它接受来自互联网的流量,然后转发请求给另一个服务器。特别是负载均衡服务器支持两个或多个应用服务器,使用分配算法将请求转发给不同服务器。最简单的负载均衡方法是轮转法round
robin,每个新的请求都会发给列表里的下一个服务器。其它的复制均衡方法包括将请求发给活动连接最少的服务器。NGINX plus 拥有将特定用户的会话分配给同一个服务器的能力。
  负载均衡可以很好的提高性能是因为它可以避免某个服务器过载而另一些服务器却没有需要处理的流量。它也可以简单的扩展服务器规模,因为你可以添加多个价格相对便宜的服务器并且保证它们被充分利用了。
  可以进行负载均衡的协议包括 HTTP、HTTPS、SPDY、HTTP/2、WebSocket、FastCGI、SCGI、uwsgi、
memcached 等,以及几种其它的应用类型,包括基于 TCP 的应用和其它的第4层协议的程序。分析你的 web应用来决定你要使用哪些以及哪些地方性能不足。
  相同的服务器或服务器群可以被用来进行负载均衡,也可以用来处理其它的任务,如 SSL 末端服务器,支持客户端的 HTTP/1.x 和 HTTP/2
请求,以及缓存静态文件。
  NGINX 经常被用于进行负载均衡;要想了解更多的情况,可以下载我们的电子书《选择软件负载均衡器的五个理由》。你也可以从《使用 NGINX 和 NGINX Plus 配置负载均衡,第一部分》中了解基本的配置指导,在 NGINX Plus 管理员指南中有完整的 NGINX 负载均衡的文档。。我们的商业版本 NGINX Plus 支持更多优化了的负载均衡特性,如基于服务器响应时间的加载路由和 Microsoft’s NTLM 协议上的负载均衡。

2.3缓存静态和动态的内容

  缓存可以通过加速内容的传输速度来提高 web应用的性能。它可以采用以下几种策略:当需要的时候预处理要传输的内容,保存数据到速度更快的设备,把数据存储在距离客户端更近的位置,或者将这几种方法结合起来使用。
  有两种不同类型数据的缓冲:
静态内容缓存。不经常变化的文件,比如图像(JPEG、PNG) 和代码(CSS,JavaScript),可以保存在外围服务器上,这样就可以快速的从内存和磁盘上提取。
动态内容缓存。很多 web 应用会针对每次网页请求生成一个新的 HTML 页面。在短时间内简单的缓存生成的 HTML内容,就可以很好的减少要生成的内容的数量,而且这些页面足够新,可以满足你的需要。
  举个例子,如果一个页面每秒会被浏览10次,你将它缓存 1 秒,90%请求的页面都会直接从缓存提取。如果你分开缓存静态内容,甚至新生成的页面可能都是由这些缓存构成的。
  下面由是 web 应用发明的三种主要的缓存技术:
缩短数据与用户的网络距离。把一份内容的拷贝放的离用户更近的节点来减少传输时间。
提高内容服务器的速度。内容可以保存在一个更快的服务器上来减少提取文件的时间。
从过载服务器上移走数据。机器经常因为要完成某些其它的任务而造成某个任务的执行速度比测试结果要差。将数据缓存在不同的机器上可以提高缓存资源和非缓存资源的性能,而这是因为主机没有被过度使用。
  对 web 应用的缓存机制可以在 web应用服务器内部实现。首先,缓存动态内容是用来减少应用服务器加载动态内容的时间。其次,缓存静态内容(包括动态内容的临时拷贝)是为了更进一步的分担应用服务器的负载。而且缓存之后会从应用服务器转移到对用户而言更快、更近的机器,从而减少应用服务器的压力,减少提取数据和传输数据的时间。
  改进过的缓存方案可以极大的提高应用的速度。对于大多数网页来说,静态数据,比如大图像文件,构成了超过一半的内容。如果没有缓存,那么这可能会花费几秒的时间来提取和传输这类数据,但是采用了缓存之后不到1秒就可以完成。
  举一个在实际中缓存是如何使用的例子, NGINX 和 NGINX Plus 使用了两条指令来设置缓存机制:proxy_cache_path 和 proxy_cache。你可以指定缓存的位置和大小、文件在缓存中保存的最长时间和其它一些参数。使用第三条(而且是相当受欢迎的一条)指令proxy_cache_use_stale,如果提供新鲜内容的服务器忙碌或者挂掉了,你甚至可以让缓存提供较旧的内容,这样客户端就不会一无所得。从用户的角度来看这可以很好的提高你的网站或者应用的可用时间。
  NGINX plus 有个高级缓存特性,包括对缓存清除的支持和在仪表盘上显示缓存状态信息。
  要想获得更多关于 NGINX 的缓存机制的信息可以浏览 NGINX Plus 管理员指南中的《参考文档》和《NGINX 内容缓存》。
  注意:缓存机制分布于应用开发者、投资决策者以及实际的系统运维人员之间。本文提到的一些复杂的缓存机制从 DevOps 的角度来看很具有价值,即对集应用开发者、架构师以及运维操作人员的功能为一体的工程师来说可以满足它们对站点功能性、响应时间、安全性和商业结果(如完成的交易数)等需要。

2.4压缩数据

  压缩是一个具有很大潜力的提高性能的加速方法。现在已经有一些针对照片(JPEG和PNG)、视频(MPEG-4)和音乐(MP3)等各类文件精心设计和高压缩率的标准。每一个标准都或多或少的减少了文件的大小。
  文本数据 —— 包括HTML(包含了纯文本和 HTML 标签),CSS 和代码,比如 Javascript —— 经常是未经压缩就传输的。压缩这类数据会在对应用程序性能的感觉上,特别是处于慢速或受限的移动网络的客户端,产生更大的影响。
  这是因为文本数据经常是用户与网页交互的有效数据,而多媒体数据可能更多的是起提供支持或者装饰的作用。智能的内容压缩可以减少HTML,Javascript,CSS和其它文本内容对带宽的要求,通常可以减少 30% 甚至更多的带宽和相应的页面加载时间。
  如果你使用 SSL,压缩可以减少需要进行 SSL 编码的的数据量,而这些编码操作会占用一些 CPU 时间而抵消了压缩数据减少的时间。
  压缩文本数据的方法很多,举个例子,在HTTP/2 中,小说文本的压缩模式就特别调整了头部数据。另一个例子是可以在 NGINX 里打开使用 GZIP压缩。你在你的服务里预先压缩文本数据之后,你就可以直接使用gzip_static 指令来处理压缩过的 .gz 版本。

2.5优化 SSL/TLS

  安全套接字(SSL) 协议和它的下一代版本传输层安全(TLS)协议正在被越来越多的网站采用。SSL/TLS对从原始服务器发往用户的数据进行加密提高了网站的安全性。影响这个趋势的部分原因是 Google 正在使用SSL/TLS,这在搜索引擎排名上是一个正面的影响因素。
  尽管 SSL/TLS 越来越流行,但是使用加密对速度的影响也让很多网站望而却步。SSL/TLS 之所以让网站变的更慢,原因有二:
任何一个连接第一次连接时的握手过程都需要传递密钥。而采用 HTTP/1.x 协议的浏览器在建立多个连接时会对每个连接重复上述操作。
数据在传输过程中需要不断的在服务器端加密、在客户端解密。
  为了鼓励使用 SSL/TLS,HTTP/2 和
SPDY(在下一章会描述)的作者设计了新的协议来让浏览器只需要对一个浏览器会话使用一个连接。这会大大的减少上述第一个原因所浪费的时间。然而现在可以用来提高应用程序使用
SSL/TLS 传输数据的性能的方法不止这些。
  web 服务器有对应的机制优化 SSL/TLS 传输。举个例子,NGINX 使用 OpenSSL 运行在普通的硬件上提供了接近专用硬件的传输性能。NGINX 的 SSL性能 有详细的文档,而且把对 SSL/TLS 数据进行加解密的时间和 CPU 占用率降低了很多。
  更进一步,参考这篇文章了解如何提高
SSL/TLS 性能的更多细节,可以总结为一下几点:
会话缓冲。使用指令 ssl_session_cache 可以缓存每个新的 SSL/TLS连接使用的参数。
会话票据或者 ID。把 SSL/TLS 的信息保存在一个票据或者 ID 里可以流畅的复用而不需要重新握手。
OCSP 分割。通过缓存 SSL/TLS 证书信息来减少握手时间。
  NGINX 和 NGINX Plus 可以被用作 SSL/TLS 服务端,用于处理客户端流量的加密和解密,而同时以明文方式和其它服务器进行通信。要设置NGINX 和 NGINX Plus 作为 SSL/TLS 服务端,参看《HTTPS连接》 和《加密的TCP连接》。

2.6使用 HTTP/2 或 SPDY

  对于已经使用了 SSL/TLS 的站点,HTTP/2 和 SPDY 可以很好的提高性能,因为每个连接只需要一次握手。而对于没有使用 SSL/TLS
的站点来说,从响应速度的角度来说 HTTP/2 和 SPDY 将让迁移到 SSL/TLS 没有什么压力(原本会降低效率)。
  Google 在2012年开始把 SPDY 作为一个比 HTTP/1.x 更快速的协议来推荐。HTTP/2 是目前 IETF 通过的标准,是基于SPDY 的。SPDY 已经被广泛的支持了,但是很快就会被 HTTP/2 替代。
  SPDY 和 HTTP/2 的关键是用单一连接来替代多路连接。单个连接是被复用的,所以它可以同时携带多个请求和响应的分片。
  通过使用单一连接,这些协议可以避免像在实现了 HTTP/1.x 的浏览器中一样建立和管理多个连接。单一连接在对 SSL 特别有效,这是因为它可以最小化SSL/TLS 建立安全链接时的握手时间。
  SPDY 协议需要使用 SSL/TLS,而 HTTP/2 官方标准并不需要,但是目前所有支持 HTTP/2 的浏览器只有在启用了 SSL/TLS的情况下才能使用它。这就意味着支持 HTTP/2 的浏览器只有在网站使用了 SSL 并且服务器接收 HTTP/2 流量的情况下才会启用HTTP/2。否则的话浏览器就会使用 HTTP/1.x 协议。
  当你实现 SPDY 或者 HTTP/2 时,你不再需要那些常规的 HTTP性能优化方案,比如按域分割、资源聚合,以及图像拼合。这些改变可以让你的代码和部署变得更简单和更易于管理。要了解 HTTP/2 带来的这些变化可以浏览我们的《白皮书》。作为支持这些协议的一个样例,NGINX 已经从一开始就支持了 SPDY,而且大部分使用
SPDY 协议的网站都运行的是 NGINX。NGINX 同时也很早对HTTP/2的提供了支持,从2015 年9月开始,开源版 NGINX 和 NGINX Plus 就支持它了。
  经过一段时间,我们 NGINX 希望更多的站点完全启用 SSL 并且向 HTTP/2迁移。这将会提高安全性,同时也会找到并实现新的优化手段,简化的代码表现的会更加优异。

2.7升级软件版本

  一个提高应用性能的简单办法是根据软件的稳定性和性能的评价来选在你的软件栈。进一步说,因为高性能组件的开发者更愿意追求更高的性能和解决 bug,所以值得使用最新版本的软件。新版本往往更受开发者和用户社区的关注。更新的版本往往会利用到新的编译器优化,包括对新硬件的调优。
  稳定的新版本通常比旧版本具有更好的兼容性和更高的性能。一直进行软件更新,可以非常简单的保持软件保持最佳的优化,解决掉 bug,以及提高安全性。
  一直使用旧版软件也会阻止你利用新的特性。比如上面说到的 HTTP/2,目前要求 OpenSSL 1.0.1。在2016 年中期开始将会要求1.0.2,而它是在2015年1月才发布的。
  NGINX 用户可以开始迁移到 NGINX 最新的开源软件 或者 NGINX Plus;它们都包含了最新的能力,如 socket分割和线程池(见下文),这些都已经为性能优化过了。然后好好看看的你软件栈,把它们升级到你能升级到的最新版本吧。

2.8Linux 系统性能调优

  Linux 是大多数 web 服务器使用的操作系统,而且作为你的架构的基础,Linux 显然有不少提高性能的可能。默认情况下,很多 Linux系统都被设置为使用很少的资源,以符合典型的桌面应用使用。这就意味着 web 应用需要一些微调才能达到最大效能。
  这里的 Linux 优化是专门针对 web 服务器方面的。以 NGINX 为例,这里有一些在加速 Linux 时需要强调的变化:
缓冲队列。如果你有挂起的连接,那么你应该考虑增加 net.core.somaxconn的值,它代表了可以缓存的连接的最大数量。如果连接限制太小,那么你将会看到错误信息,而你可以逐渐的增加这个参数直到错误信息停止出现。
文件描述符。NGINX对一个连接使用最多2个文件描述符。如果你的系统有很多连接请求,你可能就需要提高sys.fs.file_max,以增加系统对文件描述符数量整体的限制,这样才能支持不断增加的负载需求。
临时端口。当使用代理时,NGINX会为每个上游服务器创建临时端口。你可以设置net.ipv4.ip_local_port_range来提高这些端口的范围,增加可用的端口号。你也可以减少非活动的端口的超时判断来重复使用端口,这可以通过net.ipv4.tcp_fin_timeout来设置,这可以快速的提高流量。
  对于 NGINX来说,可以查阅 《NGINX
性能调优指南》来学习如果优化你的 Linux 系统,这样它就可以很好的适应大规模网络流量而不会超过工作极限。

2.9web 服务器性能调优

  无论你是用哪种 web 服务器,你都需要对它进行优化来提高性能。下面的推荐手段可以用于任何 web 服务器,但是一些设置是针对 NGINX的。关键的优化手段包括:
访问日志。不要把每个请求的日志都直接写回磁盘,你可以在内存将日志缓存起来然后批量写回磁盘。对于NGINX 来说,给指令access_log添加参数buffer=size 可以让系统在缓存满了的情况下才把日志写到磁盘。如果你添加了参数 flush=time ,那么缓存内容会每隔一段时间再写回磁盘。
缓存。缓存会在内存中存放部分响应,直到满了为止,这可以让与客户端的通信更加高效。内存放不下的响应会写回磁盘,而这就会降低效能。当 NGINX 启用了缓存机制后,你可以使用指令proxy_buffer_size 和proxy_buffers 来管理缓存。
客户端保活。保活连接可以减少开销,特别是使用 SSL/TLS 时。对于 NGINX 来说,你可以从 keepalive_requests 的默认值100 开始增加最大连接数,这样一个客户端就可以在一个指定的连接上请求多次,而且你也可以通过增加 keepalive_timeout的值来允许保活连接存活更长时间,这样就可以让后来的请求处理的更快速。
上游保活。上游的连接——即连接到应用服务器、数据库服务器等机器的连接——同样也会受益于连接保活。对于上游连接来说,你可以增加keepalive,即每个工人进程的空闲保活连接个数。这就可以提高连接的复用次数,减少需要重新打开全新连接的次数。更多关于保活连接的信息可以参见这篇“HTTP 保活连接和性能”。
限制。限制客户端使用的资源可以提高性能和安全性。对于 NGINX 来说,指令 limit_conn 和 limit_conn_zone限制了给定来源的连接数量,而 limit_rate 限制了带宽。这些限制都可以阻止合法用户扒取资源,同时也避免了攻击。指令 limit_req 和 limit_req_zone 限制了客户端请求。对于上游服务器来说,可以在 upstream 的配置块里的 server 指令使用 max_conns参数来限制连接到上游服务器的连接数。 这样可以避免服务器过载。关联的 queue 指令会创建一个队列来在连接数抵达 max_conns 限制时在指定长度的时间内保存特定数量的请求。
工人进程。工人进程负责处理请求。NGINX 采用事件驱动模型和操作系统特定的机制来有效的将请求分发给不同的工人进程。这条建议推荐设置worker_processes 为每个 CPU 一个。worker_connections的最大数(默认512)可以在大部分系统上根据需要增加,实验性地找到最适合你的系统的值。
套接字分割。通常一个套接字监听器会把新连接分配给所有工人进程。套接字分割会为每个工人进程创建一个套接字监听器,这样一来以当套接字监听器可用时,内核就会将连接分配给它。这可以减少锁竞争,并且提高多核系统的性能,要启用套接字分隔需要在 listen指令里面加上reuseport 参数。
线程池。计算机进程可能被一个单一的缓慢的操作所占用。对于web服务器软件来说,磁盘访问会影响很多更快的操作,比如计算或者在内存中拷贝。使用了线程池之后慢操作可以分配到不同的任务集,而主进程可以一直运行快速操作。当磁盘操作完成后结果会返回给主进程的循环。在NGINX 里有两个操作——read() 系统调用和 sendfile() ——被分配到了线程池技巧。当改变任何操作系统或支持服务的设置时,一次只改变一个参数然后测试性能。如果修改引起问题了,或者不能让你的系统更快,那么就改回去。

2.10监视系统活动来解决问题和瓶颈

  在应用开发中要使得系统变得非常高效的关键是监视你的系统在现实世界运行的性能。你必须能通过特定的设备和你的 web 基础设施上监控程序活动。
  监视活动是最积极的——它会告诉你发生了什么,把问题留给你发现和最终解决掉。
  监视可以发现几种不同的问题。它们包括:
服务器宕机。
服务器出问题一直在丢失连接。
服务器出现大量的缓存未命中。
服务器没有发送正确的内容。
  应用的总体性能监控工具,比如 New Relic 和 Dynatrace,可以帮助你监控到从远程加载网页的时间,而 NGINX可以帮助你监控到应用交付端。当你需要考虑为基础设施添加容量以满足流量需求时,应用性能数据可以告诉你你的优化措施的确起作用了。
  为了帮助开发者快速的发现、解决问题,NGINX Plus 增加了应用感知健康度检查 ——对重复出现的常规事件进行综合分析并在问题出现时向你发出警告。NGINX Plus 同时提供会话过滤功能,这可以阻止当前任务完成之前接受新的连接,另一个功能是慢启动,允许一个从错误恢复过来的服务器追赶上负载均衡服务器群的进度。当使用得当时,健康度检查可以让你在问题变得严重到影响用户体验前就发现它,而会话过滤和慢启动可以让你替换服务器,并且这个过程不会对性能和正常运行时间产生负面影响。下图就展示了内建的
NGINX Plus 模块实时活动监视的仪表盘,包括了服务器群,TCP连接和缓存信息等 Web 架构信息。

2.11总结: 看看10倍性能提升的效果

  这些性能提升方案对任何一个 web应用都可用并且效果都很好,而实际效果取决于你的预算、你能花费的时间、目前实现方案的差距。所以你该如何对你自己的应用实现10倍性能提升?
  为了指导你了解每种优化手段的潜在影响,这里是上面详述的每个优化方法的关键点,虽然你的情况肯定大不相同:

  1. 反向代理服务器和负载均衡 没有负载均衡或者负载均衡很差都会造成间歇的性能低谷。增加一个反向代理,比如 NGINX,可以避免web应用程序在内存和磁盘之间波动。负载均衡可以将过载服务器的任务转移到空闲的服务器,还可以轻松的进行扩容。这些改变都可以产生巨大的性能提升,很容易就可以比你现在的实现方案的最差性能提高10倍,对于总体性能来说可能提高的不多,但是也是有实质性的提升。
  2. 缓存动态和静态数据 如果你有一个负担过重的 web服务器,那么毫无疑问肯定是你的应用服务器,只通过缓存动态数据就可以在峰值时间提高10倍的性能。缓存静态文件可以提高几倍的性能。
  3. 压缩数据 使用媒体文件压缩格式,比如图像格式 JPEG,图形格式 PNG,视频格式 MPEG-4,音乐文件格式 MP3可以极大的提高性能。一旦这些都用上了,然后压缩文件数据可以将初始页面加载速度提高两倍。
  4. 优化SSL/TLS 安全握手会对性能产生巨大的影响,对它们的优化可能会对初始响应产生2倍的提升,特别是对于大量文本的站点。优化 SSL/TLS下媒体文件只会产生很小的性能提升。
  5. 使用 HTTP/2 和 SPDY 当你使用了SSL/TLS,这些协议就可以提高整个站点的性能。
  6. 对 Linux 和 web服务器软件进行调优 比如优化缓存机制,使用保活连接,分配时间敏感型任务到不同的线程池可以明显的提高性能;举个例子,线程池可以加速对磁盘敏感的任务近一个数量级。
阅读更多
个人分类: web前端
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!
关闭
关闭