2020-05-12

【未完】从URL输入到....

写在前面

  • 嘿嘿嘿 😱
  • 别想歪,我们这个系列要做的是从经典面试题入手
  • 简单了解一下计算机网络相关知识。是的,Elle 很惨😭 计算机网络学得稀烂

简单过程

  • 你先在浏览器里面输入 https://ele-peng.github.io/ ,这是一个 URL。浏览器只知道名字是“ele-peng.github.io”,但是不知道具体的地点,所以不知道应该如何访问。于是,它打开地址簿去查找。可以使用一般的地址簿协议 DNS 去查找,还可以使用另一种更加精准的地址簿查找协议 HTTPDNS 。
  • 无论用哪一种方法查找,最终都会得到这个地址:52.74.223.119。这个是 IP 地址,是互联网世界的“门牌号”。
  • 知道了目标地址,浏览器就开始打包它的请求。这里会使用HTTPS协议。无论是什么协议,里面都会写明“你要请求什么”。
  • DNS、HTTP、HTTPS 所在的层我们称为应用层。经过应用层封装后,浏览器会将应用层的包交给下一层去完成,通过 socket 编程来实现。下一层是传输层。传输层有两种协议,一种是无连接的协议UDP,一种是面向连接的协议TCP。这里使用 TCP 协议。所谓的面向连接就是,TCP 会保证这个包能够到达目的地。如果不能到达,就会重新发送,直至到达。
  • TCP 协议里面会有两个端口,一个是浏览器监听的端口,一个是 github 的服务器监听的端口。操作系统往往通过端口来判断,它得到的包应该给哪个进程。
  • 传输层封装完毕后,浏览器会将包交给操作系统的网络层。网络层的协议是 IP 协议。在 IP 协议里面会有源 IP 地址,即浏览器所在机器的 IP 地址和目标 IP 地址,也即 github 所在服务器的 IP 地址。
  • 操作系统既然知道了目标 IP 地址,就开始想如何根据这个门牌号找到目标机器。操作系统往往会判断,这个目标 IP 地址是本地人,还是外地人。如果是本地人,从门牌号就能看出来,但是显然 github 网站不在本地,而在遥远的地方。
  • 操作系统知道要离开本地去远方。虽然不知道远方在何处,但是可以这样类比一下:如果去国外要去海关,去外地就要去网关。而操作系统启动的时候,就会被 DHCP 协议配置 IP 地址,以及默认的网关的 IP 地址 192.168.1.1。
  • 操作系统如何将 IP 地址发给网关呢?在本地通信基本靠吼,于是操作系统大吼一声,谁是 192.168.1.1 啊?网关会回答它,我就是,我的本地地址在村东头。这个本地地址就是 MAC 地址,而大吼的那一声是 ARP 协议。
  • 于是操作系统将 IP 包交给了下一层,也就是 MAC 层。网卡再将包发出去。由于这个包里面是有 MAC 地址的,因而它能够到达网关。
  • 网关收到包之后,会根据自己的知识,判断下一步应该怎么走。网关往往是一个路由器,到某个 IP 地址应该怎么走,这个叫作路由表。
  • 路由器有点像玄奘西行路过的一个个国家的一个个城关。每个城关都连着两个国家,每个国家相当于一个局域网,在每个国家内部,都可以使用本地的地址 MAC 进行通信。
  • 一旦跨越城关,就需要拿出 IP 头来问,目标 IP 地址怎么走?
  • 城关往往是知道这些“知识”的,因为城关和临近的城关也会经常沟通。到哪里应该怎么走,这种沟通的协议称为路由协议,常用的有 OSP F和 BGP 。
  • 城关与城关之间是一个国家,当网络包知道了下一步去哪个城关,还是要使用国家内部的 MAC 地址,通过下一个城关的 MAC 地址,找到下一个城关,然后再问下一步的路怎么走,一直到走出最后一个城关。
  • 最后一个城关知道这个网络包要去的地方。于是,对着这个国家吼一声,谁是目标 IP 啊?目标服务器就会回复一个 MAC 地址。网络包过关后,通过这个 MAC 地址就能找到目标服务器。
  • 目标服务器发现 MAC 地址对上了,取下 MAC 头来,发送给操作系统的网络层。发现 IP 也对上了,就取下 IP 头。IP 头里会写上一层封装的是 TCP 协议,然后将其交给传输层,即TCP 层。
  • 在这一层里,对于收到的每个包,都会有一个回复的包说明收到了。这个回复的包绝非这次查询请求的结果,而仅仅是 TCP 层的一个说明,即收到之后的回复。当然这个回复,会沿着刚才来的方向走回去,报个平安。
  • 如果过一段时间还是没到,发送端的 TCP 层会重新发送这个包,还是上面的过程,直到有一天收到平安到达的回复。这个重试绝非你的浏览器重新请求 github 个人主页。对于浏览器来讲,就发送了一次 github 个人主页请求,TCP 层不断自己闷头重试。除非 TCP 这一层出了问题,例如连接断了,才轮到浏览器的应用层重新发送 github 个人主页请求。
  • 当网络包平安到达 TCP 层之后,TCP 头中有目标端口号,通过这个端口号,可以找到 github 网站的进程正在监听这个端口号,假设一个 Tomcat,将这个包发给 github 网站。
  • github 网站的进程得到 HTTP 请求的内容,知道了要响应啥。往往一个电商网站最初接待请求的这个 Tomcat 只是个接待员,负责统筹处理这个请求,而不是所有的事情都自己做。例如,这个接待员要告诉专门管理 GitHub 个人主页的进程,要响应啥等等。
  • 如何告诉相关的进程呢?往往通过 RPC 调用,即远程过程调用的方式来实现。远程过程调用就是当告诉管理 GitHub 个人主页的进程的时候,接待员不用关心中间的网络互连问题,会由 RPC 框架统一处理。RPC 框架有很多种,有基于 HTTP 协议放在 HTTP 的报文里面的,有直接封装在 TCP 报文里面的。
  • 当接待员发现相应的部门都处理完毕,就回复一个 HTTPS 的包,告知查询成功。这个 HTTPS 的包,会像来的时候一样,经过千难万险到达你的个人电脑,最终进入浏览器,显示个人主页。

