HTTP 连接处理

当我们在浏览一个web页面时,页面里的元素可能是来自于多个源的,例如每张图片有各自的来源。我们在浏览一个拥有2张图片的web页面时,浏览器需要发起3个HTTP事务,一个用于获取顶层HTML页面元素,另两个获取相对应的图片。

串行连接

如果只是简单的对连接进行管理,使用串行化的方式去请求资源。每个请求都需要等待前方的请求完毕,并且每个事务在请求时都需要建立连接-传输数据-关闭连接。

使用串行化的方式去请求,则我们拥有了三倍的连接时延和慢启动时延


并行连接

HTTP允许客户端同时打开多条连接,并行地执行多个HTTP事务。此时,每个请求不用等待其他请求的处理情况,自行建立连接去执行自身的HTTP事务即可。

HTTP 延时

HTTP性能优化一直是个十分重要的话题,但要进行优化,首先得找出有哪些地方会导致HTTP延时。

HTTP 请求过程

在HTTP请求传输的过程中,会经历这样的场景和可能遇见如下的问题:

1 . 用户输入或打开一个地址,client查找本地http缓存,如果有未过期的本地缓存,则直接200(from cache),请求结束。

现代浏览器有这样的机制,在访问server时,由server返回的HTTP响应头控制。

2 . client查找本地DNS缓存查看是否已有DNS信息,如果没有,则向DNS解析服务器请求server的IP地址

当本地DNS缓存中已有本次访问所需的信息,那么这里几乎是无延迟的,但如果client需要向DNS解析服务器请求,则会有一定的延时

3 . client向server发送一条TCP连接请求,并等待server的响应。

在这里,开始TCP的三次握手建立连接。如果client和server的网络情况并不好(网络抖动、地域过远、连接拥挤等),则会花费很长的时间。

4 . 一旦连接建立起来,则client通过新建立的TCP管道向server发送HTTP请求,当数据到达时,server从TCP管道中读取请求的报文,并对请求进行处理

在这里,依然有可能受到网络的影响,使得请求报文的传输较慢,或者是当server的负载过高,或者是server处理的是一个复杂的动态资源,或者是server底层依赖的上游服务响应较慢(例如server作为反向代理),都会使得这一阶段的延时增加。

5 . server将处理完毕后的HTTP响应,通过TCP管道回送到client。

在这里,依然可能被网络情况所影响。

6 . 请求/响应 的内容过长,也会使得传输的时间变长,毕竟传输速度不变的情况下,内容越多,所需时间越长。

所以这样一个简单请求中,也包含了硬件速度、网络、服务器负载、请求/响应报文尺寸、client/server的距离等这么多的坑等着你踩。

HTTP header

HTTP报文 一章中,我们介绍了HTTP协议由 行、头、体组成。而本章,介绍 “头”

如果你写了一个小爬虫,但抓出来的结果和想象的不同(例如界面样式,返回内容和人工看有差异,或者是需要登录),你可以更改你发送的HTTP请求的header部分,将合法的User-Agent、Cookie等添上,能解决大多数此类问题,因为HTTP是无状态并且不安全的协议,所以这些小手段能够生效。

下面取几个常用的头字段来做介绍。

请求首部:

请求首部就是由客户端,放在HTTP请求头中发送给服务器的部分。

User Agent(用户代理)

简称 UA,它是一个特殊字符串头,使得服务器能够识别客户使用的操作系统及版本、CPU 类型、浏览器及版本、浏览器渲染引擎、浏览器语言、浏览器插件等。从而为来自不同平台/浏览器的用户,提供最适合的响应内容。(例如,移动用户不应该收到PC网页的响应,就是由User Agent来做识别的)

Referer (来源)

它表示用户是从哪个网页发起的请求。通常用来做图片防盗链。
例如在图片服务器中解析请求判断Referer,如果非白名单站点发过来的请求,则返回一个防盗链的图片给请求方。

Mysql 事务隔离级别

当多个线程都开启事务操作数据库中的数据时,数据库系统要能进行隔离操作,以保证各个线程获取数据的准确性。


隔离级别

在SQL标准中定义了四种隔离级别,每一种级别都规定了一个事务中所做的修改,在事务内和事务间的可见性。较低级别的隔离通常可以执行更高的并发,系统的开销也更低。

READ UNCOMMITTED (未提交读/脏读)

在READ UNCOMMITTED级别中,事务所做的写操作,即使没有提交,对其他事务也是可见的,A事务可以读取B事务未提交的数据,这就叫做未提交读/脏读。 这个级别会导致很多问题,但从性能上来说,并不比其他级别好太多

READ COMMITTED (提交读/不可重复读)

大部分数据库系统的默认隔离级别就是 READ COMMITTED,它解决了脏读的问题,当一个事务开始时,只能“看见”已提交的事务所做的修改。但这也会引入一个不可重复读的问题:事务A在执行过程中有两次对变量a的读取,而在这两次读取之间,事务B对a做了修改,就会导致事务A的两次读取出的值不同,这就叫“不可重复读”。

HTTP 状态码

HTTP的状态码被分为了5大类,分别是:

1xx : Hold on (等着)
2xx : Here you go (执行完了,没毛病,拿着结果回去吧)
3xx : Go away (你要的不在我这儿,去别处找)
4xx : You fucked up (你丫出问题了)
5xx : I fucked up (我特么出问题了)

状态码为客户端提供了一种理解事务处理结果的便捷方式(比解析字符串方便多了)

1xx (信息性状态码):

一般来说,1xx类的状态码,发生在客户端和服务器交互过程中,两者对于某些情况做一定的约定,例如:

100 - Continue:说明收到了请求的初始部分,请客户端继续,发送了这个状态码之后,服务端在收到请求之后必须进行响应。

101 - Switching Protocols:说明服务器正在根据客户端的指定,将将协议切换成Update首部所列的协议

信息性状态码一般是在请求过程中,双方互相通知状态所使用,一般不会影响到本次请求的成功/失败。