原文地址:http://www.jb51.net/yunying/452723.htmlhtml
提升 web 应用的性能历来没有比如今更重要过。网络经济的比重一直在增加;全球经济超过 5% 的价值是在因特网上产生的(数据参见下面的资料)。这个时刻在线的超链接世界意味着用户对其的指望值也处于历史上的最高点。若是你的网站不能及时的响应,或者你的 app 不能无延时的工做,用户会很快的投奔到你的竞争对手那里。前端
举一个例子,一份亚马逊十年前作过的研究能够证实,甚至在那个时候,网页加载时间每减小100毫秒,收入就会增长1%。另外一个最近的研究特别强调一个事实,即超过一半的网站拥有者在调查中认可它们会由于应用程序性能的问题流失用户。web
网站到底须要多快呢?对于页面加载,每增长1秒钟就有4%的用户放弃使用。顶级的电子商务站点的页面在第一次交互时能够作到1秒到3秒加载时间,而这是提供最高温馨度的速度。很明显这种利害关系对于 web 应用来讲很高,并且在不断的增长。算法
想要提升效率很简单,可是看到实际结果很难。为了在你的探索之旅上帮助到你,这篇文章会给你提供10条最高能够提高10倍网站性能的建议。数据库
Tip #1: 经过反向代理来提升性能和增长安全性浏览器
若是你的 web 应用运行在单个机器上,那么这个办法会明显的提高性能:只须要换一个更快的机器,更好的处理器,更多的内存,更快的磁盘阵列,等等。而后新机器就能够更快的运行你的 WordPress 服务器, Node.js 程序, Java 程序,以及其它程序。(若是你的程序要访问数据库服务器,那么解决方法依然很简单:添加两个更快的机器,以及在两台电脑之间使用一个更快的链路。)缓存
问题是,机器速度可能并非问题。web 程序运行慢常常是由于计算机一直在不一样的任务之间切换:经过成千上万的链接和用户交互,从磁盘访问文件,运行代码,等等。应用服务器可能会抖动thrashing-好比说内存不足、将内存数据交换到磁盘,以及有多个请求要等待某个任务完成,如磁盘I/O。安全
你能够采起一个彻底不一样的方案来替代升级硬件:添加一个反向代理服务器来分担部分任务。反向代理服务器 位于运行应用的机器的前端,是用来处理网络流量的。只有反向代理服务器是直接链接到互联网的;和应用服务器的通信都是经过一个快速的内部网络完成的。性能优化
使用反向代理服务器能够将应用服务器从等待用户与 web 程序交互解放出来,这样应用服务器就能够专一于为反向代理服务器构建网页,让其可以传输到互联网上。而应用服务器就不须要等待客户端的响应,其运行速度能够接近于优化后的性能水平。服务器
添加反向代理服务器还能够给你的 web 服务器安装带来灵活性。好比,一个某种类型的服务器已经超载了,那么就能够轻松的添加另外一个相同的服务器;若是某个机器宕机了,也能够很容易替代一个新的。
由于反向代理带来的灵活性,因此反向代理也是一些性能加速功能的必要前提,好比:
负载均衡 (参见 Tip #2) – 负载均衡运行在反向代理服务器上,用来将流量均衡分配给一批应用。有了合适的负载均衡,你就能够添加应用服务器而根本不用修改应用。
缓存静态文件 (参见 Tip #3) – 直接读取的文件,好比图片或者客户端代码,能够保存在反向代理服务器,而后直接发给客户端,这样就能够提升速度、分担应用服务器的负载,可让应用运行的更快。
网站安全 – 反向代理服务器能够提升网站安全性,以及快速的发现和响应攻击,保证应用服务器处于被保护状态。
NGINX 软件为用做反向代理服务器而专门设计,也包含了上述的多种功能。NGINX 使用事件驱动的方式处理请求,这会比传统的服务器更加有效率。NGINX plus 添加了更多高级的反向代理特性,好比应用的健康度检查,专门用来处理请求路由、高级缓冲和相关支持。
Tip #2: 添加负载平衡
添加一个负载均衡服务器 是一个至关简单的用来提升性能和网站安全性的的方法。与其将核心 Web 服务器变得愈来愈大和愈来愈强,不如使用负载均衡将流量分配到多个服务器。即便程序写的很差,或者在扩容方面有困难,仅是使用负载均衡服务器就能够很好的提升用户体验。
负载均衡服务器首先是一个反向代理服务器(参见Tip #1)——它接受来自互联网的流量,而后转发请求给另外一个服务器。特别是负载均衡服务器支持两个或多个应用服务器,使用分配算法将请求转发给不一样服务器。最简单的负载均衡方法是轮转法round robin,每一个新的请求都会发给列表里的下一个服务器。其它的复制均衡方法包括将请求发给活动链接最少的服务器。NGINX plus 拥有将特定用户的会话分配给同一个服务器的能力。
负载均衡能够很好的提升性能是由于它能够避免某个服务器过载而另外一些服务器却没有须要处理的流量。它也能够简单的扩展服务器规模,由于你能够添加多个价格相对便宜的服务器而且保证它们被充分利用了。
能够进行负载均衡的协议包括 HTTP、HTTPS、SPDY、HTTP/二、WebSocket、FastCGI、SCGI、uwsgi、 memcached 等,以及几种其它的应用类型,包括基于 TCP 的应用和其它的第4层协议的程序。分析你的 web 应用来决定你要使用哪些以及哪些地方性能不足。
相同的服务器或服务器群能够被用来进行负载均衡,也能够用来处理其它的任务,如 SSL 末端服务器,支持客户端的 HTTP/1.x 和 HTTP/2 请求,以及缓存静态文件。
Tip #3: 缓存静态和动态的内容
缓存能够经过加速内容的传输速度来提升 web 应用的性能。它能够采用如下几种策略:当须要的时候预处理要传输的内容,保存数据到速度更快的设备,把数据存储在距离客户端更近的位置,或者将这几种方法结合起来使用。
有两种不一样类型数据的缓冲:
静态内容缓存。不常常变化的文件,好比图像(JPEG、PNG) 和代码(CSS,JavaScript),能够保存在外围服务器上,这样就能够快速的从内存和磁盘上提取。
动态内容缓存。不少 web 应用会针对每次网页请求生成一个新的 HTML 页面。在短期内简单的缓存生成的 HTML 内容,就能够很好的减小要生成的内容的数量,并且这些页面足够新,能够知足你的须要。
举个例子,若是一个页面每秒会被浏览10次,你将它缓存 1 秒,90%请求的页面都会直接从缓存提取。若是你分开缓存静态内容,甚至新生成的页面可能都是由这些缓存构成的。
下面由是 web 应用发明的三种主要的缓存技术:
1.缩短数据与用户的网络距离。把一分内容的拷贝放的离用户更近的节点来减小传输时间。
2.提升内容服务器的速度。内容能够保存在一个更快的服务器上来减小提取文件的时间。
3.从过载服务器上移走数据。机器常常由于要完成某些其它的任务而形成某个任务的执行速度比测试结果要差。将数据缓存在不一样的机器上能够提升缓存资源和非缓存资源的性能,而这是由于主机没有被过分使用。
对 web 应用的缓存机制能够在 web 应用服务器内部实现。首先,缓存动态内容是用来减小应用服务器加载动态内容的时间。其次,缓存静态内容(包括动态内容的临时拷贝)是为了更进一步的分担应用服务器的负载。并且缓存以后会从应用服务器转移到对用户而言更快、更近的机器,从而减小应用服务器的压力,减小提取数据和传输数据的时间。
改进过的缓存方案能够极大的提升应用的速度。对于大多数网页来讲,静态数据,好比大图像文件,构成了超过一半的内容。若是没有缓存,那么这可能会花费几秒的时间来提取和传输这类数据,可是采用了缓存以后不到1秒就能够完成。
举一个在实际中缓存是如何使用的例子, NGINX 和 NGINX Plus 使用了两条指令来设置缓存机制:proxy_cache_path 和 proxy_cache。你能够指定缓存的位置和大小、文件在缓存中保存的最长时间和其它一些参数。使用第三条(并且是至关受欢迎的一条)指令 proxy_cache_use_stale,若是提供新鲜内容的服务器忙碌或者挂掉了,你甚至可让缓存提供较旧的内容,这样客户端就不会一无所获。从用户的角度来看这能够很好的提升你的网站或者应用的可用时间。
NGINX plus 有个高级缓存特性,包括对缓存清除的支持和在仪表盘上显示缓存状态信息。
注意:缓存机制分布于应用开发者、投资决策者以及实际的系统运维人员之间。本文提到的一些复杂的缓存机制从 DevOps 的角度来看很具备价值,即对集应用开发者、架构师以及运维操做人员的功能为一体的工程师来讲能够知足它们对站点功能性、响应时间、安全性和商业结果(如完成的交易数)等须要。
Tip #4: 压缩数据
压缩是一个具备很大潜力的提升性能的加速方法。如今已经有一些针对照片(JPEG 和PNG)、视频(MPEG-4)和音乐(MP3)等各种文件精心设计和高压缩率的标准。每个标准都或多或少的减小了文件的大小。
文本数据 —— 包括HTML(包含了纯文本和 HTML 标签),CSS 和代码,好比 Javascript —— 常常是未经压缩就传输的。压缩这类数据会在对应用程序性能的感受上,特别是处于慢速或受限的移动网络的客户端,产生更大的影响。
这是由于文本数据常常是用户与网页交互的有效数据,而多媒体数据可能更多的是起提供支持或者装饰的做用。智能的内容压缩能够减小 HTML,Javascript,CSS和其它文本内容对带宽的要求,一般能够减小 30% 甚至更多的带宽和相应的页面加载时间。
若是你使用 SSL,压缩能够减小须要进行 SSL 编码的的数据量,而这些编码操做会占用一些 CPU 时间而抵消了压缩数据减小的时间。
压缩文本数据的方法不少,举个例子,在 HTTP/2 中,小说文本的压缩模式就特别调整了头部数据。另外一个例子是能够在 NGINX 里打开使用 GZIP 压缩。你在你的服务里预先压缩文本数据以后,你就能够直接使用 gzip_static 指令来处理压缩过的 .gz 版本。
Tip #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 占用率下降了不少。
Tip #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 协议。
做为支持这些协议的一个样例,NGINX 已经从一开始就支持了 SPDY,并且大部分使用 SPDY 协议的网站都运行的是 NGINX。NGINX 同时也很早对 HTTP/2 的提供了支持,从2015 年9月开始,开源版 NGINX 和 NGINX Plus 就支持它了。
通过一段时间,咱们 NGINX 但愿更多的站点彻底启用 SSL 而且向 HTTP/2 迁移。这将会提升安全性,同时也会找到并实现新的优化手段,简化的代码表现的会更加优异。
Tip #7: 升级软件版本
一个提升应用性能的简单办法是根据软件的稳定性和性能的评价来选在你的软件栈。进一步说,由于高性能组件的开发者更愿意追求更高的性能和解决 bug ,因此值得使用最新版本的软件。新版本每每更受开发者和用户社区的关注。更新的版本每每会利用到新的编译器优化,包括对新硬件的调优。
稳定的新版本一般比旧版本具备更好的兼容性和更高的性能。一直进行软件更新,能够很是简单的保持软件保持最佳的优化,解决掉 bug,以及提升安全性。
一直使用旧版软件也会阻止你利用新的特性。好比上面说到的 HTTP/2,目前要求 OpenSSL 1.0.1。在2016 年中期开始将会要求1.0.2 ,而它是在2015年1月才发布的。
NGINX 用户能够开始迁移到 NGINX 最新的开源软件 或者 NGINX Plus;它们都包含了最新的能力,如 socket 分割和线程池(见下文),这些都已经为性能优化过了。而后好好看看的你软件栈,把它们升级到你能升级到的最新版本吧。
Tip #8: Linux 系统性能调优
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 来设置,这能够快速的提升流量。
Tip #9: web 服务器性能调优
不管你是用哪一种 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,即每一个工人进程的空闲保活链接个数。这就能够提升链接的复用次数,减小须要从新打开全新链接的次数。
限制。限制客户端使用的资源能够提升性能和安全性。对于 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() ——被分配到了线程池
技巧。当改变任何操做系统或支持服务的设置时,一次只改变一个参数而后测试性能。若是修改引发问题了,或者不能让你的系统更快,那么就改回去。
Tip #10: 监视系统活动来解决问题和瓶颈
在应用开发中要使得系统变得很是高效的关键是监视你的系统在现实世界运行的性能。你必须能经过特定的设备和你的 web 基础设施上监控程序活动。
监视活动是最积极的——它会告诉你发生了什么,把问题留给你发现和最终解决掉。
监视能够发现几种不一样的问题。它们包括:
服务器宕机。
服务器出问题一直在丢失链接。
服务器出现大量的缓存未命中。
服务器没有发送正确的内容。
应用的整体性能监控工具,好比 New Relic 和 Dynatrace,能够帮助你监控到从远程加载网页的时间,而 NGINX 能够帮助你监控到应用交付端。当你须要考虑为基础设施添加容量以知足流量需求时,应用性能数据能够告诉你你的优化措施的确起做用了。
为了帮助开发者快速的发现、解决问题,NGINX Plus 增长了应用感知健康度检查 ——对重复出现的常规事件进行综合分析并在问题出现时向你发出警告。NGINX Plus 同时提供会话过滤功能,这能够阻止当前任务完成以前接受新的链接,另外一个功能是慢启动,容许一个从错误恢复过来的服务器追遇上负载均衡服务器群的进度。当使用得当时,健康度检查可让你在问题变得严重到影响用户体验前就发现它,而会话过滤和慢启动可让你替换服务器,而且这个过程不会对性能和正常运行时间产生负面影响。下图就展现了内建的 NGINX Plus 模块实时活动监视的仪表盘,包括了服务器群,TCP 链接和缓存信息等 Web 架构信息。
总结: 看看10倍性能提高的效果
这些性能提高方案对任何一个 web 应用均可用而且效果都很好,而实际效果取决于你的预算、你能花费的时间、目前实现方案的差距。因此你该如何对你本身的应用实现10倍性能提高?
为了指导你了解每种优化手段的潜在影响,这里是上面详述的每一个优化方法的关键点,虽然你的状况确定大不相同:
反向代理服务器和负载均衡。没有负载均衡或者负载均衡不好都会形成间歇的性能低谷。增长一个反向代理,好比 NGINX ,能够避免 web 应用程序在内存和磁盘之间波动。负载均衡能够将过载服务器的任务转移到空闲的服务器,还能够轻松的进行扩容。这些改变均可以产生巨大的性能提高,很容易就能够比你如今的实现方案的最差性能提升10倍,对于整体性能来讲可能提升的很少,可是也是有实质性的提高。缓存动态和静态数据。若是你有一个负担太重的 web 服务器,那么毫无疑问确定是你的应用服务器,只经过缓存动态数据就能够在峰值时间提升10倍的性能。缓存静态文件能够提升几倍的性能。压缩数据。使用媒体文件压缩格式,好比图像格式 JPEG,图形格式 PNG,视频格式 MPEG-4,音乐文件格式 MP3 能够极大的提升性能。一旦这些都用上了,而后压缩文件数据能够将初始页面加载速度提升两倍。优化 SSL/TLS。安全握手会对性能产生巨大的影响,对它们的优化可能会对初始响应产生2倍的提高,特别是对于大量文本的站点。优化 SSL/TLS 下媒体文件只会产生很小的性能提高。使用 HTTP/2 和 SPDY。当你使用了 SSL/TLS,这些协议就能够提升整个站点的性能。对 Linux 和 web 服务器软件进行调优。好比优化缓存机制,使用保活链接,分配时间敏感型任务到不一样的线程池能够明显的提升性能;举个例子,线程池能够加速对磁盘敏感的任务近一个数量级。