04 | HTTP世界全览(下):与HTTP相关的各种协议

在上一讲中,我介绍了与HTTP相关的浏览器、服务器、CDN、网络爬虫等应用技术。

今天要讲的则是比较偏向于理论的各种HTTP相关协议,重点是TCP/IP、DNS、URI、HTTPS等,希望能够帮你理清楚它们与HTTP的关系。

同样的,我还是画了一张详细的思维导图,你可以点击后仔细查看。

TCP/IP

TCP/IP协议是目前网络世界“事实上”的标准通信协议,即使你没有用过也一定听说过,因为它太著名了。

TCP/IP协议实际上是一系列网络通信协议的统称,其中最核心的两个协议是TCPIP,其他的还有UDP、ICMP、ARP等等,共同构成了一个复杂但有层次的协议栈。

这个协议栈有四层,最上层是“应用层”,最下层是“链接层”,TCP和IP则在中间:TCP属于“传输层”,IP属于“网际层”。协议的层级关系模型非常重要,我会在下一讲中再专门讲解,这里先暂时放一放。

IP协议是“Internet Protocol”的缩写,主要目的是解决寻址和路由问题,以及如何在两点间传送数据包。IP协议使用“IP地址”的概念来定位互联网上的每一台计算机。可以对比一下现实中的电话系统,你拿着的手机相当于互联网上的计算机,而要打电话就必须接入电话网,由通信公司给你分配一个号码,这个号码就相当于IP地址。

现在我们使用的IP协议大多数是v4版,地址是四个用“.”分隔的数字,例如“192.168.0.1”,总共有2^32,大约42亿个可以分配的地址。看上去好像很多,但互联网的快速发展让地址的分配管理很快就“捉襟见肘”。所以,就又出现了v6版,使用8组“:”分隔的数字作为地址,容量扩大了很多,有2^128个,在未来的几十年里应该是足够用了。

TCP协议是“Transmission Control Protocol”的缩写,意思是“传输控制协议”,它位于IP协议之上,基于IP协议提供可靠的、字节流形式的通信,是HTTP协议得以实现的基础。

“可靠”是指保证数据不丢失,“字节流”是指保证数据完整,所以在TCP协议的两端可以如同操作文件一样访问传输的数据,就像是读写在一个密闭的管道里“流动”的字节。

第2讲时我曾经说过,HTTP是一个"传输协议",但它不关心寻址、路由、数据完整性等传输细节,而要求这些工作都由下层来处理。因为互联网上最流行的是TCP/IP协议,而它刚好满足HTTP的要求,所以互联网上的HTTP协议就运行在了TCP/IP上,HTTP也就可以更准确地称为“HTTP over TCP/IP”。

DNS

在TCP/IP协议中使用IP地址来标识计算机,数字形式的地址对于计算机来说是方便了,但对于人类来说却既难以记忆又难以输入。

于是“域名系统”(Domain Name System)出现了,用有意义的名字来作为IP地址的等价替代。设想一下,你是愿意记“95.211.80.227”这样枯燥的数字,还是“nginx.org”这样的词组呢?

在DNS中,“域名”(Domain Name)又称为“主机名”(Host),为了更好地标记不同国家或组织的主机,让名字更好记,所以被设计成了一个有层次的结构。

域名用“.”分隔成多个单词,级别从左到右逐级升高,最右边的被称为“顶级域名”。对于顶级域名,可能你随口就能说出几个,例如表示商业公司的“com”、表示教育机构的“edu”,表示国家的“cn”“uk”等,买火车票时的域名还记得吗?是“www.12306.cn”。

unpreview

但想要使用TCP/IP协议来通信仍然要使用IP地址,所以需要把域名做一个转换,“映射”到它的真实IP,这就是所谓的“域名解析”。

继续用刚才的打电话做个比喻,你想要打电话给小明,但不知道电话号码,就得在手机里的号码簿里一项一项地找,直到找到小明那一条记录,然后才能查到号码。这里的“小明”就相当于域名,而“电话号码”就相当于IP地址,这个查找的过程就是域名解析。

域名解析的实际操作要比刚才的例子复杂很多,因为互联网上的电脑实在是太多了。目前全世界有13组根DNS服务器,下面再有许多的顶级DNS、权威DNS和更小的本地DNS,逐层递归地实现域名查询。

HTTP协议中并没有明确要求必须使用DNS,但实际上为了方便访问互联网上的Web服务器,通常都会使用DNS来定位或标记主机名,间接地把DNS与HTTP绑在了一起。

URI/URL

有了TCP/IP和DNS,是不是我们就可以任意访问网络上的资源了呢?

