HTTP和HTTPS,以及CDN常见异常

CDN访问异常篇之502/503/504错误

一. 源站不通或源站域名无法解析

CDN 都是公网上的节点,CDN配置的源站必须要公网可达。如果配置的源站IP公网不可达、端口不通或者源站域名没有解析,则会导致CDN回源请求源站失败,报错5xx。

常见的几种异常情况如下:

(1)源站网络不通,测试无法ping通源站IP。ping测试命令:ping 源站IP

(2)源站端口不通或源站直接响应5xx错误。例如以下案例,telnet端口报错Connection timed out

i)如果源站端口配置的是80,则测试80端口是否通:telnet 源站IP 80

ii)如果源站端口配置的是443,则测试443端口是否通。如果源站端口配置的是自定义端口,则测试自定义端口是否通。

iii)可以在CDN控制台获取配置的源站地址和端口,然后本地host绑定到源站,固定源站做七层测试,查看是否是源站直接无响应或源站直接响应5xx,具体可以参考

二.CDN配置了HTTPS回源,但源站不支持HTTPS

(1)源站端口配置成443,但源站不支持HTTPS

在CDN控制台的源站配置界面,如果源站端口配置成443,则CDN回源的时候是HTTPS回源到源站的443端口。源站需要开放443端口,且配置HTTPS证书。如果源站不支持HTTPS访问,则CDN回源失败,报错5xx。对于这种情况,可以把回源端口改成80;如果业务需要443回源的话,那么需要在源站配置HTTPS证书。

(2)CDN配置了协议跟随回源,但是源站不支持HTTPS访问。

协议跟随回源如果设置成“HTTPS”,则CDN是以HTTPS回源;协议跟随回源如果设置成“跟随”,则当客户端是HTTPS访问的时候,CDN是HTTPS回源。源站不支持HTTPS的情况下,会出现访问失败。对于这种情况,需要关闭协议跟随回源功能,或设置为HTTP回源。

三.源站开启了SNI校验,但是CDN没有开启“回源SNI”

CDN回源默认是不带SNI信息的,如果您的源站IP绑定了多个域名,当CDN节点以HTTPS协议访问您的源站时,由于没有带SNI信息,会导致源站无法正确响应HTTPS证书,导致回源失败。因为这个问题导致的错误,一般是503 Service Temporarily Unavailable错误,而且很快就会返回这个错误。您可以在CDN控制台设置开启回源SNI,指明具体访问域名。具体SNI的介绍以及配置方法参考这里

四.源站存在安全防护规则

源站的相关安全防护规则导致的CDN回源异常,通常会在10秒以内就返回5xx错误,大部分情况会返回503 Service Temporarily Unavailable的错误,具体的排查方法和解决方案可以参考文档源站安全策略导致5xx

(1)源站服务器开启了安全组限制,限制了CDN节点的访问

(2)源站服务器配置了单IP访问次数限制,把CDN的回源IP当成了异常IP

(3)源站存在云锁、安全狗、防火墙等安全策略,拦截了CDN的回源IP

(4)源站Web服务异常或服务器超载

五. 源站超时无响应导致CDN回源超时

CDN 回源有严格的超时时间,四层 TCP 是 10 秒超时,七层HTTP / HTTPS是 30 秒超时,当超过该时间时即使后续源站响应正常也是会返回 5xx错误,通常因CDN回源超时导致的问题,会响应504Gateway Time-out错误。可以绑定源站去测试源站的响应速度,如果超过30秒,需要检查源站服务,优化源站的响应速度,确保源站返回请求时间控制在一个较短的时间内,另外也可以申请延长CDN域名的默认超时时长,详细请参考配置回源请求超时时间

六. 跨境回源或源站侧网络异常

回源存在跨境链路导致的CDN回源超时,响应5xx错误。例如源站在境外,中国大陆的用户访问的时候,是先访问到中国大陆的CDN节点,然后中国大陆的CDN节点走跨境链路,回源到境外的源站;亦或者源站在中国大陆,境外用户访问的时候先请求到境外的CDN节点,境外的CDN节点走跨境链路,回源到中国大陆的源站。由于CDN回源走的都是公网,这种情况涉及到跨境链路,需要走国际互联网出口以及境外运营商的链路,本身就存在一定的不稳定因素。还有一种情况是源站侧机房的网络差,或源站侧网络不稳定。

1.HTTP Get 和 Post 区别

get 方法一般用于请求,比如你在浏览器地址栏输入www.cxuanblog.com其实就是发送了一个 get 请求,它的主要特征是请求服务器返回资源,而 post 方法一般用于

表单的提交,相当于是把信息提交给服务器,等待服务器作出响应,get 相当于一个是 pull/拉的操作,而 post 相当于是一个 push/推的操作。

get 方法是不安全的,因为你在发送请求的过程中,你的请求参数会拼在 URL 后面,从而导致容易被攻击者窃取,对你的信息造成破坏和伪造;

而 post 方法是把参数放在请求体 body 中的,这对用户来说不可见。

get 请求的 URL 有长度限制,而 post 请求会把参数和值放在消息体中,对数据长度没有要求。

get 请求会被浏览器主动 cache,而 post 不会,除非手动设置。

get 请求在浏览器反复的回退/前进操作是无害的,而 post 操作会再次提交表单请求。

get 请求在发送过程中会产生一个 TCP 数据包;post 在发送过程中会产生两个 TCP 数据包。对于 get 方式的请求,浏览器会把 http header 和 data 一并发送出去,服务器响应 200(返回数据);而对于 post,浏览器先发送 header,服务器响应 100 continue,浏览器再发送 data,服务器响应 200 ok(返回数据)

无状态协议(Stateless Protocol)就是指浏览器对于事务的处理没有记忆能力。举个例子来说就是比如客户请求获得网页之后关闭浏览器,然后再次启动浏览器,登录该网站,但是服务器并不知道客户关闭了一次浏览器。

HTTP 就是一种无状态的协议,他对用户的操作没有记忆能力。可能大多数用户不相信,他可能觉得每次输入用户名和密码登陆一个网站后,下次登陆就不再重新输入用户名和密码了。这其实不是 HTTP 做的事情,起作用的是一个叫做小甜饼(Cookie)的机制。它能够让浏览器具有记忆能力。

数字证书的有效性如何验证

主要从三个方面:

1,数字证书有效期验证,2,根证书验证,3,CRL验证

1,数字证书有效期验证

就是说证书的使用时间要在起始时间和结束时间之内。通过解析证书很容易得到证书的有效期

2,根证书验证

普通的证书一般包括三部分:用户信息,用户公钥,以及CA签名

那么我们要验证这张证书就需要验证CA签名的真伪。那么就需要CA公钥。而CA公钥存在于另外一张证书(称这张证书是对普通证书签名的证书)中。因此我们又需要验证这另外一张证书的真伪。因此又需要验证另另外证书(称这张证书是对另外一张证书签名的证书)的真伪。依次往下回溯,就得到一条证书链。那么这张证书链从哪里结束呢?就是在根证书结束(即验证到根证书结束)。根证书是个很特别的证书,它是CA中心自己给自己签名的证书(即这张证书是用CA公钥对这张证书进行签名)。信任这张证书,就代表信任这张证书下的证书链。

所有用户在使用自己的证书之前必须先下载根证书。所谓根证书验证就是:用根证书公钥来验证该证书的颁发者签名。所以首先必须要有根证书,并且根证书必须在受信任的证书列表(即信任域)

3,CRL验证

CRL是经过CA签名的证书作废列表,用于证书冻结和撤销。一般来说证书中有CRL地址,供HTTP或者LDAP方式访问,通过解析可得到CRL地址,然后下载CRL进行验证。

并且证书中有CRL生效日期以及下次更新的日期,因此CRL是自动更新的,因此会有延迟性。

于是呢,还有另外一种方式OSCP证书状态在线查询,可以即时的查询证书状态。

两种证书状态查询方式的比较:


如何向CA申请证书:

1.自己本地先生成一对密匙,然后拿着自己的公匙以及其他信息(比如说企业名称啊什么的)去CA申请数字证书

