什么是HTTP/2? 它需要SSL吗? 在Nginx和Apache上启用

什么是HTTP/2?

HTTP/2是超文本传输协议的第二个主要版本,由IETF在2015年标准化(RFC 7540)。它旨在解决HTTP/1.1的性能限制,HTTP/1.1自1997年以来一直在使用,从未为如今资源密集型的网页而构建。

HTTP/1.1受到"队头阻塞"的困扰——连接上的每个请求必须等待前一个响应才能继续。浏览器通过为每个域打开最多六个并行连接来解决这个问题,这浪费资源并增加开销。HTTP/2通过多路复用解决了这个问题,使多个请求和响应能够同时在单个连接上流动。

HTTP/2 vs HTTP/1.1: 关键改进

特性 HTTP/1.1 HTTP/2
多路复用 否(每个连接1个请求) 是(1个连接中的多个请求)
头部压缩 无(头部在每个请求中重复) HPACK压缩减少开销
服务器推送 不支持 支持(服务器主动发送资源)
协议格式 文本格式(更大) 二进制(更小,解析更快)
流优先级 无 为资源分配优先级

HTTP/2如何击败HTTP/1.1: 多路复用、头部压缩、服务器推送

HTTP/2比HTTP/1.1更快,不是因为它增加了带宽,而是因为它重新设计了数据如何在线路上传输以消除浪费。三个变化做了大部分工作——多路复用、头部压缩和流优先级——所有这些都在单个TLS加密连接上协同工作。

多路复用——一条连接上的多个请求

在HTTP/1.1中,单个连接一次处理一个请求,必须等待其响应才能发送下一个。这是队头阻塞。浏览器通过为每个域打开最多六个并行连接来解决这个问题,每个连接都需要自己的TCP和TLS握手——浪费时间和服务器内存。HTTP/2完全改变了这个模型,通过将数据分割成小的"帧"并将每个帧绑定到一个编号的"流"。这允许许多请求和响应同时在一条连接上交错,然后在目标处按流ID重新组装。结果是:具有数十个图像、CSS和JavaScript文件的页面加载速度要快得多,特别是在高延迟网络上。

头部压缩(HPACK)——消除重复的头部开销

每个HTTP/1.1请求都包含大量头部——用户代理、接受、Cookie——这些在同一页面的每个请求中几乎相同。当页面发送数十个请求时,这些重复的头部会浪费带宽。HTTP/2通过HPACK解决这个问题,这是一个专门为头部构建的压缩算法。HPACK维护一个先前发送的头部的动态参考表,因此后续请求只发送索引参考而不是完整文本。这大大减少了具有长Cookie或许多头部的网站上的头部大小,降低TTFB并加快小型子资源的加载。

流优先级和二进制帧

HTTP/2使用二进制有线格式而不是HTTP/1.1的文本格式,使其更快、更精确地解析——不再需要解释空格或换行符。它还让客户端为每个流分配优先级,例如告诉浏览器在低于折线的图像之前加载渲染关键的CSS。服务器可以随后首先为重要资源分配带宽,帮助用户更快看到主要内容并改善核心网页指标。

简言之: 多路复用减少连接,HPACK缩小重复的头部,优先级将关键资源放在首位。这三个共同构成了HTTP/2在真实网站上优于HTTP/1.1的核心原因。

HTTP/2是否需要SSL?

HTTP/2规范(RFC 7540)在技术上支持明文(h2c)和TLS加密(h2)模式。但是,当今每个主要浏览器都仅支持HTTP/2通过HTTPS(TLS)。

实际上,这意味着如果您的网站仍然运行在HTTP上,即使您的服务器支持HTTP/2,您也不会受益。安装SSL证书并切换到HTTPS是启用HTTP/2之前的必要第一步。

底线: HTTP/2实际上需要HTTPS。首先安装SSL证书,然后按照下面的步骤在您的服务器上启用HTTP/2。

在Nginx上启用HTTP/2 (listen 443 ssl http2)

