一次完整 HTTP 调用涉及到的技术

916 阅读7分钟

DNS 解析域名

什么是 DNS

我们访问网站的时候会输入域名,而在真实网络中主机通信是通过 IP 地址进行通信的,DNS 服务器的作用就是将这域名字符串解析为对应的 IP 地址

有哪些 DNS 服务器

如果说每输入一个域名都需要去一个 DNS 服务器解析的话,全世界这么高的访问量,肯定是无法承载的,所以会对 DNS 服务器进行按层分级,不同类型的 DNS 服务器负责解析不同的域名

  • 本地 DNS 缓存:电脑会将解析到的域名和 IP 地址等缓存到本地上,windows 可以通过 ipconfig /displaydns 查看
  • 本地 DNS 服务器
    • 如果电脑是自己设置了 DNS 那么本地 DNS 服务器就是这个地址
    • 如果是根据路由器 DHCP 自动分配,那么本地 DNS 服务器就是路由器的 DNS 地址
    • 路由器会将请求分发给上层的网络服务提供商的 DNS
  • 根域名服务器:根服务器主要用来管理互联网的主目录,它包含了顶级域名服务器的 IP 地址
    • .com 顶级域名服务器对应的 IP 地址
    • .cn 顶级域名服务器对应的 IP 地址
    • .net 顶级域名服务器对应的 IP 地址
    • 其它
  • 顶级域名服务器:在它其中包含了权威域名的服务器的 IP 地址
  • 权威域名服务器:返回域名对应的目标主机 IP

DNS 解析流程

当我们输入 www.abc.com 域名的时候

  1. 首先去本地缓存中查找域名对应的 IP 是否存在,如果存在则直接返回
  2. 如果不存在则去本地 DNS 服务器中查找,如果本地 DNS 服务器有则直接返回
  3. 如果本地 DNS 服务器中不存在则开始递归查找
  4. 首先查找根域名服务器发现访问的是 .com 然后返回给本地 .com DNS 服务器对应的 IP 地址
  5. 然后本地继续去请求 .com 这个顶级域名服务器,顶级域名服务器查找到了 www.abc.com 对应的 DNS 服务器的 IP 地址返回给客户端
  6. 然后本地去请求 www.abc.com 对应的 DNS 服务器解析这个域名,DNS 服务器解析后返回对应的主机 IP 地址

在第 6 步骤,DNS 服务器解析后可以返回多个对应的主机 IP 地址,那么客户端访问的时候可以通过随机或者轮询等访问做简单的负载均衡处理

上述流程就是一个没有给域名配置 CDN 的流程

CDN 加速静态资源访问

什么是 CDN

百度百科:CDN是构建在现有网络基础之上的智能虚拟网络,依靠部署在各地的边缘服务器,通过中心平台的负载均衡、内容分发、调度等功能模块,使用户就近获取所需内容,降低网络拥塞,提高用户访问响应速度和命中率。CDN的关键技术主要有内容存储分发技术

内存存储

比如说我们有个图片网站应用部署在成都,一开始应用只在成都当地推广本地人使用。后面业务发展出去了,全国各地的人都在访问了,处于新疆乌鲁木齐的用户发现图片加载的速度变得很慢(因为图片这些数据需要从成都通过网线传输到乌鲁木齐太远了,而且中途可能存在网络拥挤等等原因)那么想个办法,我们在乌鲁木齐部署一个缓存服务器,后续乌鲁木齐的用户只要访问过某张图片就将其缓存到乌鲁木齐的服务器上,后续的访问就可以变得更快

分发技术

比如说访问乌鲁木齐缓存服务器没有对应的图片缓存的时候,这个时候可以去访问西北数据中心获取数据,西北数据中心没有再去源数据中心获取,这样可以尽可能的减少对源数据中心的访问减少源数据中心压力的同时,加速用户的访问体验

  • 边缘结点:距离用户最近的数据访问中心,比如成都
  • 区域结点:如果边缘结点中没有查找到到对应的缓存可以去区域结点中,比如西南区域
  • 中心节点:如果区域结点数据还是没有命中则需要回源(访问源数据中心节点)

经过一层一层数据中心节点数据访问过后,数据会依次缓存到对应的数据中心节点中,后续用户访问就可以临近访问了

CDN 可以缓存什么

网页、图片、文件等一些不经常改变的数据,可以缓存到 CDN 中

CDN 如何更新数据

查找的数据有可能不存在,也有可能过期了,如何更新 CDN 缓存呢

  • 拉取模式
  • 推送模式

如果是某份热点数据,一开始就近 CDN 缓存中没有就向上拉取,如果出现回源,可能导致源数据中心压力会过大。

这个时候可以采取主动推送模式,将热点数据主动推送到边缘结点。

CDN 带来的问题

  • 防盗链问题
    • 请求附带 refer 标示来源
    • 时间戳防盗链
  • 数据过期问题
    • 当服务器数据更新后,CDN 数据还未更新时静态资源访问可能存在不一致的问题
    • 资源都是有设置过期时间的,等到过期时间到了就会回源拉取最新内容
    • 主动刷新 CDN 缓存,强制性的让缓存失效全部回源拉取最新数据

CDN 解析流程

  1. 此时配置了 CDN 后,不会直接返回对应的 IP 地址而是返回 CNAME 对应的 CDN 域名 abc.cdn.com
  2. 解析 abc.cdn.com 得到对应的 IP 地址后请求该 CDN DNS 服务器,此时返回全局负载均衡域名地址
  3. 解析 abc.cdn.gslb.com 得到对应的 IP 地址后请求该全局负载均衡器,根据用户的 IP 地址、所处运营商、URL 携带内容以及各 CDN 服务器的负载情况选择最为合适的最近的一台或者多态服务器的 IP 地址给客户端
  4. 客户端可以通过简单的随机或者轮询等操作发起调用

建立 HTTP 连接

HTTP 协议通过 TCP 协议进行数据传输,在传输数据之前需要建立 TCP 连接

在 HTTP 通信的时候,建立连接和断开连接分别需要 3 次握手和四次挥手,效率还是很低的在 HTTP/1.0 的时候每次发送数据都需要建立连接响应完成后就需要断开连接。自 HTTP/1.1 开始就是长连接了,除非一端主动断开连接,这样极大的提升了通信的效率。

服务端负载均衡处理

服务端一般采用 Nginx 等服务器来做负载均衡处理,客户端过来的 HTTP 请求会与 Nginx 建立长连接后开始数据传输到达 Nginx,Nginx 会维护到达不同服务器的长连接将数据转发到真实的后端服务器

当然 nginx 也可以以短连接的方式发起请求,只是使用长连接能够减少 3 次握手和 4 次挥手大大的提升通信效率,减缓网络拥挤的情况

长连接带来的问题

我们使用长连接的时候会设置长连接的超时时间,到达时候会释放连接,那么在连接释放的时候,首先服务端会发送 FIN 包到达客户端,客户端还未收到 FIN 包的时候,发起了一个 HTTP 请求的话,那么这个请求就会响应 NoHttpResponseException

解决方案:

  • 客户端重试机制(指定最多重试的次数)
  • 定时提前清理闲置的链接,客户端启用定时任务,在超时之前主动与服务端断开连接即可

参考

  • 图解 HTTP
  • 图解 TCP/IP 协议
  • 极客时间,趣谈网络协议