HTTP
1. HTTP的基本概念
1.1 HTTP基本定义
全称: 超文本传输协议
- 超文本: 针对于传输的内容,不只是文字文件,将内容扩展到了字节流(视频,音频,图片等)内容,只要能用字节传输的内容都可以叫做超文本。
- 传输:指的是客户端和服务端的关系,是双向的。请求内容的同时也能够成为接受响应的主体。
http的传输是无状态的不安全的,无需身份的认证就可以向对方发送和接受消息。
- 协议:约定的内容,约定了传输时候的行为和规范。
1.2 HTTP常见状态码
状态码分类 | 表示含义 | 常见状态码 |
---|---|---|
1xx | 中间状态,正在等待恢复响应 | |
2xx | 成功 | 200 OK - 完全成功 204 Content - 成功但没有响应头body 206 Partial Content - 断点续传或分片中传输一部分成功 |
3xx | 重定向 | 301 Moved Permanently - 永久重定向,表示资源不存在了 302 Found - 临时重定向,暂时需要用别的URL访问 304 Not Modified - 重定向到缓存,用于缓存服务 |
4xx | 客户端问题 | 400 Bad Request - 请求问题(笼统) 403 Forbidden - 权限问题 404 Not Found - 路径问题(和3xx对比,这个完全找不到) |
5xx | 服务端问题 | 500 Internal Server Error - 服务器错误(笼统) 502 Bad Gateway - 服务器本身没问题,网关问题 503 Service Unavailable - 资源正在加载中 |
1.3 GET和POST的区别
- get一般用于资源的读取,也就是只读操作。一般不会有请求体,通过路径参数或者json表单传递即可实现。所以说他的操作是幂等的。对数据安全不会产生影响。所以对于一些不重复修改的数据,我们可以使用缓存技术降低访问数据库的频率,提高系统的性能。
幂等:两次操作后,获取的结果一定是相同的。
- post一般用于资源的修改或者新增,涉及到数据的写入操作,所以有可能会出现多线程情况下的脏读,重复读,幻读等问题,在高并发的场景下需要通过锁的机制来实现对数据库资源的保护。因为每次都会产生一次修改,所以说post操作不是幂等的,也是不安全的。
2. HTTP缓存技术
缓存技术是为了解决静态资源反复从服务器中加载,但是并没有得到改变,从而消耗服务器性能而提出来的一种解决方案。它可以将读取的静态资源放在内存中,下次可以直接从自己的内存中读取资源。无需耗费服务器性能。常用于静态标签页。、
2.1 强制缓存
当你从服务器上加载了一个网页的时候,他就将该网页加载到你的缓存中,并且设置了过期时间Cache-Control
,在过期时间之前,如果没有对浏览器进行强刷新(shirt + F5
)的话,是无法看到更新的内容的。
2.2 协商缓存
协商缓存时强制缓存失效后的方式。也就是说,只要强制缓存没有过期,协商缓存就不会出现。
有两个变量控制协商缓存的行为Etag
和 Last-Modified
。
第一个变量Etag
是资源全局唯一标识,可以判断该资源有没有被修改,第二个变量Last-Modified
可以判断该资源最后修改的时间。一般先判断第一个变量,在判断第二个变量。如果响应头部中有一个变量,那么就会交给服务器进行决策,判断是200还是304。304表示无需修改,可重定向到缓存,这时继续使用缓存。200表示有更新,则更新界面和缓存。
先Etag
原因是有些服务器判断最后修改时间细粒度不够高,同步性不强。以及有些非资源内部修改操作也会导致资源修改时间被重置。
3. HTTP如何优化
这里的优化指的是通过一些手段来传输时间的减少,从而提升用户使用时候的体验
3.1 尽可能避免HTTP请求发送
利用HTTP缓存技术,将热点数据存储在本地,要发送请求的时候先判断该数据是否已经先加载过,如果在本地缓存中查找到对应内容,那么直接读取本地缓存。所以这种方式主要是通过缓存的方式来尽可能避免数据的传输来优化时间上的体验。但是会占用一定的内存存储空间。
3.2 减少HTTP每次请求交互次数
- 减少重定向次数
当客户端访问的地址迁移的时候,访问的原地址只会给客户端返回302状态码,告诉他下一步要去访问的url,如果多次访问失效的话就会浪费极多次不必要的重定向。那么这时候我们可以采用代理服务器来记录每个服务端口之间的信息,将重定向的工作交由代理服务器完成,降低了一次信息的交换,提高了信息传输的效率。
- 将碎片数据集中成大文件统一进行传输
主要应用于**.gif**
头像小文件的传输,将多张小图片合并为一张大图片进行传输,可以减少客户端和服务端之间交互的次数。同时我们也可以将图片转换为**base64**
编码文件附送到url路径中,这样服务端收到请求的时候会自动解析该文件,也减少了一次图片请求的传输。
- 非紧急文件可延迟发送
常用于分页查询,每次只需要加载一个页面的数据即可,翻页的时候再加载其他资源,可以提高响应的速度
查询100w条数据,如何快速定位到较为后面的页数 –子查询
3.3 减少HTTP请求发送大小
- 有损压缩
- 无损压缩
4. RSA四次握手
RSA是HTTP请求前的安全传输技术,因为HTTP主要通过明文传输,会有一定的窃取篡改以及冒充的风险。所以在HTTP层和TCP层之间新增了一层TSL层,而RSA的TSL的主要实现方式之一,主要通过传输前的四次握手实现数据加密,校验机制,身份鉴权来避免以上的风险。
4.1 第一次握手
客户端发送client Hello
, 发起RSA加密请求, 传输数据有三个
TSL Version
: TSL加密的版本, 用于和服务端校验统一, 相同TSL版本才可以进行握手Client Random
: 客户端随机数, 用于后续加密Cipher Suiter
: 支持的密码套件, 用于确认其他加密的方式
4.2 第二次握手
服务端发送server Hello
, 发起RSA加密请求, 传输数据有三个
TSL Version
: TSL加密的版本, 校验Server Random
: 服务端随机数, 用于后续加密Cipher Suiter
: 从接收到的客户端的密码套件中选择一个
密码套件基本的形式是「密钥交换算法 + 签名算法 + 对称加密算法 + 摘要算法」
如Cipher Suite: TLS_RSA_WITH_AES_128_GCM_SHA256
- CA数字证书 : 用于身份校验
4.3 CA数字证书校验流程
数字证书包含的内容:
- 公钥
- 持有者信息
- 信息认证机构(CA)的信息
- CA采用的签名和算法
- 证书有效期
- 额外信息
客户端已知: 能通过的CA证书加密之后的hash value1
, 服务端发送过来的经过CA机构颁发的私钥加密的数字证书。
客户端通过公钥对于服务端发送过来的加密后的数字证书进行解密,得到hash value2
, 将可通过的hash value1
列表和hash value2
进行对比, 如果相同, 就说明证书是可靠的
证书信任链:根证书信任中间证书,中间证书信任服务端证书,那么客户端信任了根证书,也就相当于信任了服务端证书。
主要目的是将根证书进行隔离,保证信任的安全性。
4.4 第三次握手
客户端首先需要校验发送过来的数字证书是否合法,如果合法,得到公钥pubkey
,进行下列操作:
生成随机数pre-master
,用pubkey
加密传输给服务端;
此时,客户端和服务端双方都共享了三个随机数,分别是 Client Random、Server Random、pre-master
双方利用这三个随机数生成会话密钥,用于后续信息的加密和解密。
之后客户端给服务端发送change cipher spec
, 用于通知服务端后续的会话将由通过会话密钥加密的方式传递信息。
最后,finish
是最后一步的校验,将前面信息做摘要, 来判断是否前面信息又被篡改。
4.5 第四次握手
服务器也是同样的操作,发 [ Change Cipher Spec ] 和 [ finish ] 消息,如果双方都验证加密和解密没问题,那么握手正式完成。
最后客户端和服务端就会通过加密的方式进行会话。
4.6 RSA算法的缺点
无法保证【前向加密】,针对于第三次握手,因为是用公钥进行加密的pre-master
,如果服务端的私钥被破解,那么全部数据就会被截取和破解,会产生冒充的风险。
前向加密:一个密钥只能访问由它所保护的数据;用来产生密钥的元素一次一换,不能再产生其他的密钥;一个密钥被破解,并不影响其他密钥的安全性。
4.7 ECDHE 密钥协商算法
- 运用了离散对数, 圆锥曲线等算法,保证了数据在加密前的安全性,这是相较于RSA算法的一大突破.
- RSA算法不支持前向保密机制,而ECDHE密钥协商算法支持前向保密机制。
- ECDHE算法的客户端可以不用等服务端的最后一次 TLS 握手,就可以提前发出加密的 HTTP 数据,节省了一个消息的往返时间
5. HTTP2的优化点
5.1 HTTP1. 1的缺陷
HTTP/2 针对于HTTP1.1的优化主要体现在其传输效率上,对于其安全性没有做出过多的改变。安全主要靠的是HTTPS协议来进行改善。
那么,HTTP/2主要针对以下几个问题进行改良:
- 串行化运行导致传输效率过慢,完成一个HTTP请求之后才能进行下一个
- 不支持服务器主动推送信息,单向化
- 头部信息过于庞大且重复,浪费空间大
针对以上问题,做出优化点如下:
5.2 头部压缩
针对于HTTP协议的头部大部分的重复特性,HTTP/2编写了编码表,可以类比于我们的哈希结构,以空间换时间,首先是很平常的字段就用静态编码表记录下来,剩下的字段用动态编码表两边各储存一份,到了一定的时间后,就可以只通过发送编码表的序号就可以达到头部的传输功能了。
5.2.1 静态编码表
定义:为高频出现在HTTP协议头部的字段建立了一张key: set
表,总共有61组键值对
其中index
为字段的编号,剩下的为键值对信息。
格式如上:首先开头两位为01,表示占位,后面六位index
为对应静态编码表中的序号。
第二个字节首位表示Value 是否经过 Huffman 编码,后七个字节表示每个值所需要表示的字节长度。
剩下内容为头部的其他信息,以第二个字节为规定的长度为一个单位。
5.2.2 动态编码表
边存储边积累,将双方链接过程中的所包含的头部信息共同存储为一张动态表,随着时间的推移,后期双方的链接只需要通过传递序号就可以表达所需要传递的头部信息了。但是这样做会造成极大的空间内存损耗。web服务器会提供类似于http2_max_requests
这样的字段来限制最大字典表字段数。
5.3 二进制帧
帧长度(24bits):表示的是帧数据(Frame Payload)的长度,不包含帧字节
帧类型(8bits):分为数据帧和控制帧两类
标志位(8bits):携带一些控制信息
流标识符(24bits):表示该帧是属于哪个流的,可以用来组装帧。
5.4 并发传输
- connection:表示HTTP连接,是一次服务端和客户端之间的对话联系
- stream:一个connection中包含了多个stream,这是http/2的优化之处,他保证了http/2的帧可以乱序发送,因为帧的头部信息携带了流标识符,最后传到在重新拼装即可,实现了Http链接之间的并行传输。
但是同一个流之中的帧不可乱序传输,因为帧头没有确定帧先后顺序的标识位。
- Response Message:响应信息,表示一个Request或者Reponse,由各个帧组成了一条完整的响应信息。
这个模式还突破了原有的全单工模式的传输,服务器和客户端可以同时发送信息了,只要双方各自建立自己的stream,在不同的流上发送即可,极大的提高了传输的效率。
但是这里有一个规定,客户端仅可建立编号为奇数的stream,服务端仅可以建立编号为偶数的stream。
5.5 服务器主动推送资源
由于stream的引入,服务器可以自己主动推送资源了。