Nginx从1.9.5版本开始支持HTTP/2。启用它就像在监听端口443的服务器块的监听指令中添加http2一样简单。下面是一个完整的生产级配置,包括HTTP到HTTPS重定向和推荐的TLS设置:

# /etc/nginx/sites-available/example.com.conf

# HTTP block — redirect everything to HTTPS
server {
    listen 80;
    server_name example.com www.example.com;
    return 301 https://$host$request_uri;
}

# HTTPS block — enable HTTP/2 here
server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;       # IPv6
    server_name example.com www.example.com;

    ssl_certificate     /etc/ssl/certs/example.com.crt;
    ssl_certificate_key /etc/ssl/private/example.com.key;

    ssl_protocols       TLSv1.2 TLSv1.3;
    ssl_ciphers         HIGH:!aNULL:!MD5;
    ssl_session_cache   shared:SSL:10m;
    ssl_session_timeout 1d;

    root /var/www/example.com;
    index index.html index.php;
}

注意:在1.25.1之前的Nginx版本上,您必须将http2添加到您想要的每个listen指令——IPv4和IPv6——否则在没有http2的监听指令上到达的连接将只使用HTTP/1.1。

启用它就像将http2添加到监听指令一样简单:

方法1 — 将http2添加到服务器块 (Nginx 1.9.5–1.25.0)

server {
    listen 443 ssl http2;
    server_name example.com;

    ssl_certificate     /etc/ssl/certs/example.com.crt;
    ssl_certificate_key /etc/ssl/private/example.com.key;

    ssl_protocols TLSv1.2 TLSv1.3;
}

方法2 — Nginx 1.25.1+的新语法

server {
    listen 443 ssl;
    http2 on;
    server_name example.com;
    # ...
}
nginx -t && systemctl reload nginx

验证HTTP/2在Nginx上是否激活

curl -I --http2 https://example.com 2>&1 | grep "HTTP/"
# 预期输出: HTTP/2 200

在Apache上启用HTTP/2 (mod_http2, Protocols h2)

Apache通过mod_http2模块支持HTTP/2,自Apache 2.4.17起可用。启用它需要三个步骤:加载模块,在SSL虚拟主机中声明Protocols h2,并验证您运行的是兼容的MPM(event或worker)。顺序h2 h2c http/1.1很重要:h2是HTTP/2通过TLS,h2c是明文HTTP/2(内部使用),http/1.1是旧浏览器的回退——Apache在TLS握手期间通过ALPN协商双方支持的最高协议。

步骤1 — 启用模块

a2enmod http2
systemctl restart apache2

步骤2 — 添加Protocols指令

<VirtualHost *:443>
    ServerName example.com
    Protocols h2 h2c http/1.1
    # ...
</VirtualHost>

步骤3 — 检查MPM兼容性

Apache中的HTTP/2需要event或worker MPM。如果您使用prefork(在旧的Ubuntu安装上很常见),切换到event:

a2dismod mpm_prefork
a2enmod mpm_event
apachectl configtest && systemctl restart apache2

验证HTTP/2 + 什么是HTTP/3

一旦启用,确认您的网站确实通过HTTP/2响应,并了解下一个版本HTTP/3的不同之处,以便您可以规划未来的升级。

如何检查您的网站是否使用HTTP/2

什么是HTTP/3以及它与HTTP/2的不同之处

HTTP/3是HTTP协议的最新版本,旨在解决HTTP/2仍然存在的弱点。最重要的区别是传输层:HTTP/2运行在TCP上,而HTTP/3运行在QUIC上,QUIC构建在UDP之上。HTTP/2通过TCP的问题是,即使它在一条连接上多路复用许多流,如果任何流中的单个数据包丢失,TCP会停止所有流的传递,直到该数据包重新传输。这是TCP级别的队头阻塞,在移动或Wi-Fi网络上最明显,这些网络具有高丢包率。

HTTP/3中的QUIC独立管理每个流——如果一个流的数据包丢失,其他流继续流动而不等待。QUIC还将TLS 1.3握手与连接握手合并以加快设置(0-RTT/1-RTT),并支持连接迁移,让客户端在不重建整个连接的情况下切换网络(例如Wi-Fi到4G)。像HTTP/2一样,HTTP/3总是需要TLS并通过UDP端口443提供。

