Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

auto-archiving for issue #271 #272

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
<!-- 为了更方便归档,请先完善以上信息,正文贴下面 -->
<!--
注意点:
0. 文章中的资源(主要是图片)引用请使用 HTTPS
1. 文章末可以加上自己的署名,如: by [Kaola](http://www.kaola.com)
2. 最好不要用 NOS 图床,感觉加防盗链是迟早的事
3. 文章会定期归档到 https://blog.kaolafed.com/
-->
*很久以前理解过一个URL从在浏览器地址栏输入,到呈现页面都发生了什么。前两天碰到一个nginx反向代理的问题,又回想起这个流程,我想是对这个流程理解的还不够透彻,所以特意抽出时间来总结一下。*


废话不多说先上图
![](https://oscimg.oschina.net/oscnet/9b45c727a7bfccc992d165ed2a358b31138.jpg)

**一个URL从在浏览器地址栏输入,到呈现页面经历了:**
1. DNS解析,查找域名服务器
2. TCP三次握手
3. 发送http请求
4. nginx反向代理
5. servlet处理请求,返回http请求信息
7. 关闭TCP连接,四次挥手
6. 浏览器根据返回内容渲染页面

## DNS解析
DNS解析就是使用你输入的域名:www.kaola.com 去定位真正的ip地址

DNS解析是一个递归查询的过程,具体步骤如下图
![](https://oscimg.oschina.net/oscnet/35c85b079e628c53fcaf261f24750cb94f2.jpg)


1. 本地域名服务器查找有没有www.kaola.com所对应的ip
2. 本地服务器未查找到,则去根域名服务器查找
3. 根域名服务器未找到相应ip,会返回一级域名服务器地址
4. 查找一级域名服务器
5. 一级域名服务器未找到相应ip,返回二级域名服务器地址
6. 查找二级域名服务器
7. 二级域名服务器查看本地name.conf,是否有www主机的记录
8. 查到www主机的记录,返回www主机的ip到二级域名服务器
9. 返回ip到本地域名服务器
10. 返回ip到浏览器

**第9步,本地域名服务器拿到ip以后,会存入本地DNS缓存。

#### DNS优化
- DNS缓存: 浏览器缓存,系统缓存,路由器缓存,IPS服务器缓存,根域名服务器缓存,顶级域名服务器缓存,主域名服务器缓存。通过缓存直接读取域名相对应的ip,减去了繁琐的查找ip的步骤,大大加快访问速度。
- DNS负载均衡:使用CDN进行负载均衡,利用DNS的重定向技术,同步服务器运行情况,然后根据该情况及时适当调整调度策略,从而使得负载均衡能力大大提高。

## HTTP请求
客户端根据域名得到相应ip以后开始发送http请求,HTTP请求分为三个部分:TCP三次握手(图一3)、http请求响应信息(图一4、图一6)、关闭TCP连接(图一7)

### TCP三次握手
在客户端发送数据之前会发起**tcp三次握手**用以同步客户端和服务端的序列号和确认号,并交换TCP窗口大小信息。tcp三次握手的过程如下:
1. 第一次握手:客户端向服务端发送连接请求报文段,SYN和Seq,等待服务端确认(你在吗?)
2. 第二次握手:服务端收到报文段确认后,向客户端发送报文段。SYN、ACK和Seq(我在的!)
3. 第三次握手:客户端收到服务器的报文段,向服务器发送ACK和Seq。(好的,我知道你在了。)

### HTTP请求响应信息
TCP三次握手结束后,开始发送HTTP请求报文
#### http请求报文
TTP请求报文由请求行(request line)、请求头部(header)、请求主体三个部分组成。如下图所示:

![](https://oscimg.oschina.net/oscnet/6121051fe6116a357a9b3cbb2f7c5790884.jpg)

##### 1. 请求行包含:请求方法、URL、协议版本
- 请求方法包含8种:GET、POST、PUT、DELETE、PATCH、HEAD、OPTIONS、TRACE。
- URL即请求地址,由 *<协议>://<主机>:<端口>/<路径>?<参数>* 组成
- 协议版本即http版本号

##### 2. 请求头部包含请求的附加信息,由 名/值 对组成

##### 3. 请求主体包含回车符、换行符和请求数据,并不是所有请求都具有请求数据

#### http响应报文
http请求报文发送后,经过nginx服务器转发(图一5)、服务端servlet处理请求(图一6)之后,响应信息会以响应报文的形式返回给客户端。
*(图一5步骤后续补充)*

TTP响应报文由响应行(request line)、响应头部(header)、响应主体三个部分组成。如下图所示:

![](https://oscimg.oschina.net/oscnet/c7eb7a77458d4aa8bd4d9c395c2f5aacde5.jpg)

##### 1. 响应行包含:协议版本,状态码,状态码描述
状态码规则如下:
- 1xx:指示信息--表示请求已接收,继续处理。
- 2xx:成功--表示请求已被成功接收、理解、接受。
- 3xx:重定向--要完成请求必须进行更进一步的操作。
- 4xx:客户端错误--请求有语法错误或请求无法实现。
- 5xx:服务器端错误--服务器未能实现合法的请求。

##### 2. 响应头部包含响应报文的附加信息,由 名/值 对组成

##### 3.响应主体包含回车符、换行符和响应返回数据,并不是所有响应报文都有响应数据

### 关闭TCP连接,四次挥手
当数据传送完毕,需要断开tcp连接,此时发起tcp四次挥手
- 发起方向被动方发送报文,Fin、Ack、Seq,表示已经没有数据传输了。并进入FIN_WAIT_1状态。(嗨,我要走了)
- 被动方发送报文,Ack、Seq,表示同意关闭请求。此时主机发起方进入FIN_WAIT_2状态。(好的,准了)
- 被动方向发起方发送报文段,Fin、Ack、Seq,请求关闭连接。并进入LAST_ACK状态。(我也要走啦!)
- 发起方向被动方发送报文段,Ack、Seq。然后进入等待TIME_WAIT状态。被动方收到发起方的报文段以后关闭连接。发起方等待一定时间未收到回复,则正常关闭。(好的,我也批准了……怎么一直没回音?好吧,那我真的走了。)

## nginx反向代理
反向代理即指:将来自客户端的请求转发至内部网络中的服务器进行处理。并将服务器的结果返回给客户端。具体实现步骤如下图:

![](https://oscimg.oschina.net/oscnet/8a2e2d27bd8a3fa8cbc53f905e3956c7de8.jpg)

- 客户端发送请求到服务端的nginx服务器
- nginx服务器在缓存中查找请求内容,找到直接返回客户端。
- nginx服务器未找到请求内容,则将请求代理至相应的服务器。
- 相应服务器处理请求并返回请求信息给nginx服务器,nginx服务器将请求信息返回给用户。

#### nginx的优点
- 保护服务器,外网只能访问到反向代理服务器,对真正提供服务的服务器起到了保护的作用
- 节约ip资源
- 负载均衡,减少WEB服务器压力,提高响应速度
- 解决ajax跨域问题
- 可对所有请求进行的统一控制;
- 等等……

## 浏览器解析渲染页面

浏览器解析渲染页面分为一下五个步骤:
1. 根据HTML解析出DOM树
2. 根据CSS解析生成CSS规则树
3. 结合DOM树和CSS规则树,生成渲染树
4. 根据渲染树计算每一个节点的信息
5. 根据计算好的信息绘制页面

#### 根据HTML解析DOM树
- 根据HTML的内容,将标签按照结构解析成为DOM树,DOM树解析的过程是一个深度优先遍历。即先构建当前节点的所有子节点,再构建下一个兄弟节点。
- 在读取HTML文档,构建DOM树的过程中,若遇到script标签,则DOM树的构建会暂停,直至脚本执行完毕。

#### 根据CSS解析生成CSS规则树

- 解析CSS规则树时js 执行将暂停,直至CSS规则树就绪。
- 浏览器在CSS规则树生成之前不会进行渲染。

#### 结合DOM树和CSS规则树,生成渲染树

- DOM树和CSS规则树全部准备好了以后,浏览器才会开始构建渲染树。
- 精简 CSS 并可以加快CSS规则树的构建,从而加快页面相应速度。

#### 根据渲染树计算每一个节点的信息(布局)

- 布局:通过渲染树中渲染对象的信息,计算出每一个渲染对象的位置和尺寸
- 回流:在布局完成后,发现了某个部分发生了变化影响了布局,那就需要倒回去重新渲染。

#### 根据计算好的信息绘制页面
- 绘制阶段,系统会遍历呈现树,并调用呈现器的“paint”方法,将呈现器的内容显示在屏幕上。
- 重绘:某个元素的背景颜色,文字颜色等,不影响元素周围或内部布局的属性,将只会引起浏览器的重绘。
- 回流:某个元素的尺寸发生了变化,则需重新计算渲染树,重新渲染。

by [王潭 Summer](https://my.oschina.net/u/2600761/blog/1838482)