2.CA在拿到这些信息后,会选择一种单向Hash算法(比如说常见的MD5)对这些信息进行加密,加密之后的东西我们称之为摘要。单向Hash算法有一种特点就是单向不可逆的,只要原始内容有一点变化,加密后的数据都将会是千差万别(当然也有很小的可能性会重复,有兴趣的小伙伴鸽巢原理了解一下),这样就防止了信息被篡改。

3.生成摘要后还不算完,CA还会用自己的私匙对摘要进行加密,摘要加密后的数据我们称之为数字签名。

4.最后,CA将会把我们的申请信息(包含服务器的公匙)和数字签名整合在一起,由此而生成数字证书。然后CA将数字证书传递给我们。

数字证书怎么起作用呢?

服务器在获取到数字证书后,服务器会将数字证书发送给客户端,客户端就需要用CA的公匙解密数字证书并验证数字证书的合法性。

那我们如何能拿到CA的公匙呢?我们的电脑和浏览器中已经内置了一部分权威机构的根证书,这些根证书中包含了CA的公匙。之所以是根证书,是因为现实生活中,认证中心是分层级的,也就是说有顶级认证中心,也有下面的各个子级的认证中心,是一个树状结构,计算机中内置的是最顶级机构的根证书,不过不用担心,根证书的公匙在子级也是适用的。客户端用CA的公匙解密数字证书,如果解密成功则说明证书来源于合法的认证机构。解密成功后,客户端就拿到了摘要。此时,客户端会按照和CA一样的Hash算法将申请信息生成一份摘要,并和解密出来的那份做对比,如果相同则说明内容完整,没有被篡改。 最后,客户端安全的从证书中拿到服务器的公匙就可以和服务器进行安全的非对称加密通信了。服务器想获得客户端的公匙也可以通过相同方式。

什么是加密套件?

  加密套件是用于在SSL / TLS握手期间协商安全设置的算法的组合。在ClientHello和ServerHello消息交换之后,客户端发送优先级列表的密码支持套件。然后,服务器使用从列表中选择的密码套件进行响应。

TLS算法组合:

在TLS中,5类算法组合在一起,称为一个CipherSuite:

认证算法,加密算法,消息认证码算法 简称MAC,密钥交换算法,密钥衍生算法

比较常见的算法组合是 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA 和  TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 都是ECDHE 做密钥交换,使用RSA做认证,SHA256做PRF算法。

一个使用AES128-CBC做加密算法,用HMAC做MAC。

一个使用AES128-GCM做加密算法,MAC由于GCM作为一种AEAD模式并不需要。

这里是一个加密套件的例子:

TLS _ECDHE_ RSA _ WITH_AES_128_GCM _ SHA256

2.HTTPS 的工作原理

HTTPS并非是应用层的一种新协议。只是HTTP通信接口部分用SSL和TLS协议代替而已。

通常,HTTP直接和TCP通信。当使用SSL时,则演变成先和SSL通信,再由SSL和TCP通信了。简言之,所谓HTTPS,其实就是身披SSL协议这层外壳的HTTP。

在采用SSL后,HTTP就拥有了HTTPS的加密、证书和完整性保护这些功能。也就是说HTTP加上加密处理和认证以及完整性保护后即是HTTPS。

HTTPS 协议的主要功能基本都依赖于 TLS/SSL 协议,TLS/SSL 的功能实现主要依赖于三类基本算法:散列函数 、对称加密和非对称加密,其利用非对称加密实现身份认证和密钥协商,对称加密算法采用协商的密钥对数据加密,基于散列函数验证信息的完整性。


TLS 具体的握手过程会根据所使用的密钥交换算法的类型和双方支持的密码套件而不同。我们以RSA 非对称加密来讨论这个过程。整个 TLS 通信流程图如下

采用单钥密码系统的加密方法,同一个密钥可以同时用作信息的加密和解密,这种加密方法称为对称加密,也称为单密钥加密。

采用单钥密码的加密方法,同一个密钥可以同时用来加密和解密,这种加密方法称为对称加密,也称为单密钥加密。常用的单向加密算法:

1、DES(Data Encryption Standard):数据加密标准,速度较快,适用于加密大量数据的场合;

2、3DES(Triple DES):是基于DES,对一块数据用三个不同的密钥进行三次加密,强度更高;

3、AES(Advanced Encryption Standard):高级加密标准,是下一代的加密算法标准,速度快,安全级别高,支持128、192、256、512位密钥的加密;

对称加密+非对称加密(HTTPS采用这种方式)

使用对称密钥的好处是解密的效率比较快,使用非对称密钥的好处是可以使得传输的内容不能被破解,因为就算你拦截到了数据,但是没有对应的私钥,也是不能破解内容的。就比如说你抢到了一个保险柜,但是没有保险柜的钥匙也不能打开保险柜。那我们就将对称加密与非对称加密结合起来,充分利用两者各自的优势,在交换密钥环节使用非对称加密方式,之后的建立通信交换报文阶段则使用对称加密方式。

具体做法是:发送密文的一方使用对方的公钥进行加密处理“对称的密钥”,然后对方用自己的私钥解密拿到“对称的密钥”,这样可以确保交换的密钥是安全的前提下,使用对称加密方式进行通信。所以,HTTPS采用对称加密和非对称加密两者并用的混合加密机制

