01 HTTP性能优化

一、哪些地方存在性能问题

  • 从 HTTP 最基本的“请求 - 应答”模型看,这个模型有两个角色:客户端和服务器,还有中间的传输链路,考查性能就可以看这三个部分。

1. HTTP服务器

  • 它一般运行在 Linux 操作系统上,用 Apache、Nginx 等 Web 服务器软件对外提供服务,所以,性能的含义就是它的服务能力,也就是尽可能多、尽可能快地处理用户的请求。
  • 衡量服务器性能的主要指标有三个:吞吐量(requests per second)、并发数(concurrency)和响应时间(time per request)。

1. 吞吐量

  • 吞吐量就是我们常说的 RPS,每秒的请求次数,也有叫 TPS、QPS,它是服务器最基本的性能指标,RPS 越高就说明服务器的性能越好。

2. 并发数

  • 并发数反映的是服务器的负载能力,也就是服务器能够同时支持的客户端数量,当然也是越多越好,能够服务更多的用户。

3. 响应时间

  • 响应时间反映的是服务器的处理能力,也就是快慢程度,响应时间越短,单位时间内服务器就能够给越多的用户提供服务,提高吞吐量和并发数。

4. 其他

  • 服务器还要考虑 CPU、内存、硬盘和网卡等系统资源的占用程度,利用率过高或者过低都可能有问题。

5. 性能测试工具

  • 在 Linux 上,最常用的性能测试工具可能就是 ab
#指定了并发数 100,总共发送 10000 个请求:
ab -c 100 -n 10000 'http://www.xxx.com'
  • 系统资源监控方面,Linux 自带的工具也非常多

    • uptime、top、vmstat、netstat、sar 等等
  • 服务器的性能优化方向:合理利用系统资源,提高服务器的吞吐量和并发数,降低响应时间。

2. HTTP客户端

  • 客户端是信息的消费者,一切数据都要通过网络从服务器获取,所以它最基本的性能指标就是“延迟”(latency)。

1. 延迟的可能原因

  1. “不可逾越”的障碍——光速

    • 因为地理距离而导致的延迟是无法克服的,访问数千公里外的网站显然会有更大的延迟。
  2. 宽带

    • 包括接入互联网时的电缆、WiFi、4G 和运营商内部网络、运营商之间网络的各种带宽
    • 每一处都有可能成为数据传输的瓶颈,降低传输速度,增加延迟。
  3. DNS 查询

    • 如果域名在本地没有缓存,就必须向 DNS 系统发起查询,引发一连串的网络通信成本,而在获取 IP 地址之前客户端只能等待,无法访问网站。
  4. TCP 握手

    • 必须要经过 SYN、SYN/ACK、ACK 三个包之后才能建立连接,它带来的延迟由光速和带宽共同决定。

2. 测试

  1. WebPageTest
    • 它的特点是在世界各地建立了很多的测试点,可以任意选择地理位置、机型、操作系统和浏览器发起测试,非常方便,用法也很简单
    • image.png
      • 图里面的这些指标都是含义
        • 因为有“队头阻塞”,浏览器对每个域名最多开 6 个并发连接(HTTP/1.1),当页面里链接很多的时候就必须排队等待(Queued、Queueing),这里它就等待了 1.62 秒,然后才被浏览器正式处理;
        • 浏览器要预先分配资源,调度连接,花费了 11.56 毫秒(Stalled);
        • 连接前必须要解析域名,这里因为有本地缓存,所以只消耗了 0.41 毫秒(DNS Lookup);
        • 与网站服务器建立连接的成本很高,总共花费了 270.87 毫秒,其中有 134.89 毫秒用于 TLS 握手,那么 TCP 握手的时间就是 135.98 毫秒(Initial connection、SSL);
        • 际发送数据非常快,只用了 0.11 毫秒(Request sent);
        • 之后就是等待服务器的响应,专有名词叫 TTFB(Time To First Byte),也就是“首字节响应时间”,里面包括了服务器的处理时间和网络传输时间,花了 124.2 毫秒;
        • 接收数据也是非常快的,用了 3.58 毫秒(Content Dowload)。

3. HTTP 传输链路

  • 客户端和服务器之间的传输链路,它也是影响 HTTP 性能的关键。

1. 三公里

  • image.png
  1. 第一公里

    • 指网站的出口,也就是服务器接入互联网的传输线路,它的带宽直接决定了网站对外的服务能力,也就是吞吐量等指标
    • 显然,优化性能应该在这“第一公里”加大投入,尽量购买大带宽,接入更多的运营商网络。
  2. 中间一公里

    • 由许多小网络组成的实际的互联网,其实它远不止“一公里”,而是非常非常庞大和复杂的网络,地理距离、网络互通都严重影响了传输速度
    • 好在这里面有一个 HTTP 的“好帮手”——CDN,它可以帮助网站跨越“千山万水”,让这段距离看起来真的就好像只有“一公里”。
  3. 最后一公里

    • 用户访问互联网的入口,对于固网用户就是光纤、网线,对于移动用户就是 WiFi、基站
  4. 第零公里

    • 网站内部的 Web 服务系统
    • 它其实也是一个小型的网络(当然也可能会非常大),中间的数据处理、传输会导致延迟,增加服务器的响应时间,也是一个不可忽视的优化点。