方面 HTTP/2 HTTP/3
传输层 TCP QUIC (基于UDP)
队头阻塞 仍然在TCP级别存在 无(流是独立的)
连接设置 单独的TCP + TLS步骤 合并的握手,更快(0-RTT/1-RTT)
连接迁移 不支持(需要重建) 支持(无缝切换网络)
加密 TLS(实际上强制) TLS 1.3始终强制

实际的建议是首先启用HTTP/2作为您的基线——它有广泛的支持并且易于配置。一旦您的服务器和CDN支持QUIC,添加HTTP/3作为额外的层,以便支持的浏览器受益,而不支持它的浏览器会自动回退到HTTP/2。

HTTP/2服务器推送

服务器推送允许服务器在浏览器请求资源之前主动发送资源(CSS、JS、字体),减少额外的往返:

# Nginx — 与HTML一起推送CSS和JS
server {
    location = /index.html {
        http2_push /css/style.css;
        http2_push /js/main.js;
    }
}

实际上,服务器推送的价值没有听起来那么大,因为浏览器已经缓存了资源。仅启用基本的HTTP/2多路复用就能为大多数网站带来最显著的性能收益。

HTTP/2和SEO

Google使用核心网页指标(LCP、INP、CLS)作为排名因素,HTTP/2直接改善这些指标通过:

常见问题

HTTP/3与HTTP/2有何不同?

HTTP/3使用QUIC协议(基于UDP而不是TCP),进一步降低连接延迟——特别是在不稳定的网络上。大多数现代浏览器支持HTTP/3,但服务器端支持不如HTTP/2普遍。HTTP/2仍然是大多数部署的实际标准。

AsiaGB虚拟主机支持HTTP/2吗?

是的。AsiaGB虚拟主机一旦安装SSL证书就支持HTTP/2。每个AsiaGB虚拟主机包都通过DirectAdmin包括免费的Let's Encrypt证书,所以所有客户都可以使用HTTP/2。

HTTP/2可能比HTTP/1.1更慢吗?

在资源极少的极简页面上(单个HTML文件,没有CSS或JS),差异微乎其微。对于具有数十个资源的典型页面,HTTP/2始终比HTTP/1.1更快。

我需要更改网站代码来启用HTTP/2吗?

不需要更改代码。HTTP/2在传输协议级别上运行,对您的HTML、CSS和JavaScript完全透明——现有的网络应用程序立即工作。也就是说,一些HTTP/1.1时代的优化可能不再必要,例如将CSS/JS连接成单个文件或使用图像雪碧图,因为多路复用已经高效处理许多文件。逻辑上分割文件实际上对缓存更好。但这些是改进,不是要求。

如果我的网站在Cloudflare或CDN后面,我需要在服务器上使用HTTP/2吗?

如果您的网站通过Cloudflare或其他CDN以代理模式提供,访问者连接到CDN边缘而不是直接连接到您的源服务器。所以HTTP/2(和HTTP/3)在用户和网站之间通常在CDN边缘自动启用。CDN和源服务器之间的连接使用源服务器支持的任何协议,所以在源服务器上启用HTTP/2仍然有用——但访问者已经从边缘获得HTTP/2。

我可以将Let's Encrypt与HTTP/2一起使用吗?

是的。HTTP/2只需要有效的SSL证书,不在乎哪个机构签发。Let's Encrypt是一个免费的DV证书,启用HTTP/2的方式与付费证书完全相同。DV、OV和EV证书之间的区别是身份验证级别,不是HTTP/2支持。

需要SSL证书来在您的网站上启用HTTP/2?

AsiaGB提供来自RapidSSL、GeoTrust和DigiCert的SSL证书——DV SSL起价฿1,000/年,通配符SSL起价฿5,000/年。包括完整的HTTP/2和OCSP装订支持。

查看所有SSL证书