1.Client发起一个HTTPS(比如https://juejin.im/user/5a9a9cdcf265da238b7d771c)的请求,根据RFC2818的规定,Client知道需要连接Server的443(默认)端口。

2.Server把事先配置好的公钥证书(public key certificate)返回给客户端。

3.Client验证公钥证书:比如是否在有效期内,证书的用途是不是匹配Client请求的站点,是不是在CRL吊销列表里面,它的上一级证书是否有效,这是一个递归的过程,直到验证到根证书(操作系统内置的Root证书或者Client内置的Root证书)。如果验证通过则继续,不通过则显示警告信息。

4.Client使用伪随机数生成器生成加密所使用的对称密钥,然后用证书的公钥加密这个对称密钥,发给Server。

5.Server使用自己的私钥(private key)解密这个消息,得到对称密钥。至此,Client和Server双方都持有了相同的对称密钥。

6.Server使用对称密钥加密“明文内容A”,发送给Client。

7.Client使用对称密钥解密响应的密文,得到“明文内容A”。

8.Client再次发起HTTPS的请求,使用对称密钥加密请求的“明文内容B”,然后Server使用对称密钥解密密文,得到“明文内容B”。

HTTPS的结构图

1. 客户使用https的URL访问Web服务器,要求与Web服务器建立SSL连接(通知可加密的算法)。

2. Web服务器收到客户端请求后,会将网站的电子证书(证书中包含公钥)传送一份给客户端。

3. 客户端确认电子证书是否刚才访问网站所属

4. 客户端的浏览器根据双方同意的安全等级,建立会话密钥,然后利用网站的公钥将会话密钥加密,并传送给网站。

5. Web服务器利用自己的私钥解密出会话密钥(客户端发来的对称加密密钥)。

6. Web服务器利用对称密钥加密与客户端之间的通信。

2.2.1 客户端访问https连接

这一步,就是相当于我们在浏览器上输入url回车的过程。这个时候浏览器或者客户端(接下来统一为客户端)会把我们客户端支持的加密算法Cipher Suite(密钥算法套件)带给服务端。

2.2.2 - 2.2.3 服务端发送证书(公钥)给客户端

服务端接收Cipher后,和自己支持的加密算法进行比对,如果不符合,则断开连接。否则,服务端会把符合的算法和证书发给客户端,包括证书时间、证书日期、证书颁发的机构。

2.2.4- 2.2.5 客户端验证服务端的证书

1、客户端验证证书,包括颁发证书的机构是否合法与是否过期,证书中包含的网站地址是否与正在访问的地址一致等

2、验证通过后(或者用户接受了不信任的证书),客户端会生成一个随机字符串,然后用服务端的公钥进行加密。这里就保证了只有服务端才能看到这串随机字符串(因为服务端拥有公钥对应的私钥,RSA解密,可以知道客户端的随机字符串)。

3、生成握手信息  用约定好的HASH算法,对握手信息进行取HASH,然后用随机字符串加密握手信息和握手信息的签名HASH值,把结果发给服务端。这里之所以要带上握手信息的HASH是因为,防止信息被篡改。如果信息被篡改,那么服务端接收到信息进行HASH时,就会发现HASH值和客户端传回来的不一样。这里就保证了信息不会被篡改。。

其他解释:

一、首先HTTP请求服务端生成证书,客户端对证书的有效期、合法性、域名是否与请求的域名一致、证书的公钥(RSA加密)等进行校验;

二、客户端如果校验通过后,就根据证书的公钥的有效, 生成随机数,随机数使用公钥进行加密(RSA加密);

三、消息体产生的后,对它的摘要进行MD5(或者SHA1)算法加密,此时就得到了RSA签名;

四、发送给服务端,此时只有服务端(RSA私钥)能解密。

五、解密得到的随机数,再用AES加密,作为密钥(此时的密钥只有客户端和服务端知道)。

证书验证阶段:

浏览器发起 HTTPS 请求。

服务端返回 HTTPS 证书。

客户端验证证书是否合法,如果不合法则提示告警。

数据传输阶段:

当证书验证合法后,在本地生成随机数。

通过公钥加密随机数,并把加密后的随机数传输到服务端。

服务端通过私钥对随机数进行解密。

服务端通过客户端传入的随机数构造对称加密算法,对返回结果内容进行加密后传输。

非对称加密

这种方法就是,让客户端和服务器都拥有两把钥匙,一把钥匙是公开的(全世界知道都没关系),我们称之为公钥;另一把钥匙则是保密的(只有自己本人才知道),我们称之为私钥。这且,用公钥加密的数据,只有对应的私钥才能解密;用私钥加密的数据,只有对应的公钥才能解密

非对称加密比较慢,对称加密不安全

这样,服务器在给客户端传输数据的过程中,可以用客户端明文给他的公钥进行加密,然后客户端收到后,再用自己的私钥进行解密。客户端给服务器发送数据的时候也一样采取这样的方式。这样就能保持数据的安全传输了。画个图理解一下:

非对称加密也并非是安全的,

服务器以明文的方式给客户端传输公钥的时候,中间人截取了这把属于服务器的公钥,并且把中间人自己的公钥冒充服务器的公钥传输给了客户端。

之后客户端就会用中间人的公钥来加密自己生成的密钥。然后把被加密的密钥传输给服务器,这个时候中间人又把密钥给截取了,中间人用自己的私钥对这把被加密的密钥进行解密,解密后中间人就可以获得这把密钥了。

最后中间人再对这把密钥用刚才服务器的公钥进行加密,再发给服务器。如图:

数字证书登场

服务器在给客户端传输公钥的过程中,会把公钥以及服务器的个人信息通过Hash算法生成信息摘要。如图

为了防止信息摘要被人调换,服务器还会用CA提供的私钥对信息摘要进行加密来形成数字签名。如图:

并且,最后还会把原来没Hash算法之前的个人信息以及公钥 和 数字签名合并在一起,形成数字证书。如图

当客户端拿到这份数字证书之后,就会用CA提供的公钥来对数字证书里面的数字签名进行解密来得到信息摘要,然后对数字证书里服务器的公钥以及个人信息进行Hash得到另外一份信息摘要。最后把两份信息摘要进行对比,如果一样,则证明这个人是服务器,否则就不是。如图:

这样,就可以保证服务器的公钥安全着交给客户端了。

3.证书的验证

对称加密:加密使用的秘钥和解密使用的秘钥是相同的,也就是说加密和解密都使用同一个秘钥,加密算法是公开的,秘钥是加密者和解密者绝对保密的

非对称加密:加密使用的秘钥和解密使用的秘钥是不相同的,HTTPS在数字证书验证的时候,采用的RSA密码体制就是一种非对称加密

非对称加密:指的是加、解密使用不同的密钥,一把作为公开的公钥,另一把作为私钥。公钥加密的信息,只有私钥才能解密。反之,私钥加密的信息,只有公钥才能解密。

举个例子,你向某公司服务器请求公钥,服务器将公钥发给你,你使用公钥对消息加密,那么只有私钥的持有人才能对你的消息解密。与对称加密不同的是,公司服务器不需要将私钥通过网络发送出去,因此安全性大大提高。

RSA是一种公钥密码体制,现在使用非常广泛,这个密码体制分为三部分,公钥、私钥、加密算法,其中公钥和加密算法是公布的,私钥是自己保密的。这种机制最大的特点是,通过公钥加密的密文只有对应的私钥才能解密,同样通过私钥加密的密文也只有对应的公钥才能解密。下面我们将会讲到HTTPS是如何通过RSA这种密码体制去验证身份的

1.浏览器要求基于数字证书对网站进行在线身份鉴别(身份认证);

2.网站(Web服务器)将数字证书传递给用户浏览器;

3. 浏览器验证网站数字证书的有效性和可信性,包括验证网站证书是否由可信的电子认证机构签发(用CA的公钥验证签名),证书上的域名是否与用户要访问的网站域名一致,证书是否在有效期内等;

4.证书有效性和可信性验证通过后,浏览器将一串随机生成的数据传递到网站,要求网站对此进行数字签名;

5.网站用私钥对接收到随机数据进行数字签名,然后将签名后的数据传送到到用户浏览器;

 6.用户浏览器使用网站证书上的公钥对数字签名后的数据进行验证,验证通过则说明用户要访问的网站确实是证书上所标识的网站。

4.从输入URL到页面展现的过程

1.输入URL后,会先进行域名解析。优先查找本地host文件有无对应的IP地址,没有的话去本地DNS服务器查找,还不行的话,本地DNS服务器会去找根DNS服务器要一个域服务器的地址进行查询,域服务器将要查询的域名的解析服务器地址返回给本地DNS,本地DNS去这里查询就OK了。

2.浏览器拿到服务器的IP地址后,会向它发送HTTP请求。HTTP请求经由一层层的处理、封装、发出之后,最终经由网络到达服务器,建立TCP/IP连接,服务器接收到请求并开始处理。

3.服务器构建响应,再经由一层层的处理、封装、发出后,到达客户端,浏览器处理请求。

4.浏览器开始渲染页面,解析HTML,构建render树,根据render树的节点和CSS的对应关系,进行布局,绘制页面。

一个HTTP请求从源端发出到在终端接收的处理过程都是要经过以下四层。其中每一层都有各自的协议。


证书包含什么信息?

颁发机构信息,公钥,公司信息,域名,有效期,指纹,封装和分用

3. 浏览器如何验证证书的合法性?

浏览器发起 HTTPS 请求时,服务器会返回网站的 SSL 证书,浏览器需要对证书做以下验证:

验证域名、有效期等信息是否正确。证书上都有包含这些信息,比较容易完成验证;

判断证书来源是否合法。每份签发证书都可以根据验证链查找到对应的根证书,操作系统、浏览器会在本地存储权威机构的根证书,利用本地根证书可以对对应机构签发证书完成来源验证;

判断证书是否被篡改。需要与 CA 服务器进行校验;

判断证书是否已吊销。通过CRL(Certificate Revocation List 证书注销列表)和 OCSP(Online Certificate Status Protocol 在线证书状态协议)实现,其中 OCSP 可用于第3步中以减少与 CA 服务器的交互,提高验证效率

以上任意一步都满足的情况下浏览器才认为证书是合法的。

这里插一个我想了很久的但其实答案很简单的问题:

既然证书是公开的,如果要发起中间人攻击,我在官网上下载一份证书作为我的服务器证书,那客户端肯定会认同这个证书是合法的,如何避免这种证书冒用的情况?

其实这就是非加密对称中公私钥的用处,虽然中间人可以得到证书,但私钥是无法获取的,一份公钥是不可能推算出其对应的私钥,中间人即使拿到证书也无法伪装成合法服务端,因为无法对客户端传入的加密数据进行解密。

数据在经过每一层的时候都要被对应的协议包装,到达终端的时候,要一层一层的解包。这两个过程叫封装和分用。

发送时,用户数据被HTTP封装为报文,每一层会将上层传过来的报文作为本层的数据块,并添加自己的首部,其中包含了协议标识,这一整体作为本层报文向下传递。

接收时,数据自下而上流动,经过每一层时被去掉报文首部,根据报文标识确定正确的上层协议,最终到应用层被应用程序处理。

HTTP

请求报文有4部分组成:

响应行,响应头,空行,响应体


HTTP属于应用层,用户触发交互所产生的行为数据和服务端对此的响应都由它封装成HTTP报文,再交由下层协议进行处理。报文的作用是客户端与服务端沟通的载体,双方都要遵循统一规则对信息进行处理,这一规则称为HTTP。

•请求首部:是放在请求报文中的首部,它被用来告诉服务端一些信息。•响应首部:为客户端提供一些可能用到的信息。•通用首部:请求与响应报文都包含的首部,例如Date首部•实体首部:对于报文实体主体部分的描述,比如Content-Type,表明其数据类型。•扩展首部:开发者自己添加的首部字段,用来满足定制化需求。

实体部分是可选的,它被用来运送请求或者响应的数据,实体由实体首部 + 实体主体组成,实体首部对实体主体做描述。HTTP/1.1定义了以下的基本实体首部字段:

•Content-Type: 实体主体中的数据类型。•Content-Length: 实体主体的长度或者大小。,Content-Language: 和传输的数据最匹配的语言。

Content-Encoding: 来标识服务端编码时所用的编码方式。

Content-Location: 要返回的数据的地址。

Content-Range: 如果是部分实体,用来标记它是实体的哪个部分。

Content-MD5: 实体主体内容的校验和。

Last-Modified: 所传输内容在服务器上创建或者最后修改的日期时间。

Expires: 实体数据试下的日期时间。

Allow: 所请求资源允许的请求方法。

ETag: 资源的特定版本的标识符。可以让缓存更高效,并节省带宽。

Cache-Control: 控制缓存机制的指令。

HTTP可缓存性包括:

public:HTTP请求返回时,经过的代理服务器以及客户端都可以对内容进行缓存。

private:只有发起请求的浏览器可以进行缓存

no-cache:本地和代理服务器可以缓存,但是每次使用缓存时都要到服务器验证一下,服务器返回可以使用缓存才能生效。

max-age :可以设置缓存的有效期

s-maxage:代理服务器的缓存有效期。同时设置max-age和s-maxage,客户端会使用max-age,代理服务器会使用s-maxage

max-stale:发起端设置,指明请求可以使用过期的缓存。(浏览器用不到)

验证方面:

must-revalidate:如果缓存过期,必须到服务器发送请求重新获取数据

proxy-revalidate:缓存服务器的must-revalidate

Last-Modified:服务器返回Response的上次修改时间,配合客户端发送Request的If-Modified-Since使用

Etag:通过数据签名标记这个资源,下次请求时配合Requesst的If-Match/If-Non-Match的对比缓存中的Etag判断是否使用缓存(数据签名:资源对它的内容会产生唯一的签名,如果内容修改,签名会进行修改,例如对内容hash计算)

no-store:本地和代理服务器都不能存储缓存,每次都到原服务器拿数据。

no-transform:不允许改动返回的内容(比如压缩、格式转换)

以上是HTTP报文包含的主要结构,当请求报文到达服务器时,服务器会对报文中的内容解析出来,根据方法、资源路径、首部、和主体来处理请求,然后通过对请求资源的访问结果,来构建响应,回送给客户端。

5.一次完整的HTTP请求过程

当我们在web浏览器的地址栏中输入: www.baidu.com,然后回车,到底发生了什么

  1.对www.baidu.com这个网址进行DNS域名解析,得到对应的IP地址

  2.根据这个IP,找到对应的服务器,发起TCP的三次握手

  3.建立TCP连接后发起HTTP请求

  4.服务器响应HTTP请求,浏览器得到html代码

  5.浏览器解析html代码,并请求html代码中的资源(如js、css图片等)(先得到html代码,才能去找这些资源)

  6.浏览器对页面进行渲染呈现给用户

域名解析 --> 发起TCP的3次握手 --> 建立TCP连接后发起http请求 --> 服务器响应http请求,浏览器得到html代码 --> 浏览器解析html代码,并请求html代码中的资源(如js、css、图片等) --> 浏览器对页面进行渲染呈现给用户

先弄懂下面5个基本知识点:

封装报文是从上层到下层(应用层 --> 传输层 --> 网络层 – > 数据链路层 --> 物理层),解封装报文是从下层到上层

实际例子:从PC1远程登录服务器(Server)。

数据包传输的过程中,源IP和目标IP不会变,除非遇到NAT(SNAT或DNAT),源MAC和目标MAC遇到网关会变

二层内通过MAC寻址,三层通过IP寻址。

当一个数据包的目的地址不是本机,所以需要查询路由表,当查到路由表中的网关之后,需要获取网关的MAC地址,并将数据包的MAC地址修改成网关地址,然后发送到对应的网卡。

协议数据单元在应用层、表示层和会话层被称做数据(Data),在传输层被称做分段(Segment),在网络层被称做(Packet),在数据链路层被称做(Frame),在物理层被称做比特(Bit)。

PC1或者Server上保留的arp表是:arp和ip的映射关系。而二层交换机是arp和端口的映射关系,也就是这个arp 应该由哪个端口转发。三层交换机可以保留arp和ip的映射关系。

 1.域名解析

  a)首先会搜索浏览器自身的DNS缓存(缓存时间比较短,大概只有1分钟,且只能容纳1000条缓存)

  b)如果浏览器自身的缓存里面没有找到,那么浏览器会搜索系统自身的DNS缓存

  c)如果还没有找到,那么尝试从 hosts文件里面去找

  d)在前面三个过程都没获取到的情况下,就递归地去域名服务器去查找,具体过程如下

 2.TCP连接(三次握手)

  拿到域名对应的IP地址之后,User-Agent(一般指浏览器)会以一个随机端口(1024<端口<65535)向服务器的WEB程序(常用的有httpd,nginx)等的80端口。这个连接请求(原始的http请求经过TCP/IP4层模型的层层封包)到达服务器端后(这中间有各种路由设备,局域网内除外),进入到网卡,然后是进入到内核的TCP/IP协议栈(用于识别连接请求,解封包,一层一层的剥开),还有可能要经过Netfilter防火墙(属于内核的模块)的过滤,最终达到WEB程序,最终建立了TCP/IP的连接

