今天我们将继续探讨HTTP性能优化的有效策略。
在上一节中,我们提到在整个HTTP系统中有三个主要的优化点,即服务器、客户端以及传输链路(包括“第一公里”和“中间一公里”)。由于客户端不在我们的直接控制范围内,因此实际的优化工作通常集中在服务器端。这部分可以进一步划分为后端与前端,其中后端涉及网站的后台服务,而前端则涵盖HTML、CSS及图像等内容,这些内容最终呈现给客户端用户。
明确了优化的方向后,具体如何实施HTTP性能优化呢?从总体上看,任何计算机系统的优化措施可以归纳为以下几类:硬件与软件、内部与外部、付费与免费。
硬件升级
最直接的优化方式莫过于投资于现有的硬件设施,如更换更强劲的CPU、速度更快的网卡、更高的带宽或更多的服务器。这种做法能迅速提高网站的服务能力,从而实现HTTP性能的优化。
外部软件和服务采购
除了硬件投资,购买外部软件或服务也是另一种有效的优化途径。例如,使用CDN(内容分发网络)能够显著改善“中间一公里”的传输效率,同时提供多种专业优化功能。将网站托管至CDN,就如同给网站装上了喷气式引擎,几乎无需额外努力即可达到良好的优化效果。
然而,上述“付费”解决方案往往缺乏技术深度,适合那些寻求简便方案的用户。接下来,我们将重点关注网站内部的、无需花费额外成本的软件优化方法。
内部软件优化
内部软件优化可以总结为三个关键词:开源、节流、缓存。
开源
这里的“开源”并不是指开放源代码,而是指挖掘网站服务器本身的潜能,在保持现有条件不变的前提下,尽可能提升其服务能力。首先,推荐使用高性能的Web服务器,如Nginx或OpenResty,避免选择基于Java、Python或Ruby的服务器作为前端服务器,后者更适合处理后端业务逻辑。通过Nginx的高效反向代理功能实现动静态内容的分离,动态页面由Tomcat、Django或Rails处理,而静态资源如图片和样式表则交由Nginx管理。
Nginx和OpenResty还提供了众多配置选项以进一步优化性能,例如禁用负载均衡锁定、增加连接池大小、CPU绑定等。特别值得注意的是,务必启用HTTP长连接,因为TCP和SSL新连接的建立成本极高,可能会占据客户端总延迟的一半以上。长连接虽然不能减少连接握手的时间,但它能将这一成本分散到多个请求中,从而降低整体延迟。
此外,现代操作系统普遍支持TCP Fast Open特性,类似于TLS中的False Start机制,能够在首次握手时就开始数据传输,实现0-RTT。因此,建议在操作系统和Nginx中启用此功能,以减少内外网的握手延迟。
以下是启用长连接等优化设置的一个Nginx配置实例,同时实现了动静态内容的分离:
server {
listen 80 deferred reuseport backlog=4096 fastopen=1024;
keepalive_timeout 60;
keepalive_requests 10000;
location ~* \.(png)$ {
root /var/images/png/;
}
location ~* \.(php)$ {
proxy_pass http://php_back_end;
}
}
节流
“节流”旨在减少客户端与服务器间的数据传输量,以便在有限的带宽内传输更多信息。实现这一目标的基本方法是利用HTTP协议自带的数据压缩功能,除了传统的gzip之外,还可以考虑使用br(Brotli)压缩算法,后者具有更好的压缩效果。
在应用数据压缩时,应合理选择压缩级别,避免追求极致压缩比导致服务器计算资源消耗过大,进而影响响应时间和整体性能。对于不同类型的数据,还可以采取特定的压缩策略。例如,对于HTML、CSS和JavaScript等文本文件,可以通过移除代码中的空白字符、换行符和注释来实现“压缩”,尽管这样做会使代码变得难以阅读,但不会影响浏览器的执行效果。
图片是HTTP传输中占用大量带宽的内容之一,即使已经经过压缩,仍有优化空间。常见的优化措施包括删除图片中的元数据(如拍摄时间、地点等)、适当降低分辨率和尺寸,以及选择合适的图片格式,如JPEG用于有损压缩,WebP用于无损压缩。
对于较小的文本或图片文件,还可以采用资源合并(Concatenation)的方法,即将多个小文件合并成一个较大的文件,一次性下载到客户端,再通过JavaScript或CSS进行分割使用。这种方法的优点在于减少了请求次数,但处理过程相对复杂。
以上讨论的压缩技术主要针对HTTP响应体中的数据。而在HTTP/1.x中,头部信息无法被压缩,但我们可以通过移除不必要的头部字段(如Server、X-Powered-By等)来减小头部的体积。
网站通常利用Cookie来保存用户信息,每次浏览器访问时都会携带这些Cookie,这增加了数据的冗余。因此,应减少Cookie的使用频率,缩小其记录的信息量,并通过设定domain和path属性来限制Cookie的影响范围,从而减少不必要的Cookie传输。若客户端支持现代浏览器,可考虑采用HTML5提供的Web Local Storage,以替代Cookie。
除了数据压缩外,性能优化还包括两大方面:域名管理和重定向处理。
DNS域名解析过程消耗较多时间,当网站拥有多个域名时,解析每个域名以获取IP地址会增加成本。因此,建议精简域名数量至两到三个,以缩短域名解析时间,使客户端能更快地从系统缓存中获取解析结果。
重定向导致的客户端延迟同样显著,因为它不仅增加了额外的请求往返次数,还可能触发新的域名DNS解析,这是HTTP前端性能优化中的重要禁忌。除非绝对必要,否则应尽量避免使用重定向,或利用Web服务器实现“内部重定向”。
缓存在提高HTTP性能方面扮演着关键角色,它不仅是HTTP,也是所有计算机系统性能优化的核心工具。结合上述的“开源”与“节流”策略,合理运用缓存能够显著提升HTTP性能。
在网站内部,可以通过部署Memcache、Redis、Varnish等专用缓存服务,将计算的中间结果及资源存储于内存或硬盘中。Web服务器首先查询缓存系统,若有相关数据则直接反馈给客户端,从而节省了访问后端服务的时间。
在传输路径的中间环节,缓存同样是性能优化的关键。CDN的网络加速功能即基于缓存技术,可以说没有缓存就没有CDN的存在。
要充分利用缓存,关键在于理解其工作原理(详情参见第20讲和第22讲)。为每个资源添加ETag和Last-modified字段,并通过Cache-Control、Expires等指令配置合适的缓存控制属性。基本的设置包括max-age,用于指定资源可被缓存的时间长度。例如,图片和CSS等静态资源可设置较长的缓存时间,而动态资源除非要求极高,也应设定较短的缓存时间。
当资源首次抵达客户端后会被缓存,只要仍在有效期内,客户端就不会再次向服务器发起请求,这就是所谓的“最快速的请求是没有请求的请求”。
除了上述“开源”、“节流”和“缓存”三大策略,HTTP性能优化的另一个方向是将协议版本从HTTP/1升级至HTTP/2。通过“飞翔篇”的介绍,我们了解到HTTP/2具备消除应用层头部阻塞、头部压缩、二进制帧、多路复用、流量控制及服务器推送等多项优势,极大地提高了HTTP传输效率。
这些特性本质上是对“开源”和“节流”的进一步优化,但由于它们已集成于协议内部,因此只需切换到HTTP/2即可显著改善网站性能。然而需要注意的是,某些针对HTTP/1的有效优化措施在HTTP/2环境下可能会产生相反的效果。
例如,HTTP/2推荐单个域名下的所有请求共用同一个TCP连接以达到最佳性能。多域名策略反而会导致带宽和服务器资源的浪费,降低HTTP/2的效能,故域名精简在HTTP/2环境中尤为重要。
此外,在HTTP/1中,资源合并有助于减少多次请求带来的开销;而在HTTP/2中,由于引入了头部压缩和多路复用技术,传输小型文件的成本极低,因此资源合并不再具有明显优势。事实上,资源合并还会削弱缓存的有效性,因为一旦某个小文件更新,整个缓存集都将失效,需重新下载全部内容。
鉴于当前广泛使用的高带宽和CDN环境,应尽量减少资源合并(如JavaScript、CSS图片合并,数据内嵌等),保持资源的细颗粒度,以便更充分地利用缓存机制的优势。