网络分层模型

TCP/IP 协议栈

  • TCP/IP 协议栈
  • link layer 链接层:负责在以太网、WiFi 这样的底层网络上发送原始数据包(frame 帧),工作在网卡这个层次,使用 MAC 地址来标记网络上的设备,所以有时候也叫 MAC 层。
  • internet layer 网际层:IP 协议就处在这一层。因为 IP 协议定义了“IP 地址”的概念,所以就可以在“链接层”的基础上,用 IP 地址取代 MAC 地址,把许许多多的局域网、广域网连接成一个虚拟的巨大网络,在这个网络里找设备时只要把 IP 地址再“翻译”成 MAC 地址就可以了。传输单位是包(packet)
  • transport layer 传输层:TCP/UDP 协议工作的层次
    • TCP 是一个有状态的协议,需要先与对方建立连接然后才能发送数据,而且保证数据不丢失不重复。而 UDP 则比较简单,它无状态,不用事先建立连接就可以任意发送数据,但不保证数据一定会发到对方。两个协议的另一个重要区别在于数据的形式。TCP 的数据是连续的“字节流”,有先后顺序,而 UDP 则是分散的小数据包,是顺序发,乱序收。
    • TCP 层的传输单位是段(segment)
  • application layer 应用层:各种面向具体应用的协议,例如 DHCP、HTTP、HTTPS、RTMP、DNS、P2P、GTP、RPC、Telnet、SSH、FTP、SMTP 等等。
    • HTTP 的传输单位则是消息或报文(message)