3.建立TCP连接之后,发起HTTP请求

HTTP请求报文由三部分组成:请求行,请求头和请求正文

请求行:用于描述客户端的请求方式,请求的资源名称以及使用的HTTP协议的版本号(例:GET/books/java.html HTTP/1.1)

请求头:用于描述客户端请求哪台主机,以及客户端的一些环境信息等

4.服务器端响应http请求,浏览器得到html代码

HTTP响应也由三部分组成:状态码,响应头和实体内容

状态码:状态码用于表示服务器对请求的处理结果

列举几种常见的:200(没有问题) 302(要你去找别人) 304(要你去拿缓存) 307(要你去拿缓存) 403(有这个资源,但是没有访问权限) 404(服务器没有这个资源) 500(服务器这边有问题

5.浏览器解析html代码,并请求html代码中的资源

浏览器拿到html文件后,就开始解析其中的html代码,遇到js/css/image等静态资源时,就向服务器端去请求下载(会使用多线程下载,每个浏览器的线程数不一样),这是时候就用上 keep-alive特性了,建立一次HTTP连接,可以请求多个资源,下载资源的顺序就是按照代码里面的顺序,但是由于每个资源大小不一样,而浏览器又是多线程请求请求资源,所以这里显示的顺序并不一定是代码里面的顺序。

6.浏览器对页面进行渲染呈现给用户

最后,浏览器利用自己内部的工作机制,把请求的静态资源和html代码进行渲染,渲染之后呈现给用户

5.HTTP的长连接与短连接

在HTTP/1.0中默认使用短连接。也就是说,客户端和服务器每进行一次HTTP操作,就建立一次连接,任务结束就中断连接。当客户端浏览器访问的某个HTML或其他类型的Web页中包含有其他的Web资源(如JavaScript文件、图像文件、CSS文件等),每遇到这样一个Web资源,浏览器就会重新建立一个HTTP会话。

而从HTTP/1.1起,默认使用长连接,用以保持连接特性。使用长连接的HTTP协议,会在响应头加入这行代码:

Connection:keep-alive

长连接短连接操作过程

短连接的操作步骤是:

建立连接——数据传输——关闭连接...建立连接——数据传输——关闭连接

长连接的操作步骤是:

建立连接——数据传输...(保持连接)...数据传输——关闭连接

什么时候用长连接,短连接?

长连接多用于操作频繁,点对点的通讯,而且连接数不能太多情况,。每个TCP连接都需要三步握手,这需要时间,如果每个操作都是先连接,再操作的话那么处理速度会降低很多,所以每个操作完后都不断开,次处理时直接发送数据包就OK了,不用建立TCP连接。例如:数据库的连接用长连接, 如果用短连接频繁的通信会造成socket错误,而且频繁的socket 创建也是对资源的浪费。

而像WEB网站的http服务一般都用短链接,因为长连接对于服务端来说会耗费一定的资源,而像WEB网站这么频繁的成千上万甚至上亿客户端的连接用短连接会更省一些资源,如果用长连接,而且同时有成千上万的用户,如果每个用户都占用一个连接的话,那可想而知吧。所以并发量大,但每个用户无需频繁操作情况下需用短连好。

由上可以看出,长连接可以省去较多的TCP建立和关闭的操作,减少浪费,节约时间。对于频繁请求资源的客户来说,较适用长连接。不过这里存在一个问题存活功能的探测周期太长,还有就是它只是探测TCP连接的存活,属于比较斯文的做法,遇到恶意的连接时,保活功能就不够使了。在长连接的应用场景下,client端一般不会主动关闭它们之间的连接,Client与server之间的连接如果一直不关闭的话,会存在一个问题,随着客户端连接越来越多,server早晚有扛不住的时候,这时候server端需要采取一些策略,如关闭一些长时间没有读写事件发生的连接,这样可 以避免一些恶意连接导致server端服务受损;如果条件再允许就可以以客户端机器为颗粒度,限制每个客户端的最大长连接数,这样可以完全避免某个蛋疼的客户端连累后端服务。

短连接对于服务器来说管理较为简单,存在的连接都是有用的连接,不需要额外的控制手段。但如果客户请求频繁,将在TCP的建立和关闭操作上浪费时间和带宽

6. HTTP1,HTTP2,HTTP3区别

HTTP/1.x 有连接无法复用、队头阻塞、协议开销大和安全因素等多个缺陷

HTTP/1.0 传输数据时,每次都需要重新建立连接,增加延迟。

HTTP/1.1 虽然加入 keep-alive 可以复用一部分连接,但域名分片等情况下仍然需要建立多个 connection,耗费资源,给服务器带来性能压力。

HTTP/2 通过多路复用、二进制流、Header 压缩等等技术,极大地提高了性能,但是还是存在着问题的

同个域名只需要占用一个 TCP 连接,使用一个连接并行发送多个请求和响应,消除了因多个 TCP 连接而带来的延时和内存消耗。并行交错地发送多个请求,请求之间互不影响。并行交错地发送多个响应,响应之间互不干扰。

在 HTTP/2 中,每个请求都可以带一个 31bit 的优先值,0 表示最高优先级, 数值越大优先级越低。有了这个优先值,客户端和服务器就可以在处理不同的流时采取不同的策略,以最优的方式发送流、消息和帧。

在 HTTP/2 中引入了多路复用的技术。多路复用很好的解决了浏览器限制同一个域名下的请求数量的问题,同时也接更容易实现全速传输,毕竟新开一个 TCP 连接都需要慢慢提升传输速度。

QUIC 基于 UDP 实现,是 HTTP/3 中的底层支撑协议,该协议基于 UDP,又取了 TCP 中的精华,实现了即快又可靠的协议

HTTP1.1 的缺陷

高延迟 — 队头阻塞(Head-Of-Line Blocking),无状态特性 — 阻碍交互, 明文传输 — 不安全性, 不支持服务端推送

HTTP2

新增特性:

二进制分帧 - HTTP2 性能增强的核心,  多路复用 - 解决串行的文件传输和连接数过多

二进制分帧

首先,HTTP2 没有改变 HTTP1 的语义,只是在应用层使用二进制分帧方式传输。因此,也引入了新的通信单位:帧、消息、流

分帧有什么好处?服务器单位时间接收到的请求数变多,可以提高并发数。最重要的是,为多路复用提供了底层支持。

多路复用

一个域名对应一个连接,一个流代表了一个完整的请求-响应过程。是最小的数据单位,每个会标识出该帧属于哪个也就是多个帧组成的数据流。多路复用,就是在一个 TCP 连接中可以存在多个流。

二进制分帧

首先,HTTP2 没有改变 HTTP1 的语义,只是在应用层使用二进制分帧方式传输。因此,也引入了新的通信单位:帧、消息、流。分帧有什么好处?服务器单位时间接收到的请求数变多,可以提高并发数。最重要的是,为多路复用提供了底层支持。

多路复用

一个域名对应一个连接,一个流代表了一个完整的请求-响应过程。是最小的数据单位,每个会标识出该帧属于哪个也就是多个帧组成的数据流。多路复用,就是在一个 TCP 连接中可以存在多个流。

QUIC

简介

Google

在推 SPDY 的时候就已经意识到了这些问题,于是就另起炉灶搞了一个基于 UDP 协议的 QUIC 协议。而这个就是 HTTP3。它真正“完美”地解决了“队头阻塞”问题。

主要特点

改进的拥塞控制、可靠传输

快速握手

集成了 TLS 1.3 加密

多路复用

连接迁移

7.常见HTTP代码

2XX

200 OK (RFC7231)

201 Created (RFC7231)

请求成功,正在创建一个或更多新资源。Location 标头中应存在新资源的位置,或由请求的 URI 提供。通常,有效负载将描述并引用新生成资源的链接。

205 Reset Content (RFC7231)

源站服务器建议客户端将视图重置为请求之前的原始状态。通常用于表单或其他输入提交。在请求中发送了有效负载,源站服务器成功进行了操作,现在通知浏览器允许进行其他提交。

206 Partial Content (RFC 7233)

请求的部分资源已成功,并位于有效负载中。请求必须已通过以下方式之一注明了范围:

单个部分请求带有 HTTP 标头,包括 Content Range 后跟大小。(如果响应标头中存在,则必须与有效负载中的八位字节完全相等)例如,Content Range: bytes 21010-47021/47022

HTTP 标头中有多个与 Content-Type: multipart/byteranges 相关的块,包括为各个部分分别列出 Content-Range 字段,但在响应 HTTP 标头中。也需要 RFC 7233 第 4.1 节中规定的分界线。例如

206 通常用于处理需要分割的较大文件的客户端,或者具有多个同步流以改进延迟的已中断下载。

301 Moved Permanently (RFC7231)

所请求资源的永久 URL 重定向。目标资源已被分配了新的永久 URI,日后引用该资源时都应使用所含的某一个 URI

3、301重定向与302重定向的区别

302重定向是暂时的重定向,搜索引擎会抓取新的内容而保留旧的网址。因为服务器返回302代码,搜索引擎认为新的网址只是暂时的。

301重定向是永久的重定向,搜索引擎在抓取新内容的同时也将旧的网址替换为重定向之后的网址。

从网址A 做一个302 重定向到网址B 时,主机服务器的隐含意思是网址A 随时有可能改主意,重新显示本身的内容或转向其他的地方。大部分的搜索引擎在大部分情况下,当收到302 重定向时,一般只要去抓取目标网址就可以了,也就是说网址B。如果搜索引擎在遇到302 转向时,百分之百的都抓取目标网址B 的话,就不用担心网址URL 劫持了。问题就在于,有的时候搜索引擎,尤其是Google,并不能总是抓取目标网址

304 Not Modified  (RFC 7232)

提醒客户端,请求的资源在缓存中可用并且有效。源站服务器未曾修改请求所查询的资源。客户端可以接收指定资源的有效负载,无需再次连接源站服务器,因此它将重定向请求以使用存储的资源。 [RFC7234] 第 4.3.4 节中定义了有关可接收 304 响应的缓存的要求。

在这一响应前,客户端发送了有条件 GET 或 HEAD 请求,以指定当前已存储了什么资源。服务器向客户端发出“OK”信号,以将此资源用作最新的版本,从而减少客户端和服务器之间的数据传输量。

4xx 客户端错误

400 Bad Request  (RFC7231)

服务器无法处理请求,由于某些内容被认为是客户端错误(例如,语法错误、无效的请求消息框架或异常的请求路径)

403 Forbidden (RFC7231)

出现此错误的主要原因是:

1.您设置的权限配置,或者您设置的 .htaccess 文件中配置的规则

2.Mod_security 规则。

3.IP 拒绝访问限制

404 Not Found (RFC7231)

源站服务器无法或不愿找到所请求的资源。这通常意味着主机服务器无法找到资源。 要发送此问题的永久错误消息,应使用 410 错误代码。

413 Payload Too Large  (RFC7231)

服务器拒绝处理请求,因为从客户端发送的负载大于服务器希望接受的有效负载。服务器可选择关闭连接。

429 Too Many Requests (RFC6585)

客户端在根据服务器指定的时间内发送了太多请求。429通常会在触发“Rate Limiting (速率限制)”时产生。服务器可以作出响应并提供信息,使请求者在特定时间段之后重试。

499 Client Close Request

Nginx 特定响应代码,表明当服务器仍在处理请求时,客户端主动关闭连接,使服务器无法返回状态代码。

Error 500: internal server error

500 错误通常表示您的源站 Web 服务器存在问题。 Error establishing database connection 是源站 Web 服务器生成的常见 HTTP 500 错误消息。 联系您的主机提供商来解决。

Error 502 bad gateway 或 Error 504 gateway timeout

联系您的主机提供商,在您的源站 Web 服务器上排查这些常见的原因:

确保在请求生成 生成 502 或 504 错误的访问者 URL 中的主机名和域名时,源站服务器能够响应请求。

调查服务器过载、崩溃或网络故障。

识别发生超时或被阻止的应用程序或服务。

请检查它们是否似乎正在使用基于DNS的负载均衡器(例如,他们拥有AWS ELB的CNAME) 记录)。 您还可以询问客户在Web服务器前是否还有其他基础架构。 沿原始路径的任何支持HTTP的软件都可以返回502,因此有必要检查每个日志。