还不行,DNS和IP地址只是标记了互联网上的主机,但主机上有那么多文本、图片、页面,到底要找哪一个呢?就像小明管理了一大堆文档,你怎么告诉他是哪个呢?

所以就出现了URI(Uniform Resource Identifier),中文名称是 统一资源标识符,使用它就能够唯一地标记互联网上资源。

URI另一个更常用的表现形式是URL(Uniform Resource Locator), 统一资源定位符,也就是我们俗称的“网址”,它实际上是URI的一个子集,不过因为这两者几乎是相同的,差异不大,所以通常不会做严格的区分。

我就拿Nginx网站来举例,看一下URI是什么样子的。

http://nginx.org/en/download.html

你可以看到,URI主要有三个基本的部分构成:

  1. 协议名:即访问该资源应当使用的协议,在这里是“http”;
  2. 主机名:即互联网上主机的标记,可以是域名或IP地址,在这里是“nginx.org”;
  3. 路径:即资源在主机上的位置,使用“/”分隔多级目录,在这里是“/en/download.html”。

还是用打电话来做比喻,你通过电话簿找到了小明,让他把昨天做好的宣传文案快递过来。那么这个过程中你就完成了一次URI资源访问,“小明”就是“主机名”,“昨天做好的宣传文案”就是“路径”,而“快递”,就是你要访问这个资源的“协议名”。

HTTPS

在TCP/IP、DNS和URI的“加持”之下,HTTP协议终于可以自由地穿梭在互联网世界里,顺利地访问任意的网页了,真的是“好生快活”。

但且慢,互联网上不仅有“美女”,还有很多的“野兽”。

假设你打电话找小明要一份广告创意,很不幸,电话被商业间谍给窃听了,他立刻动用种种手段偷窃了你的快递,就在你还在等包裹的时候,他抢先发布了这份广告,给你的公司造成了无形或有形的损失。

有没有什么办法能够防止这种情况的发生呢?确实有。你可以使用“加密”的方法,比如这样打电话:

你:“喂,小明啊,接下来我们改用火星文通话吧。”
小明:“好啊好啊,就用火星文吧。”
你:“巴拉巴拉巴拉巴拉……”
小明:“巴拉巴拉巴拉巴拉……”

如果你和小明说的火星文只有你们两个才懂,那么即使窃听到了这段谈话,他也不会知道你们到底在说什么,也就无从破坏你们的通话过程。

HTTPS就相当于这个比喻中的“火星文”,它的全称是“HTTP over SSL/TLS”,也就是运行在SSL/TLS协议上的HTTP。

注意它的名字,这里是SSL/TLS,而不是TCP/IP,它是一个负责加密通信的安全协议,建立在TCP/IP之上,所以也是个可靠的传输协议,可以被用作HTTP的下层。

因为HTTPS相当于“HTTP+SSL/TLS+TCP/IP”,其中的“HTTP”和“TCP/IP”我们都已经明白了,只要再了解一下SSL/TLS,HTTPS也就能够轻松掌握。

SSL的全称是“Secure Socket Layer”,由网景公司发明,当发展到3.0时被标准化,改名为TLS,即“Transport Layer Security”,但由于历史的原因还是有很多人称之为SSL/TLS,或者直接简称为SSL。

SSL使用了许多密码学最先进的研究成果,综合了对称加密、非对称加密、摘要算法、数字签名、数字证书等技术,能够在不安全的环境中为通信的双方创建出一个秘密的、安全的传输通道,为HTTP套上一副坚固的盔甲。

你可以在今后上网时留心看一下浏览器地址栏,如果有一个小锁头标志,那就表明网站启用了安全的HTTPS协议,而URI里的协议名,也从“http”变成了“https”。

代理

代理(Proxy)是HTTP协议中请求方和应答方中间的一个环节,作为“中转站”,既可以转发客户端的请求,也可以转发服务器的应答。

代理有很多的种类,常见的有:

  1. 匿名代理:完全“隐匿”了被代理的机器,外界看到的只是代理服务器;
  2. 透明代理:顾名思义,它在传输过程中是“透明开放”的,外界既知道代理,也知道客户端;
  3. 正向代理:靠近客户端,代表客户端向服务器发送请求;
  4. 反向代理:靠近服务器端,代表服务器响应客户端的请求;

上一讲提到的CDN,实际上就是一种代理,它代替源站服务器响应客户端的请求,通常扮演着透明代理和反向代理的角色。