OSI (Open System Interconnection Reference Model) 开放式系统互联通信参考模型

  • OSI参考模型
  • physical layer 物理层:网络的物理形式,例如电缆、光纤、网卡、集线器等等
  • data link layer 数据链路层:基本相当于 TCP/IP 的链接层
  • network layer 网络层:相当于 TCP/IP 里的网际层
  • transport layer 传输层:相当于 TCP/IP 里的传输层
  • session layer 会话层:维护网络中的连接状态,即保持会话和同步
  • presentation layer 表示层:把数据转换为合适、可理解的语法和语义
  • application layer 应用层:面向具体的应用传输数据

两个分层模型的映射关系

  • 两个分层模型的映射关系
  • 第一层:物理层,TCP/IP 里无对应
  • 第二层:数据链路层,对应 TCP/IP 的链接层
  • 第三层:网络层,对应 TCP/IP 的网际层
  • 第四层:传输层,对应 TCP/IP 的传输层
  • 第五、六、七层:统一对应到 TCP/IP 的应用层
    • TCP/IP 实际应用时的会话管理、编码转换、压缩等和具体应用经常联系的很紧密,很难分开

HTTP - HyperText Transfer Protocol

  • HTTP概览图
  • Protocol
    • 协议必须要有两个或多个参与者,也就是“协”
    • 协议是对参与者的一种行为约定和规范,也就是“议”,包括语法、语义、同步规则和错误处理
    • 总结:HTTP 是一个用在计算机世界里的协议。它使用计算机能够理解的语言确立了一种计算机之间交流通信的规范,以及相关的各种控制和错误处理方式。
  • Transfer
    • HTTP 协议是一个“双向协议”
    • 数据虽然是在 A 和 B 之间传输,但并没有限制只有 A 和 B 这两个角色,允许中间有“中转”或者“接力”
      • 传输方式从“A<===>B” 可以变成了 “A<=>X<=>Y<=>Z<=>B”
      • A 到 B 的传输过程中可以存在任意多个“中间人”,而这些中间人也都遵从 HTTP 协议,只要不打扰基本的数据传输,就可以添加任意的额外功能,例如安全认证、数据压缩、编码转换等等,优化整个传输过程。
    • 总结:HTTP 是一个在计算机世界里专门用来在两点之间传输数据的约定和规范。
  • HyperText
    • Text
      • 表示 HTTP 传输的不是 TCP/UDP 这些底层协议里被切分的杂乱无章的二进制包(datagram),而是完整的、有意义的数据,可以被浏览器、服务器这样的上层应用程序处理。
    • 超文本:文字、图片、音频和视频等的混合体,最关键的是含有“超链接”,能够从一个“超文本”跳跃到另一个“超文本”,形成复杂的非线性、网状的结构关系。
  • 总结:HTTP 是一个在计算机世界里专门在两点之间传输文字、图片、音频、视频等超文本数据的约定和规范

HTTP不是?

  • 不存在“单独的实体”,但 HTTP 又与应用程序、操作系统、Web 服务器密切相关,在它们之间的通信过程中存在,而且是一种“动态的存在”,是发生在网络连接、传输超文本数据时的一个“动态过程”。
  • HTTP 不是互联网
    • 互联网(Internet)是遍布于全球的许多网络互相连接而形成的一个巨大的国际网络,在它上面存放着各式各样的资源,也对应着各式各样的协议,例如超文本资源使用 HTTP,普通文件使用 FTP,电子邮件使用 SMTP 和 POP3 等。
  • HTTP 不是编程语言
    • 编程语言是人与计算机沟通交流所使用的语言,而 HTTP 是计算机与计算机沟通交流的语言
    • 无法使用 HTTP 来编程,但可以反过来,用编程语言去实现 HTTP,告诉计算机如何用 HTTP 来与外界通信
  • HTTP 不是用于从互联网服务器传输超文本到本地浏览器的协议
    • 过于片面,HTTP 发生在两点之间,即服务端与客户端,客户端不是只包括本地浏览器,服务器也可以作为客户端,客户端也不仅仅只有浏览器,还可以有 App、小程序,浏览器只能作为客户端
  • HTTP 不是一个孤立的协议
    • HTTP 通常跑在 TCP/IP 协议栈之上,依靠 IP 协议实现寻址和路由、TCP 协议实现可靠数据传输、DNS 协议实现域名查找、SSL/TLS 协议实现安全通信
    • 还有一些协议依赖于 HTTP,例如 WebSocket、HTTPDNS 等
  • 总结:HTTP 是构建互联网的重要基础技术,它没有实体,依赖许多其他的技术来实现,但同时许多技术也都依赖于它。