Error 520: web server returns an unknown error

当源站服务器向返回空白、未知或意外响应时,会发生 520 错误

源站 Web 服务器应用程序崩溃

您的源站上未列入白名单。

源站 Web 服务器 TCP 空闲超时短于 300 秒

标头超过 8 KB(通常因为 Cookie 数量过多)

源站 Web 服务器的空响应中缺少 HTTP 状态代码或响应正文

缺少响应标头或源站 Web 服务器未返回正确的 HTTP 错误响应

520 错误普遍发生于造成源站 Web 服务器崩溃的 PHP 应用程序。

标准回答:

Web服务器或网络设备(防火墙,负载平衡器)在建立TCP连接后将其重置。 有时,当Web服务器崩溃时,它将重置连接。 检查您的Web服务器访问/错误日志,以了解发生错误的时间范围,并查找任何错误消息。

您的Web服务器返回的无效响应超出了我们的限制。 如果您的Web服务器返回太多/太大的标头,通常会发生这种情况。 例如,这通常是由返回过多cookie的失控脚本引起的。 Code Igniter PHP框架也与此有关。

Error 503: service temporarily unavailable

HTTP 错误 503 在源站 Web 服务器过载时发生。可能的原因有两种,可通过错误消息来辨别

解决方案:联系您的主机提供商,以核实是否针对您的源站 Web 服务器的请求实施了速率限制。