由于代理在传输过程中插入了一个“中间层”,所以可以在这个环节做很多有意思的事情,比如:

  1. 负载均衡:把访问请求均匀分散到多台机器,实现访问集群化;
  2. 内容缓存:暂存上下行的数据,减轻后端的压力;
  3. 安全防护:隐匿IP,使用WAF等工具抵御网络攻击,保护被代理的机器;
  4. 数据处理:提供压缩、加密等额外的功能。

关于HTTP的代理还有一个特殊的“代理协议”(proxy protocol),它由知名的代理软件HAProxy制订,但并不是RFC标准,我也会在之后的课程里专门讲解。

小结

这次我介绍了与HTTP相关的各种协议,在这里简单小结一下今天的内容。

  1. TCP/IP是网络世界最常用的协议,HTTP通常运行在TCP/IP提供的可靠传输基础上;
  2. DNS域名是IP地址的等价替代,需要用域名解析实现到IP地址的映射;
  3. URI是用来标记互联网上资源的一个名字,由“协议名+主机名+路径”构成,俗称URL;
  4. HTTPS相当于“HTTP+SSL/TLS+TCP/IP”,为HTTP套了一个安全的外壳;
  5. 代理是HTTP传输过程中的“中转站”,可以实现缓存加速、负载均衡等功能。

经过这两讲的学习,相信你应该对HTTP有了一个比较全面的了解,虽然还不是很深入,但已经为后续的学习扫清了障碍。

课下作业

  1. DNS与URI有什么关系?
  2. 在讲代理时我特意没有举例说明,你能够用引入一个“小强”的角色,通过打电话来比喻一下吗?

欢迎你通过留言分享答案,与我和其他同学一起讨论。如果你觉得有所收获,欢迎你把文章分享给你的朋友。

unpreview

