1. HTTP 连接管理
1.1 短连接和长连接的区别
image短连接:每次请求-响应,都需要建立和断开 TCP 连接,而 TCP 连接相比比较耗时,所以,短连接效率低。
长连接:当 TCP 连接建立后,状态会被保持,后续的请求-响应不会再建立 TCP 连接了。如果在一定时间内客户端-服务器之间没有再次发送任何 HTTP 请求-响应数据包,比如:30 分钟,会自动断开 TCP 连接。
1.2 长连接存在的问题
服务器需要在内存中保存当前状态,如果出现大量的空闲长连接连而不发,就会耗尽服务器的资源,导致服务器无法为真正的用户提供服务。
解决方法
一定时间无“请求-响应”数据包传输时,断开长连接。
常见的服务器长连接策略(nginx)
- 使用
keep-timeout
指令,设置长连接超时时间 - 使用
keep-requests
指令,设置长连接可以发送的最大请求数 - 同时配置
keep-timeout
和keep-requests
2. HTTP 队头阻塞
2.1 问题描述
HTTP 收发数据是一个先进先出的“串行”队列,如果队首的请求由于处理的太慢,后面的数据就不得不等待,导致其它的请求承担了不应有的时间成本。
2.2 优化方法
并发连接
一般会创建一个连接池,对连接进行复用,来进行并发的请求,也就是只要连接池里的连接没有被使用完,每个连接都是并发执行的,不会出现由于串行导致的队头阻塞问题。
域名分片
使用多个域名指向同一个服务器,突破 HTTP 和浏览器对并发数量的限制。
3. HTTP 重定向
3.1 HTTP 重定向的方式
由服务器控制,并使用状态码 301/302 + 响应头字段 Location: 重写向网址
来定义重定向。
其中,这里的域名可以是绝对 URI(带域名)或相对 URI(只带 path 和 query 部分)。
3.2 重定向的种类
301:永久重定向。意思是原 URI 已经“永久”的不存在了。搜索引擎的爬虫看到了 301,会更新数据库,不再使用老的 URI。一般的应用场景为:启用新域名、服务器切换到新的机房、网站目录层次重构等。
302:临时重定向。意思是 URI 处于临时维护状态。搜索引擎的爬虫会认为原来的 URI 仍然有效,但暂时不可用,所以只会执行简单的跳转动作不记录新的 URI。一般应用场景为网站维护。
3.3 重定向可能导致的问题
- 循环跳转问题。由于设置不合理,导致跳转中出现了环。好在这个问题一般的浏览器做了都有做的相应处理
- 性能损耗。重定向由原来的一次请求变成了两次请求,如果大量的跳转就会对服务器产生影响
4. Cookie
4.1 Cookie 的工作原理
image这里需要使用两个头字段。分别是:
- 服务端的
Set-Cookie
头字段 - 客户端的
Cookie
头字段
浏览器首次访问服务器时,服务器是不知道它的身份的,就会为该客户端创建一个独特的身份标识,格式是“key=value”的形式,然后放进 Set-Cookie
字段里,随响应数据一起发送给客户端。
浏览器收到带有 Set-Cookie
的字段时,会将其保存起来,下次再请求的时候,就是通过 Cookie 头字段将保存的 Cookie 信息带给服务器。
注意
浏览器如果要发送多个 key-value
的信息给浏览器,会通过添加多个 Set-Cookie
头字段的方式来进行响应。而客户端在请求的时候,并不需要通过添加多个 Cookie,而只需要将多个 key-value
键值对通过 “;” 分隔即可。
同时,Cookie 是由浏览器保存的,所以,换了浏览器后,需要重新发送或保存 Cookie。
4.2 常见的 Cookie 属性
- Expires:使用绝对时间点。比如:2020 年 12 月 21 日失效
- Max-Age:使用的是相对时间点,单位秒。比如:过 10000s 后失效
- Domain:指定作用域中的域名,表示当前 Cookie 所属的域名
- Path:指定作用域中的路径,表示当前 Cookie 所属域名下的路径
- HttpOnly:表示此 Cookie 只允许浏览器访问,禁止其它方式访问,浏览器的 JS 引擎会禁用访问 Cookie 的 API
- SameSite:可以防范跨站请求伪造,设置成
sameSite=strict
表示严格限制 Cookie 不能随着跳转链接跨站发送 - Secure:表示这个 Cookie 仅能用 Https 协议加密传输,但 Cookie 本身还是明文的
Expires 和 Max-Age 同时出现
浏览器会优先使用 Max-Age
来作为失效的计算时间。
4.3 Cookie 的应用
身份识别
保存用户的登录信息,实现会话事务。
广告追踪
一般像 Google 这样的广告商会偷偷给你贴上 Cookie 小纸条,当你上其它网站的时候,别的广告就能读取出你的身份,然后给你推送广告。
而这里的 Cookie 小纸条等一般都是第三方 Cookie。
5. HTTP 缓存控制
5.1 服务器缓存
image- 浏览器发现本地无缓存,就向服务器发送请求
- 服务器响应请求,返回资源,同时标记资源的有效期
- 浏览器缓存资源,等待下次重用
Cache-Control 响应头字段
服务器使用 Max-Congtrol
响应头字段来标记资源的有效期,如:max-age=30,表示缓存时间为 30s。
Cache-Contrl 值的范围:
- no-store:不允许使用缓存,例如:秒杀页面
- no-cache:可以缓存,但在使用之前需要去服务器上验证是否过期,是否有新版本
- must-revalidate:正常缓存,过期了,需要去服务器重新获取
缓存流程图
image5.2 客户端缓存控制
Cache-Control
浏览器也可以使用 Cache-Control
来进行缓存控制。
当点击刷新(F5)时,浏览器会在请求头中添加 Cache-Control: max-age=0
,此时,会向服务器发送请求。
当强制刷新时(Ctrl + F5)浏览器会在请求头中添加 Cache-Control: no-cache
,此时,也会向服务器发送请求。
除刷新或强制刷新的操作外,其它时候浏览器都不会使用 Cache-Control
请求头字段,也就是当成一个正常的请求,会先去读本地是否有缓存。
条件请求
If-Modified-Since
和 Last-Modified
通过修改时间来判断文件是否被修改,是否需要更新请求新的数据。
If-None-Match
和 ETag
通过文件内容是否有变化,或者变化是否大来判断是否需要请求新的数据。
Last-Modefied:表示资源最后修改的时间。
ETag:资源的唯一标识,类似于 MD5,用来区分文件是否变化。
6. HTTP 代理
6.1 什么是 HTTP 代理服务
代理服务:服务本身不产生内容,而是处理中间位置转发上下游的请求和响应,具有双重身份。
6.2 代理的作用
负载均衡
通过请求分发到不同的服务器,来达到负载均衡的目的。
健康检查
使用“心跳”等监控后端服务器,如果出现问题,就将其从集群移除,保证服务的高可用。
安全防护
保护后端服务器,限制 IP 地址或流量,抵御网络攻击和过载。
加密卸载
对外使用 SSL/TLS 加密通信认证,而在安全内网不加密,消除内部通信加密成本。
数据过滤
拦截上下行数据,通过策略来过滤请求或响应。
内容缓存
暂存,利用服务器响应。
6.3 代理相关头字段
Via
代理服务器需要通过 Via 来表明代理的身份。请求头或响应头都可以出现。
每经历一个代理服务器,都会在 Via 头字段的值后面追加当前代理服务器的信息。
imageX-Forward-For(非 HTTP 协议标准字段)
表示每经历一个代理服务器,就将当前服务器的 IP 追加进来。
X-Real-IP(非 HTTP 协议标准字段)
只记录客户端 IP 地址,而不关心代理服务器的 IP 地址。
为什么需要知道客户端的 IP 地址
主要是方便服务器做访问控制、用户画像和统计分析等。
6.4 HTTP Proxy 代理抓包
image- 客户端 55061 先用 TCP 三次握手连接到代理的 80 端口,然后发送 GET 请求
- 代理代表客户端,用 55063 端口连接到源服务器,也是三次握手
- 代理连接源服务器成功后,发送了一个 HTTP/1.0 的 GET 请求
- 因为 HTTP/1.0 默认是短连接,在接收到服务器响应报文后立即用四次握手关闭连接
- 代理拿到响应报文后再发回给客户端,完成一次代理任务
6.5 代理协议
为什么会有代理协议
主要是由于代理服务器如果想要操作代理信息就必须解析 HTTP 报头的 X-Forward-For
字段,使得原本只需要转发消息的代理服务器,还需要费力解析数据再修改数据,会降低代理的转发性能。
另一个原因是:使用 X-Forward-For
头字段记录代理服务器的 IP,就必须修改原始报文,在一些情况下,如:Https 通信被加密,是不可能修改报文的。
代理协议
代理协议分为 v1 和 v2 两个版本。其中,v1 是明文;v2 是二进制格式。
v1:在 HTTP 报文前增加了一行 ASCII 码文本,相当于添加了一个代理头。具体的格式为:PROXY + TCP4/6 + 请求 IP 地址 + 应答方 IP 地址 + 请求方端口号 + 应答方端口号 + 回车换行(\r\n)。
PROXY TCP4 1.1.1.1 2.2.2.2 55555 80\r\n
GET / HTTP/1.1\r\n
Host: www.xxx.com\r\n
\r\n
好处:服务器拿到这样的报文,只需要解析第一行就可以拿到客户端地址。
7. 缓存代理
7.1 什么是缓存代理
缓存代理主要是代理服务器为 HTTP 服务器缓存数据,让客户端请求不需要到达源服务器,就能获得到相应的数据,进行返回,减少源服务的访问压力。
image代理服务器在收到源服务器返回的报文后,在将报文返回给客户端的同时,也将报文存入到自己的 Cache 里。
缓存代理服务器即是客户端,又是服务器
在面向源服务器时,缓存代理服务器是客户端;在面向客户端时,缓存代理服务器又是服务器。所以,缓存代理服务器可以同时使用 Cache-Control
的各种属性来实现缓存控制策略。
7.2 客户端的缓存控制
imagemax-stale:如果代理上的缓存过期了,也是可以接受到,但是过期时间不能太长,超过 x 秒后也会不要。
min-fresh:缓存必须有效,必须在 x 秒后必须有效。
only-if-cached:只接受代理缓存的数据,不接收来自源服务器的响应。如果代理没有或缓存过期,则返回一个 504(Gateway Timeout)。
Cache-Control: public,max-age=10,s-maxage-30
数据可以被缓存到代理服务器和浏览器。其中,可以缓存在代理服务器 30s,浏览器为 10s。
8. HTTPS
8.1 什么样的通信过程才是安全的?
如果通信过程具有四个特性:
- 机密性:只能由可信的人访问,简单来说就是不能让不相关的人看到不该看的东西
- 完整性:数据在传输的过程中,没有被窜改
- 身份认证:确认对方的真实身份,也就是证明“你就是你”
- 不可否认:也叫不可抵赖性,意思是不能否认已经发生过的行为
8.2 什么是 HTTPS?
HTTPS 是在 HTTP 与 TCP 层之间加了一层安全层,主要对应的协议为 SSL/TLS,其中,TLS 是 SSL 3.0 改名而来的,而 SSL 是由网景公司开发的。
目前 TLS 的版本经历了 V1.0(就是 SSL 的 V3.1) V1.1、V1.2 和 V1.3 四个版本。其中,应用最广泛的是 TLS 1.2,之前的版本已经被验证了是不安全的。
TLS 由哪些子协议组成
TLS 由记录协议、握手协议、警告协议、变更密码规范协议、扩展协议等子协议组成。
浏览器和服务器在进行连接时需要选择一组恰当的加密算法来实现安全通信,这些算法的组合被称为“密码套件”。
image上图分别罗列了客户端和服务端所支持的“密码套件”,而最终选择了 ECDHE-RSA-AES256-GCM-SHA384
。
密码套件由四个部分组成:密钥交换算法 + 签名算法 + 对称加密算法 + 摘要算法。
ECDHE-RSA-AES256-GCM-SHA384:表示握手时使用 ECDHE
算法进行密钥交换,用 RSA 签名和身份认证,握手后,通信使用 AES 对称算法,密钥长度为 256 位,分组模式为 GCM,摘要算法 SHA384 用于消息认证和产生随机数。
OpenSSL 库
OpenSSL 是一个著名的密码学工具包,几乎支持所有公开的加密算法和协议,很多应用软件使用 OpenSSL 来作为底层库实现 TLS 功能,包括 Apache 和 Ngnix。
9. 对称加密与非对称加密
9.1 对称加密
对称加密:加密和解密时使用的密钥都是同一个,是“对称”的。只要保证了密钥的安全,那整个通信过程就可以说具有了机密性。TLS 里提供了多种对称加密方式,但基本上只有 AES 和 chacha20 被认为是安全的。
加密分组模式
它可以让算法用固定长度的密钥加密任意长度的明文。
9.2 非对称加密
TLS 中常用的非对称加密只有 DSA、RSA、ECC 等几种。目前推荐的是 RSA 2048 位。
ECC:比起 RSA,ECC 在安全强度和性能上都有明显的优势。160 位的 ECC 相当于 1024 位的 RSA。而 224 位的 ECC 相当于 2048 位的 RSA。
私钥和公钥的关系
公钥和私钥具体“单向性”的特性,虽然都可以用来加密、解密,但公钥加密后,只能用私钥来解密,反过来,私钥加密后也只能用公钥来解密。
有了非对称加密,还需要对称加密技术么?
由于非对称加密是基于复杂的数学难题,运算速度很慢,即使是 ECC 也比 AES 差几个数量级。
下面是 AES 和 RSA 性能的对比:
aes_128_cbc enc/dec 1000 times : 0.97ms, 13.11MB/s
rsa_1024 enc/dec 1000 times : 138.59ms, 93.80KB/s
rsa_1024/aes ratio = 143.17
rsa_2048 enc/dec 1000 times : 840.35ms, 15.47KB/s
rsa_2048/aes ratio = 868.13
9.3 混合加密
密钥交换过程
在通信刚开始的时候使用非对称算法,比如:RSA、ECDHE,首先解决密钥交换的问题。
然后用随机数产生对称算法使用的 会话密钥
,再用公钥加密。会话密钥一般 16 或 32 字节。
对方拿到密文后用私钥解密,取出会话密钥。这样就完成了密钥交换的过程。后续传输数据使用对称加密。
10. 数字签名和证书
10.1 完整性
实现完整性的手段是:摘要算法,也称散列函数和哈希函数。
10.2 摘要算法
任意长度的字符串经过摘要算法处理后,都会变成长度固定、而且独一无二的“摘要”字符串,就好像为这段数据生成了一个指纹。
TLS 使用摘要算法来生成随机数。TLS 推荐的摘要算法是 SHA-2。而 MD5 和 SHA-1 由于安全强度比较低,已被禁止使用。
摘要算法与非对称加密算法的区别
摘要算法只有通过算法生成的密文,没有密钥,加密后的数据无法解密。而非对称加密算法既有密文,也有密钥。
TLS 中摘要算法存在的问题
如果明文传输,那么黑客可以修改消息后把摘要也一起改了,网站还是鉴别不出完整性。
所以,真正的完整性需要建立在机密性之上,在混合加密系统里用“会话密钥”加密消息和摘要。这样由于消息和消息摘要都被加密了,而密钥只有客户端才知道,所以,黑客无法修改数据。
image10.3 数字签名
没有数字签名之前,存在的问题
黑客可以伪造网站来窃取信息。而反过来,他也可以伪装成你,向网站发送支付、转账等信息,网站没有办法确认你的身份,钱可能就这么被偷走了。
数字签名的实现
使用“私钥”加摘要算法,就可以实现数字签名,同时,实现“身份认证”和“不可否认”。
就是把公钥和私钥反过来用,之前是公钥加密,私钥解密;现在是私钥加密、公钥解密。但由于非对称加密的效率太低,所以,私钥只加密原文的摘要,这样运算就小的多,而且得到的数字签名也小得多,方便保管和传输。
image这整个过程又被称为“签名”和“验签”。客户端和服务器分别生成签名,来确保双方的身份。
数字摘要在 TLS 中的作用
- 加密原文,用于验证数据完整性
- 加密原文,得到摘要,再使用私钥加密摘要,得到数字签名
10.4 数字证书和 CA
公钥的信任问题
也就是缺少黑客伪造公钥的问题。
解决方法
使用权威机构颁发的数字证书。CA 是颁发数字证书的权威机构,而数字证书是里包含公钥。
知名的 CA 机构:DigiCert、VeriSign、Entrust 等,它们签发的证书分为 DV、OV 和 EV 三个等级,用于区分可信度。其中,DV 最低,EV 最高。
同时,操作系统和浏览器内置了各大 CA 的根证书。上网的时候,浏览器发过来它的证书,操作系统和浏览器又可以验证证书里的签名。顺着证书链,一层一层地验证,直到找到根证书,就能证明证书是可信的,从而证明里面的公钥也是可信的。
证书体系的弱点
如果 CA 失误或者被欺骗了,签发了错误的证书,虽然证书是真的,可以代表的网站却是假的。针对这个问题,开发出了 CRL 和 OOP ,及时废止有问题的证书。
另一种情况,CA 被黑客攻陷。将该 CA 从操作系统和浏览器的根证书中移除。
说明
此文是根据罗剑锋透视 HTTP 协议相关专栏内容整理而来,非原创。
网友评论