503 Service Unavailable消息,表示您需要联系托管服务提供商以寻求帮助或查看本地错误日志。 上游503可以指示资源耗尽或失败的进程,并且应从服务器或应用程序日志中清除确切原因。

Error 521: web server is down

源站 Web 服务器拒绝来连接时,会发生 521 错误。源站上的安全解决方案可能阻止了来自某些 IP地址的合法连接。

521 错误的两个最常见原因:

源站 Web 服务器应用程序离线,CDN 请求被阻止

Error 522: connection timed out

联系源站 Web 服务器时超时会发生 522 错误。有两种不同的错误导致 HTTP 错误 522,具体取决于CDN和源站 Web 服务器之间发生超时的时间:

在连接建立之前,源站 Web 服务器未在CDN发送 SYN 后 15 秒内将 SYN + ACK 返回给 Cloudflare。

在连接建立之后,源站 Web 服务器未在 90 秒内确认(ACK) 的资源请求。

联系您的主机提供商,从源站 Web 服务器上排查下列常见原因:

(最常见).htaccess、iptables 或防火墙中阻止了 对CDN或对其设置了速率限制。确认您的主机提供商已将CDN的IP Range地址列入白名单。

源站 Web 服务器过载或离线,因而丢弃了传入的请求。

源站 Web 服务器上禁用了 Keepalives 功能。

从源站 Web 服务器到发生问题前最常连接您的源站 Web 服务器的 的 MTR 或 traceroute 结果。在源站 Web 服务器日志记录的 IP 中,找到一个可成功连接的 IP。

Error 523: origin is unreachable

当 无法联系您的源站 Web 服务器时,会发生 523 错误。这通常在CDN和源站 Web 服务器之间的网络设备没有通向源站 IP 地址的路由时发生。

Error 524: a timeout occurred

524 错误表明 成功连接了源服务器,但源站 Web 服务器没有在默认的 100 秒连接超时结束前提供 HTTP 响应。

从您的源站 Web 服务器上排查下列常见原因:

源站 Web 服务器上长时间运行的进程。发生过载的源站 Web 服务器。

源站 Web 服务器上记录请求响应时间有助于辨别资源速度缓慢的原因。联系您的主机提供商或站点管理员,以协助调整日志格式,或者搜索适用于您的 Web 服务器品牌(如 Apache 或 Nginx)的日志文档

当我们能够建立与您的原始Web服务器的TCP连接时,就会发生[524错误] 但您的网络服务器在连接超时限制(大约100秒)之前没有响应。此错误通常是由源服务器上的长时间运行过程引起的,例如PHP应用程序或数据库查询,Web服务器必须在响应请求之前等待。

此错误也可能是源服务器超载导致的-如果您看到此错误,则最好检查服务器的可用资源,包括CPU和RAM以及总流量水平。 如果您的服务器具有较高的CPU负载或内存不足,则可能表明资源有问题。我继续检查了过去24小时的日志,发现在此期间没有其他524错误。

最有效方法是直接向其原始Web服务器使用以下cURL请求,该请求计算TCP连接发生所需的时间以及从其Web服务器(TTFB)传输到第一个字节的时间。

curl -sv -o /dev/null -w "Connect: %{time_connect} \n TTFB: %{time_starttransfer} \n Total time: %{time_total} \n" https://www.scott.cf/sleep.php --resolve www.scott.cf:443:[origin IP]

Error 525:SSL handshake failed

525 错误通常由源站 Web 服务器中的配置问题引起。满足以下两个条件时会发生 525 错误:

1.原始Web服务器未安装证书。

2.原始Web服务器未在端口443(或其他自定义安全端口)上侦听。

3.原始Web服务器不支持SNI或配置不正确。

4.接受的密码套件与原始服务器支持的密码套件不匹配。

方案1:原始Web服务器未安装证书。