精选留言

  • 壹笙☞漂泊

    2019-06-05 10:00:31

    课后题:
    1、URI DNS
    DNS 是将域名解析出真实IP地址的系统
    URI 是统一资源标识符,标定了客户端需要访问的资源所处的位置,如果URI中的主机名使用域名,则需要使用DNS来讲域名解析为IP。
    2、打电话给小明,请小明找小王拿一下客户资料。小明处于代理角色。
    内容笔记
    1、四层模型:应用层、传输层、网际层、链接层
    2、IP协议主要解决寻址和路由问题
    3、ipv4,地址是四个用“.”分隔的数字,总数有2^32个,大约42亿个可以分配的地址
    4、ipv6,地址是八个用“:”分隔的数字,总数有2^128个。
    5、TCP协议位于IP协议之上,基于IP协议提供可靠的(数据不丢失)、字节流(数据完整)形式的通信,是HTTP协议得以实现的基础
    6、域名系统:为了更好的标记不同国家或组织的主机,域名被设计成了一个有层次的结构
    7、域名用“.”分隔成多个单词,级别从左到右逐级升高。
    8、域名解析:将域名做一个转换,映射到它的真实IP
    9、URI:统一资源标识符;URL:统一资源定位符
    10、URI主要有三个基本部分构成:协议名、主机名、路径
    11、HTTPS:运行在SSL/TLS协议上的HTTP
    12 、SSL/TLS:建立在TCP/IP之上的负责加密通信的安全协议,是可靠的传输协议,可以被用作HTTP的下层
    13、代理(Proxy):是HTTP协议中请求方和应答方中间的一个环节。既可以转发客户端的请求,也可以转发服务器的应答。
    14、代理常见种类:匿名台历、透明代理、正向代理、反向代理
    15、代理可以做的事:负载均衡、内容缓存、安全防护、数据处理。
    作者回复

    总结的非常详细,也很准确,鼓掌!

    2019-06-05 14:16:41

  • 2020-03-24 07:34:45

    1:DNS 与 URI 有什么关系?
    DNS专门用于域名解析,作用是简化人类记忆数据的复杂度。
    URI专门用于标识互联网世界中的资源,作用是帮助找到对应的互联网中资源。
    互联网中的电脑通过IP地址来表示,DNS可以把一个域名变成一个IP地址,IP地址是标识资源的一部分,仅定位了具体的电脑,还有继续定位在电脑上的具体位置。

    2:在讲代理时我特意没有举例说明,你能够用引入一个“小强”的角色,通过打电话来比喻一下吗?
    小强给小明打电话要小红的照片——小明是正向代理
    小强要小红的照片小明负责处理——小明是反向代理

    网络通信是分布式系统的底座,也是信息交互的法宝
    TCP——负责数据传输
    IP——负责标识传输对象
    DNS——负责简化人类的记忆
    URI/L——负责标识传输的资源
    SSL——负责数据传输的安全
    Proxy——负责信息的中转
    像极了走标,
    需要搞清楚从哪到哪——IP
    需要搞定怎么传输——TCP
    需要保障货物的安全——SSL
    需要送货的具体位置——URI
    需要把目的地的经纬度换成地址名——DNS
    需要中间中转一下——Proxy
    HTTP——我不那么多,我向你要什么你就给什么
    作者回复

    amazing!!

    2020-03-24 08:54:46

  • Atomic

    2019-06-06 07:47:51

    打个比方:我让老婆帮我去楼下超市买瓶水,DNS可以帮她找到楼下超市,URI可以帮她找到水放在超市的具体位置
    作者回复

    比喻的好生动,笑。

    2019-06-06 09:18:26

  • Shine Sunner

    2020-01-01 11:32:23

    1.假如去某个小区找人,DNS可以帮我定位到是哪栋大楼,URI可以帮我定位到是哪个房间。
    2.
    正向代理:
    假如我【客户端】想找小强【服务端】借钱,但是我不好意思。我去找小李【代理】,然后让小李找小强借。对于小强来说他以为是小李找他借钱,而不是我。

    反向代理:
    同样是借钱,这回我【客户端】找小李【代理】借钱,小李没钱了,他去找小强【服务端】借钱,然后再把钱借给我,对我来说我认为是小李借钱给我,而不是小强。

    总结:
    正向代理的代理服务器是部署在客户端,而对服务端来说,它以为对它发起请求的是代理服务器,而真正请求的客户端对服务端来说是不可见的。
    反向代理的代理服务器是部署在服务端,而对客户端来说,它以为对它做出响应的是代理服务器,而真正响应的服务端对客户端来说是不可见的。
    作者回复

    说的非常好,给你点32个赞(笑)。

    2020-01-02 09:31:55

  • 一粟

    2019-06-05 06:57:58

    小强家钥匙丢了,需要找一家开锁公司开门。于是小强打电话给114,114给小强提供一家有资质的开锁公司,并将电话转接过去。这里的114就是代理。
    作者回复

    2019-06-05 09:37:01

  • 蚂蚁内推+v

    2019-06-06 09:05:30

    1. URL 包含了协议+主机名+路径,DNS 会将其中的主机名解析为 IP,进而方便根据 IP 协议进行寻址、路由;
    2. 我们为了更安全的和小明交流,选择通过和小强交流,让其再告诉小明,这是匿名代理,也是正向代理,而如果让小明知道我们的存在则不是匿名代理,是透明代理;小明由于某些原因不能直接响应我们,找了小强来代为响应我们,这是反向代理;
    3. 另外回答一下楼下同学关于 URI 和 URL 区别的疑惑,URI 是 Identifier,即标识符,URL 是 Location,即定位,所以定位只是标识符的一种,打个比方,我们找到小明可以通过其家庭地址(Location)也可以通过名字(比如上课点名)来找到他,所以后者也可以成为 URN。因此 URL 和 URN 都是 URI 的子集。
    作者回复

    说的很好,不过现在urn用的很少,现在的uri基本上就是url,除非写论文,否则不用特意区分。

    2019-06-06 09:26:34

  • 不知道该叫什么

    2019-10-28 10:24:28

    但是我还是没明白URI跟RUL的区别
    作者回复

    url是uri的子集,url只表示网址,而uri除了表示网址,还能够标记其他的任意东西。

    但在互联网上,这两者是基本等价的,也不需要去钻字眼刻意区分。

    2019-10-28 11:20:50

  • 小葱🤓

    2019-06-12 18:00:31

    别的不想说,请问能调高课程的费用吗???
  • 2019-06-05 09:41:15

    Http协议不是依赖tcp/ip的拆包和封包吗?Unix domain socket可以做到吗?
    作者回复

    当然可以,如果在Linux上跑Nginx,就可以指定用Unix domain socket。

    关键要理解协议栈,http不强制要求下层必须是tcp。

    2019-06-05 11:03:52

  • 我爱夜来香

    2021-05-02 16:54:56

    老师,我有个问题,就是URL由三部分组成,前面的协议名和主机名能理解,后面的路径指的是应用在服务器上的真实路径吗?或者说是由真实路径经过一层封装而形成的?
    作者回复

    注意,uri表示的是网络上的资源,这实际上是一种抽象,意思是在主机上的某个位置有一个资源。

    但这个资源路径不一定会与主机磁盘上的路径完全匹配,可以相同也可以不相同,通常来说会有一个简单的转换,比如映射到不同的目录。

    而且,图片、html等静态资源是可以对应到文件系统的,而动态资源,它根本就没有实体,所以uri就完全是一个标识符的作用,不存在路径。

    2021-05-02 19:27:49

  • 2019-06-05 09:04:07

    看到老师后面小帖士说的,在unix系统上http可以依赖一种进程间传输的机制Unix domain socket进行传输,这是因为满足了底层的可靠的传输。这句话意思是说,http不一定在tcp/ip之上进行传输?只要底层满足可靠传输的都可以?

    作者回复

    当然了,这就是http灵活性的体现。

    2019-06-05 09:31:42

  • Jerryz

    2021-01-12 08:56:01

    1. DNS 可以定位到一台主机,URI 则可以定位到主机上的资源。
    2. 正向代理:我通过查找小强的电话薄,转话到小明。反向代理:我通过查找小明的电话薄,但是和我通话的实际是小强。
    作者回复

    very nice!

    2021-01-12 09:08:22

  • Tio Kang

    2019-09-02 20:16:56

    老师,我有一个疑问,一个代理即可以是反向代理也可以正向代理吗?
    作者回复

    理论上应该是可以的,但实际上应该没有这么用。

    因为正向代理连接的是上网的客户端,反向代理连接的是网站的服务器,代理的对象是不同的,合不到一起。

    2019-09-03 08:59:08

  • dingdongfm

    2019-06-19 07:59:48

    不做本地证书校验时,https可以被抓包工具抓到明文包,原因是什么?https不能防止中间人攻击么
    作者回复

    开头的握手数据是明文的,但后面都是加密的,与证书验证无关。

    https中间人攻击必须要客户端信任根证书,像fiddler就是这么做的。

    2019-06-19 09:31:26

  • 愚人

    2019-06-12 22:37:30

    域名可以对应多个IP,IP也可以通过端口映射对应多个域名。能讲一讲这方面实例么?
    作者回复

    这个好像不需要什么实例,这种做法很普遍,比如以前的z.cn和www.amzon.cn都指向一个站点。

    另外,ip对应多个域名,不用端口映射。

    2019-06-13 08:57:09

  •        鸟人

    2019-06-11 09:32:21

    a要向b发送消息,实际是先发到代理,由代理发给b。反向由b返回给代理,代理返回给a。
    那么我向cdn发送评论 此时为正向,然后刷新页面 看到自己写的评论 此时为反向
    可以这样理解么?
    作者回复

    好像不太正确,每一次的http消息都是一个往返,请求先到服务器,然后服务器发回响应。

    正向代理是指“正”着代理客户端,反向代理是指“逆”着请求的方向代理服务器。

    2019-06-11 09:48:30

  • 发条橙子 。

    2019-06-09 10:51:34

    老师,我这里有个疑问 。 一个请求由DNS解析到指定的IP ,然后通过URI确定要访问哪些资源。最后通过 TCP/IP 进行路由寻址以及数据的传输。
    但是一台机子上有多个应用 , 可能两个相同的应用运行在同一个主机上 ,有着两个不同的进程。 那么根据URI是指定从哪个进程里获取数据呢 。
    这时候是不是根据端口号来判定 , 但是URI上并没有显式的让我们看出是哪个端口号 ??
    作者回复

    uri会有默认端口号,比如http默认是80,用tcp连接必须要同时指定ip地址和端口。

    服务器进程在指定端口上监听,然后tcp就可以建立连接。

    2019-06-09 16:09:14

  • 小伙儿爱裸睡

    2019-06-07 21:58:20

    老师,TCP协议作用中的数据不丢失和数据完整有什么区别呢?可能我刚入门,有点抠字眼,还望老师不吝赐教哈。
    作者回复

    简单来说,丢失就不完整了。可以对比一下udp,udp不保证数据完整,会丢包,使用udp的应用需要自己处理丢包,保证数据完整,而使用tcp的应用就不需要考虑这些。

    2019-06-08 06:15:08

  • herseus

    2019-06-07 10:37:40

    负载均衡应该算作反向代理,因为是为服务器端服务的。另外,字节流应该是数据传输格式,不是
    作者回复

    字节流是一种抽象,是对比udp的包来说的,只有完整可靠的传输才能看成是字节流。

    2019-06-07 16:06:07

  • 尔东橙

    2019-06-07 10:33:49

    老师会后面会展开来讲么,比如域名解析过程,CDN调度过程等。现在面试官都问的太深了,如果只了解表面的概念很难以应对。希望老师能挖深一点
    作者回复

    由于时间、篇幅的限制,讲不了特别深,我尽量吧。

    2019-06-07 16:04:42