这次只专注应用层。
-
准备:
通过 DNS 协议获取 IP 地址,三次握手建立 TCP 连接。就可以发送 HTTP 请求了。 -
web 服务器:
用户发送 HTTP 请求,web 服务器(以 Nginx 为例)对请求进行负载均衡。也就是说如果请求的是静态资源,Nginx 自己就可以处理,如果请求的是动态资源,Nginx 就会把它转发给应用服务器。 -
应用服务器
处理动态资源请求,从数据库中取出数据,发回给 Nginx,Nginx 再发回给浏览器。 -
浏览器
把得到的静态资源 HTML 文件变成 DOM Tree,CSS 变成 CSS Rule Tree,JavaScript 变成 DOM Tree 。然后共同作用生成 Render Tree,之后布局,绘制。
但是这里每一步都有许多细节,并且为了后续的请求,还会做些额外的操作。例如:
- DNS 协议采用的是 TCP 还是 UDP 连接?
- 获取到 IP 地址后,为了方便下次访问,浏览器会额外做些什么?
- 三次握手建立连接具体是怎样?
- Nginx 是如何处理请求的?单线程?多线程?复用 IO?复用 IO 有哪几种?
- 当应用服务器不止一个时,Nginx 又是如何选择把动态资源请求发给哪个应用服务器?
- 应用服务器是如何处理请求的?BIO? NIO?
- 如何控制动态资源有效期?如果过期了,如何确认是否被修改?
- 如何查看缓存,如何无视缓存强制刷新?
解答:
- 当域名字节低于 512 时,DNS 采用 UDP 连接;高于 521 字节,采用 TCP 连接。
- 浏览器会把 IP 地址缓存起来,可通过 查看。
- 略。
- 单线程,简单,但性能羸弱。
多线程,当线程数很多时,线程本身与线程间的切换都消耗大量 CPU 资源。
复用 IO 如 epoll,监视所有连接,当连接有数据读写时,才用一个线程处理那个连接,处理完后继续监视,等待下次状态变化。 - 轮询:按次序逐个转发。
权重:给每个应用服务器指定一个权重,作为转发概率。
ip_hash:对 IP 做 hash 操作,找个服务器转发,这样同一个 IP 总是转发到同一个应用服务器。
fair:哪个应用服务器响应时间短,就转发给哪个。 - BIO,Blocking IO,每个线程处理一个请求。
NIO,non-blocking IO,若干个线程处理所有请求。 - Cache-Control、Expire 控制资源有效期,Last-Modified、ETag 判断资源是否被修改。
- 查看缓存:,强制刷新:Ctrl + F5 。