curl -s --resolve hostname:443:serveripaddress https://example.com -vso /dev/null -k

openssl s_client -showcerts -connect serveripaddress:443 -servername hostname< /dev/null | openssl x509 -noout -text

93/5000

方案2:原始Web服务器未在端口443(或其他自定义安全端口)上侦听。

nmap -p 443 ec2-52-72-30-86.compute-1.amazonaws.com

方案3:原始Web服务器不支持SNI或未正确配置SNI。

wireshark

Error 526: invalid SSL certificate

请您服务器管理员或主机提供商核查源站 Web 服务器的 SSL 证书,并进行以下验证:

证书没有到期, 证书没有撤销, 证书由书颁发机构签名(而非自签名)

所请求的域名和主机名列在证书的 Common Name 或 Subject Alternative Name 中

您的源站 Web 服务器接受通过 SSL 端口 443 进行连接

并访问 https://www.sslshopper.com/ssl-checker.html#hostname=www.example.com(将 www.example.com 替换为您的主机名和域名),以验源站 SSL 证书并无问题:

检查原始服务器上是否存在带有有效主机名并由证书颁发机构签名的证书。

$ openssl s_client -connect $ORIGIN_IP:443 -servername $DOMAIN < /dev/null 2>/dev/null | openssl x509 -noout -text |grep 'DNS:\|Issuer:\|Subject:';

$ echo | openssl s_client -servername $DOMAIN -connect $ORIGIN_SERVER_IP:443 2>/dev/null | openssl x509 -noout -dates

8.curl是基于URL语法在命令行方式下工作的文件传输工具,它支持FTP,FTPS,HTTP,HTTPS,GOPHER,TELNET,DICT,FILE及LDAP等协议。curl支持HTTPS认证,并且支持HTTP的POST,PUT等方法,FTP上传,kerberos认证,HTTP上传,代理服务器,cookies,用户名/密码认证,通过http代理服务器上传文件到FTP服务器等等,功能十分强大。

这一系列标志指定详细的响应,同时将页面的输出/正文转储到本地/ dev / null项,该项立即丢弃该信息并且不保存。 这用于提供干净的信息显示,例如请求/响应头。 以下是这些选项的细分:

-s:静默模式。 删除显示进度表或错误消息。

-v:启用详细输出。

-o / dev / null:将输出设置为文件。 在这种情况下,我们会将页面正文发送到/ dev / null项目。

Debugging HTTP Errors

curl -svo /dev/null --header "Host: example.com" http://123.123.123.123/

上面的--header选项对于发送特定的请求标头非常有用,例如Host,Set-Cookie甚至是在唯一的客户应用程序/平台中使用的自定义标头。

在较新版本的curl还支持一个为例子显示下:–resolve的选项,可以直接用来指定对url的解析

curl -svo /dev/null --resolve example.com:80:123.123.123.123 http://example.com/

resolve选项为特定主机和端口设置自定义地址。 这提供了使用指定地址发送curl请求的功能,并防止使用其他通常可以解析的地址(替代修改本地/ etc / hosts文件的命令行)。 该选项对于比较原始服务器与特定服务器之间的服务器响应非常有用。

这显示了完成请求所花费的总时间:

curl -svo /dev/null https://example.com/ -w "\nContent Type: %{content_type} \

\nHTTP Code: %{http_code} \

\nHTTP Connect:%{http_connect} \

\nNumber Connects: %{num_connects} \

\nNumber Redirects: %{num_redirects} \

\nRedirect URL: %{redirect_url} \

\nSize Download: %{size_download} \

\nSize Upload: %{size_upload} \

\nSSL Verify: %{ssl_verify_result} \

\nTime Handshake: %{time_appconnect} \

\nTime Connect: %{time_connect} \

\nName Lookup Time: %{time_namelookup} \

\nTime Pretransfer: %{time_pretransfer} \

\nTime Redirect: %{time_redirect} \

\nTime Start Transfer: %{time_starttransfer} \

\nTime Total: %{time_total} \

Debugging SSL/TLS

curl -svo /dev/null https://whiskytango.us/ 2>&1 | egrep -v "^{.*$|^}.*$|^\* http.*$"

字符串2>&1 | egrep -v“ ^ {。* $ | ^}。* $ | ^ \ * http。* $”可用于清理和解析cURL输出,以减少TLS握手/证书信息的干扰。

WebSocket的使用场景

社交聊天、弹幕、多玩家游戏、协同编辑、股票基金实时报价、体育实况更新、视频会议/聊天、基于位置的应用、在线教育、智能家居等需要高实时的场景

WebSocket 的其他特点:

建立在 TCP 协议之上,服务器端的实现比较容易。

与 HTTP 协议有着良好的兼容性。默认端口也是80和443,并且握手阶段采用 HTTP 协议,因此握手时不容易屏蔽,能通过各种 HTTP 代理服务器。

数据格式比较轻量,性能开销小,通信高效。

可以发送文本,也可以发送二进制数据。

没有同源限制,客户端可以与任意服务器通信。

协议标识符是ws(如果加密,则为wss),服务器网址就是 URL。

由轮询到WebSocket

1 轮询

客户端和服务器之间会一直进行连接,每隔一段时间就询问一次。客户端会轮询,有没有新消息。这种方式连接数会很多,一个接受,一个发送。而且每次发送请求都会有Http的Header,会很耗流量,也会消耗CPU的利用率。

2 长轮询

长轮询是对轮询的改进版,客户端发送HTTP给服务器之后,有没有新消息,如果没有新消息,就一直等待。当有新消息的时候,才会返回给客户端。在某种程度上减小了网络带宽和CPU利用率等问题。但是这种方式还是有一种弊端:例如假设服务器端的数据更新速度很快,服务器在传送一个数据包给客户端后必须等待客户端的下一个Get请求到来,才能传递第二个更新的数据包给客户端,那么这样的话,客户端显示实时数据最快的时间为2×RTT(往返时间),而且如果在网络拥塞的情况下,这个时间用户是不能接受的,比如在股市的的报价上。另外,由于http数据包的头部数据量往往很大(通常有400多个字节),但是真正被服务器需要的数据却很少(有时只有10个字节左右),这样的数据包在网络上周期性的传输,难免对网络带宽是一种浪费。

3  WebSocket

现在急需的需求是能支持客户端和服务器端的双向通信,而且协议的头部又没有HTTP的Header那么大,于是,Websocket就诞生了!流量消耗方面,相同的每秒客户端轮询的次数,当次数高达数万每秒的高频率次数的时候,WebSocket消耗流量仅为轮询的几百分之一

WebSocket协议原理

Websocket是应用层第七层上的一个应用层协议,它必须依赖 HTTP 协议进行一次握手 ,握手成功后,数据就直接从 TCP 通道传输,与 HTTP 无关了。

Websocket的数据传输是frame形式传输的,比如会将一条消息分为几个frame,按照先后顺序传输出去。这样做会有几个好处:

1 大数据的传输可以分片传输,不用考虑到数据大小导致的长度标志位不足够的情况。

2 和http的chunk一样,可以边生成数据边传递消息,即提高传输效率。

WebSocket和Socket的区别与联系

首先,Socket 其实并不是一个协议。它工作在 OSI 模型会话层(第5层),是为了方便大家直接使用更底层协议(一般是 TCP 或 UDP )而存在的一个抽象层。Socket是对TCP/IP协议的封装,Socket本身并不是协议,而是一个调用接口(API)。

Socket通常也称作”套接字”,用于描述IP地址和端口,是一个通信链的句柄。网络上的两个程序通过一个双向的通讯连接实现数据的交换,这个双向链路的一端称为一个Socket,一个Socket由一个IP地址和一个端口号唯一确定。应用程序通常通过”套接字”向网络发出请求或者应答网络请求。

Socket在通讯过程中,服务端监听某个端口是否有连接请求,客户端向服务端发送连接请求,服务端收到连接请求向客户端发出接收消息,这样一个连接就建立起来了。客户端和服务端也都可以相互发送消息与对方进行通讯,直到双方连接断开