二、性能优化

  • 可优化的环节,分别是服务器、客户端和传输链路(“第一公里”和“中间一公里”),
  • 但因为我们是无法完全控制客户端的,实际上的优化工作通常是在服务器端。这里又可以细分为后端和前端,后端是指网站的后台服务,而前端就是 HTML、CSS、图片等展现在客户端的代码和数据。

1. 花钱

1. 投资购买现成的硬件最简单的优化方式

  • 比如换上更强的 CPU、更快的网卡、更大的带宽、更多的服务器,效果也会“立竿见影”,直接提升网站的服务能力,也就实现了 HTTP 优化。

2. 花钱购买外部的软件或者服务也是一种行之有效的优化方式

  • 最“物有所值”的应该算是 CDN 了

2. 不花钱

1. 开源

  • 指抓“源头”,开发网站服务器自身的潜力,在现有条件不变的情况下尽量挖掘出更多的服务能力。
  1. 选用高性能的 Web 服务器,最佳选择当然就是 Nginx/OpenResty
    • 尽量不要选择基于 Java、Python、Ruby 的其他服务器,它们用来做后面的业务逻辑服务器更好。
    • 利用 Nginx 强大的反向代理能力实现“动静分离”,动态页面交给 Tomcat、Django、Rails,图片、样式表等静态资源交给 Nginx。
    • Nginx 或者 OpenResty 自身也有很多配置参数可以用来进一步调优
      • 比如说禁用负载均衡锁、增大连接池,绑定 CPU 等等
      • 特别要说的是,对于 HTTP 协议一定要启用长连接
    • 在现代操作系统上都已经支持 TCP 的新特性“TCP Fast Open”(Win10、iOS9、Linux 4.1),它的效果类似 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;
  }
}

2. 节流

  • 减少客户端和服务器之间收发的数据量,在有限的带宽里传输更多的内容。

2.1 压缩

  1. ”最基本的做法就是使用 HTTP 协议内置的“数据压缩”编码,不仅可以选择标准的 gzip,还可以积极尝试新的压缩算法 br,它有更好的压缩效果。

    • 不过在数据压缩的时候应当注意选择适当的压缩率,不要追求最高压缩比,否则会耗费服务器的计算资源,增加响应时间,降低服务能力,反而会“得不偿失”。
  2. 有针对性地采用特殊的压缩方式。

    1. HTML/CSS/JavaScript 属于纯文本,就可以采用特殊的“压缩”,去掉源码里多余的空格、换行、注释等元素。
    2. 图片在 HTTP 传输里占有非常高的比例,虽然它本身已经被压缩过了,不能被 gzip、br 处理,但仍然有优化的空间。
      • 去除图片里的拍摄时间、地点、机型等元数据,适当降低分辨率,缩小尺寸。
      • 图片的格式也很关键,尽量选择高压缩率的格式,有损格式应该用 JPEG,无损格式应该用 Webp 格式。
    3. 对于小文本或者小图片,还有一种叫做“资源合并”(Concatenation)的优化方式
      • 把许多小资源合并成一个大资源,用一个请求全下载到客户端,然后客户端再用 JavaScript、CSS 切分后使用,好处是节省了请求次数,但缺点是处理比较麻烦。
  3. 在 HTTP/1 里没有办法可以压缩 header,采取一些手段来减少 header 的大小,不必要的字段就尽量不发

    • 例如 Server、X-Powered-By
  4. 尽可能减少 Cookie 的传输。如果客户端是现代浏览器,还可以使用 HTML5 里定义的 Web Local Storage,避免使用 Cookie。

2.2 域名

  1. DNS 解析域名会耗费不少的时间,如果网站拥有多个域名,那么域名解析获取 IP 地址就是一个不小的成本,
    • 适当“收缩”域名,限制在两三个左右,减少解析完整域名所需的时间,让客户端尽快从系统缓存里获取解析结果

2.3 重定向

  1. 重定向引发的客户端延迟也很高,
    • 它不仅增加了一次请求往返,还有可能导致新域名的 DNS 解析,是 HTTP 前端性能优化的“大忌”。除非必要,应当尽量不使用重定向,或者使用 Web 服务器的“内部重定向”。

3. 缓存

  1. 在“中间一公里”,缓存更是性能优化的重要手段

    • CDN 的网络加速功能就是建立在缓存的基础之上的,可以这么说,如果没有缓存,那就没有 CDN。
  2. 利用好缓存功能的关键是理解它的工作原理

    • 为每个资源都添加 ETag 和 Last-modified 字段,再用 Cache-Control、Expires 设置好缓存控制属性。
    • 其中最基本的是 max-age 有效期,标记资源可缓存的时间。对于图片、CSS 等静态资源可以设置较长的时间,比如一天或者一个月,对于动态资源,除非是实时性非常高,也可以设置一个较短的时间,比如 1 秒或者 5 秒。
    • 这样一旦资源到达客户端,就会被缓存起来,在有效期内都不会再向服务器发送请求,也就是:“没有请求的请求,才是最快的请求。”

4. 升级HTTP/2

  • 它消除了应用层的队头阻塞,拥有头部压缩、二进制帧、多路复用、流量控制、服务器推送等许多新特性,大幅度提升了 HTTP 的传输效率。

你可能感兴趣的:(01 HTTP性能优化)