Domain

Domain 形式

  • 域名是一个有层次的结构,是一串用“.”分隔的多个单词,最右边的被称为“顶级域名”,然后是“二级域名”,层级关系向左依次降低。
  • 本质上还是个名字空间系统

DNS Domain Name System

  • 就像 IP 地址必须转换成 MAC 地址才能访问主机一样,域名也必须要转换成 IP 地址,这个过程就是“域名解析”。
  • DNS 使用 TCP 和 UDP 端口53
  • DNS 的核心系统是一个三层的树状、分布式服务,基本对应域名的结构:
    • 根域名服务器(Root DNS Server):管理顶级域名服务器,返回“com”“net”“cn”等顶级域名服务器的 IP 地址
      • 全世界共有 13 组根域名服务器,又有数百台的镜像,保证一定能够被访问到
    • 级域名服务器(Top-level DNS Server):管理各自域名下的权威域名服务器,比如 com 顶级域名服务器可以返回 apple.com 域名服务器的 IP 地址
    • 权威域名服务器(Authoritative DNS Server):管理自己域名下主机的 IP 地址,比如 apple.com 权威域名服务器可以返回 www.apple.com 的 IP 地址
    • DNS 三层的树状
  • 所以我们访问 https://ele-peng.github.io/ 就需要进行下面的三次查询
    • 访问根域名服务器,它会告诉你 “io” 顶级域名服务器的地址
    • 访问 “io” 顶级域名服务器,它再告诉你 “github.io” 域名服务器的地址
    • 最后访问 “github.io” 域名服务器,就得到了 “ele-peng.github.io” 的地址
  • DNS 是一个树状的分布式查询系统,为了提高查询效率,外围有多级的缓存(非权威域名服务器、操作系统缓存和 hosts 文件等手段)用来减轻域名解析的压力,并且能够更快地获取结果,基本思路都是“缓存”
    • 许多大公司、网络运行商都会建立自己的 DNS 服务器,作为用户 DNS 查询的代理,代替用户访问核心 DNS 系统。这些“野生”服务器被称为“非权威域名服务器”,可以缓存之前的查询结果,如果已经有了记录,就无需再向根服务器发起查询,直接返回对应的 IP 地址
      • 这些 DNS 服务器的数量要比核心系统的服务器多很多,而且大多部署在离用户很近的地方。比较知名的 DNS 有 Google 的“8.8.8.8”,Microsoft 的“4.2.2.1”,还有 CloudFlare 的“1.1.1.1”等等。
    • 其次,操作系统里也会对 DNS 解析结果做缓存,如果你之前访问过“ele-peng.github.io”,那么下一次在浏览器里再输入这个网址的时候就不会再跑到 DNS 那里去问了,直接在操作系统里就可以拿到 IP 地址
    • 另外,操作系统里还有一个特殊的“主机映射”文件
  • 假如访问 www.不存在.com
    • www.不存在.com -> Hosts 文件 -> 操作系统本地缓存 -> 非权威域名服务器查询其缓存 -> 查询根域名、顶级域名、以及域名服务器,当后面的查询得到结果时,将会写入本地缓存
  • 现在的 DNS 架构
    • 现在的 DNS 架构
  • 使用 DNS 可以实现基于域名的负载均衡,既可以在内网,也可以在外网

写在后面

  • 学而不思则罔 互勉
  • 祝大家多多发财