forward 和 redirect 的区别?

Forward和Redirect代表了两种请求转发方式:直接转发和间接转发。

直接转发方式(Forward),客户端和浏览器只发出一次请求,Servlet、HTML、JSP或其它信息资源,由第二个信息资源响应该请求,在请求对象request中,保存的对象对于每个信息资源是共享的。

间接转发方式(Redirect)实际是两次HTTP请求,服务器端在响应第一次请求的时候,让浏览器再向另外一个URL发出请求,从而达到转发的目的。

密钥套件

也称加密套件、密码套件,是 SSL 中最核心的算法套件,称之为套件是因为其中包含了密钥交换算法、签名算法、加密算法和摘要算法,由两个字节表示。以下是 TLS 密钥套件的语法:


那服务端又是怎么选择这个密钥套件呢?在 openssl 里面密钥套件的选择与几个因素有关:

1.服务端配置的密钥套件列表。

2.客户端支持的密钥套件列表。

3.服务端密钥套件列表优先还是客户端密钥套件列表优先。

4.已选择的 SSL 协议版本。

5.证书所支持的算法。

Cipher Suite,加密套件,即密码套件。是TLS/SSL网络协议中的一个概念。指在ssl通信中,服务器和客户端所使用的加密算法的组合。

一个加密套件是一个四件套,包含四个功能:密钥交换算法、身份验证算法 、对称加密算法和信息摘要算法。

密钥交换算法

顾名思义,该算法用来交换秘钥。

SSL 通信过程(握手结束后)中,双方使用的是对称加密的方式 。由于通信双方以前并不知道彼此的存在,它们也不可能预先存储相同的加密秘钥,那么应当怎么做呢?答案是在 SSL 通信的握手阶段,使用秘钥交换算法使双方使用的秘钥保持一致。

常用的密钥交换算法有RSA、Diffie-Hellman密钥交换、ECDH(Elliptic Curve Diffie-Hellman)、SRP(安全远程密码)、由TLS 1.2支持密钥交换算法PSK(Pre Shared Key)。

身份验证算法

身份验证又称“验证”、“鉴权”,是指通过一定的手段,完成对用户身份的确认。常用算法有 RSA、ECDSA、DSS

对称加密算法

对称加密(也叫私钥加密)指加密和解密使用相同密钥的加密算法。常用算法有 AES、DES、3DES。

信息摘要算法

根据某种运算规则对信息进行提取某种形式的提取,提取出来的数据就是摘要。主要用于验证信息的完整性。常用算法有 MD5、SHA-1。

举例说明

比如加密套件为:TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA1

TLS:通信协议

ECDHE:秘钥交换算法

ECDSA:身份验证算法

AES_128_CBC:通信时使用的对称加密算法

SHA1:信息摘要算法

网络---关于HTTP 304状态码的理解

首先看一个关于304请求的响应头的信息,这里面有两个比较重要的请求头字段:If-Modified-Since 和 If-None-Match,这两个字段表示发送的是一个条件请求

当客户端缓存了目标资源但不确定该缓存资源是否是最新版本的时候, 就会发送一个条件请求,这样就可以辨别出一个请求是否是条件请求,在进行条件请求时,客户端会提供给服务器一个If-Modified-Since请求头,其值为服务器上次返回的Last-Modified响应头中的Date日期值,还会提供一个If-None-Match请求头,值为服务器上次返回的ETag响应头的值。


服务器会读取到这两个请求头中的值,判断出客户端缓存的资源是否是最新的,如果是的话,服务器就会返回HTTP/304 Not Modified响应头, 但没有响应体.客户端收到304响应后,就会从本地缓存中读取对应的资源.

所以:出现304访问的情况下其实就是先在本地缓存了访问的资源,然后请求的时候流量其实就是cdn返回的响应头的字节数的流量。

网站加载 Waiting (TTFB) 时间过长的原因和解决办法

TTFB 是 Time to First Byte 的缩写,指的是浏览器开始收到服务器响应数据的时间(后台处理时间+重定向时间),是反映服务端响应速度的重要指标。就像你问朋友了一个问题,你的朋友思考了一会儿才给你答案,你朋友思考的时间就相当于 TTFB。你朋友思考的时间越短,就说明你朋友越聪明或者对你的问题越熟悉。对服务器来说,TTFB 时间越短,就说明服务器响应越快。

大家可以上传一些静态的 HTML 页面到服务器,然后打开这些静态页面,看一些这些页面的 TTFB 时间,大多数服务器的 TTFB 时间都在 50 ms 以下,这个时间就是我们优化时候可以追求的时间。下面两个图中的 TTFB 时间分别是本站所在服务器的静态和动态网页 TTFB 等待时间。

静态网页 Waiting (TTFB)时间

动态网页 Waiting (TTFB)时间

根据我们的测试,TTFB 时间如果超过了 500 ms,用户在打开网页的时候就会感觉到明显的等待。我么可以把 500 ms 以上认为是 TTFB 时间过长。可见,WordPress 智库的服务器还不算差。

TTFB 过长的原因

我们知道,对于动态网页来说,服务器收到用户打开一个页面的请求时,首先要从数据库中读取该页面需要的数据,然后把这些数据传入到模版中,模版渲染后,再返回给用户。由于查询数据和渲染模版需要需要一定的时间,在这个过程没有完成之前,浏览器就一致处于等待接收服务器响应的状态。有些服务的性能比较低,或者优化没做好,这个时间就会比较长。

当然,如果服务器到用户之间的网络不好,(比如,服务器在欧洲,用户在中国,用户打开网页的时候,请求需要跨越千山万水才能达到服务器),服务器接收到用户请求的时间过长,也是导致 TTFB 时间过长的原因。

有时候,页面在用户的浏览器中保存了过多的 Cookie,每次请求,这些 Cookie 都要发送到服务器,服务器都要处理这些 Cookie,这也是导致 TTFB 时间过长的原因之一。

Waiting (TTFB) 时间过长的解决办法

知道了原因,解决办法就显而易见了,那就是缩短服务器响应时间,最简单直接并且有效的办法就是使用缓存,把 PHP 和 MySQL 的执行时间最小化,一些缓存插件可以把 SQL 查询结果缓存起来,把几十次查询结果转换为几次;一些缓存插件可以直接把用户所请求的页面静态化,用户打开网页时,相当于直接从服务器上下载了静态页面。

如果是网络原因,换一个服务器是比较直接的解决办法。如果因为一些原因不能换服务器,可以使用一个 CDN,把页面同步到离用户比较近的 CDN 节点上,也是一个不错的解决办法。

如果是 Cookie 的原因,可以通过修改应用程序,删除一些不必要的 Cookie,或者精简 Cookie 内容,缩短 Cookie 的有效期等,都是解决办法。

影响 TTFB 的主要因素有三个:

CDN

一般网站会将静态内容分发到 CDN,CDN 的内容又会复制到其他地理位置的服务器,以便更接近用户,从而减少 TTFB 的时间。当然动态内容也可以放到 CDN 上,只要及时清除 cache 就行。

后端服务器的性能,后端服务器软件的和系统的设计

其实 TTFB 作为一个单一指数很难去衡量一个网站的真实速度和用户体验。主要就是讲在某些情况下,虽然 TTFB 很快,但是因为数据没有压缩,其实后面数据的传输反而慢,用户看到整个页面需要等待更久。

但是作为被动方,也就是用户,不能控制 server,研究这个也还是有价值的。比如需要实时获取一些数据的时候,如果要更快,你的服务器地址就有讲究了,这个 TTFB 指标就有用。

一般来讲,CDN 不会影响 TTFB,因为都是先加载 html,再是静态文件,例如图片和 css、js 文件等。但是大的 CDN 服务提供商,例如 Cloudflare 这样的,会从 DNS 层就开始控制,所以 DNS 和服务器的 会影响到 TTFB。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,029评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,395评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,570评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,535评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,650评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,850评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,006评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,747评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,207评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,536评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,683评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,342评论 4 330
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,964评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,772评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,004评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,401评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,566评论 2 349