QUIC与HTTP/3实战:现代网络协议解析与性能优化

978-7-115-68738-8
作者: 李龙彦
译者:
编辑: 贾静
分类: 其他

图书目录:

详情

HTTP/3的核心是QUIC协议,本书围绕QUIC协议和HTTP/3的原理、应用与代码实现展开,旨在帮助读者理解HTTP/3的价值与落地方法。 本书共4部分。第一部分是网络协议基础知识,共2章,主要介绍TCP/IP和HTTP的基础知识。第二部分是QUIC协议,共7章,主要包括QUIC协议概述,QUIC协议的流,QUIC连接建立、连接迁移、传输机制、帧类型与格式和错误处理。第三部分是HTTP/3,共4章,主要介绍HTTP/3的特性、应用、实践和发展以及优化。第四部分是QUIC协议的实现,共2章,分别介绍QUIC客户端和服务端的代码实现。 本书既适合QUIC协议与HTTP/3的开发者与维护者、互联网业务软件开发/测试工程师、运维工程师阅读,也适合计算机相关专业的学生阅读。

图书摘要

版权信息

书名:QUIC与HTTP/3实战 : 现代网络协议解析与性能优化

ISBN:978-7-115-68738-8

本书由人民邮电出版社发行数字版。版权所有,侵权必究。

您购买的人民邮电出版社电子书仅供您个人使用,未经授权,不得以任何方式复制和传播本书内容。

我们愿意相信读者具有这样的良知和觉悟,与我们共同保护知识产权。

如果购买者有侵权行为,我们可能对该用户实施包括但不限于关闭该帐号等维权措施,并可能追究法律责任。

版  权

著    李龙彦

责任编辑 贾 静

人民邮电出版社出版发行  北京市丰台区成寿寺路11号

邮编 100164  电子邮件 315@ptpress.com.cn

网址 http://www.ptpress.com.cn

读者服务热线:(010)81055410

反盗版热线:(010)81055315

内 容 提 要

HTTP/3的核心是QUIC协议,本书围绕QUIC协议和HTTP/3的原理、应用与代码实现展开,旨在帮助读者理解HTTP/3的价值与落地方法。

本书共4部分。第一部分是网络协议基础知识,共2章,主要介绍TCP/IP和HTTP的基础知识。第二部分是QUIC协议,共7章,主要包括QUIC协议概述,QUIC协议的流,QUIC连接建立、连接迁移、传输机制、帧类型与格式和错误处理。第三部分是HTTP/3,共4章,主要介绍HTTP/3的特性、应用、实践和发展以及优化。第四部分是QUIC协议的实现,共2章,分别介绍QUIC客户端和服务端的代码实现。

本书既适合QUIC协议与HTTP/3的开发者与维护者、互联网业务软件开发/测试工程师、运维工程师阅读,也适合计算机相关专业的学生阅读。

前  言

在网络技术飞速迭代的今天,HTTP作为互联网的基石,从HTTP/1.1的文本传输到HTTP/2的多路复用,每一次升级都深刻影响着应用的传输效率与用户体验。而HTTP/3的横空出世,更是凭借底层传输协议的革新,为解决弱网环境高延迟、高丢包场景下的传输痛点提供了全新方案,逐渐成为高性能网络应用的首选协议。

作为一名深耕网络领域近15年的从业者,我亲历了HTTP协议的演进历程。在早年的工作中,我长期基于HTTP/1.1和HTTP/2开展网络开发,深知传统协议在复杂网络环境中的局限——弱网下的高延迟、多请求场景的阻塞问题,始终是影响业务体验与收益的关键瓶颈。2019年,我在华为技术有限公司中央软件院首次接触到QUIC协议,这个基于UDP的可靠传输技术,让我看到了突破传输瓶颈的可能。

2020年初,我加入OPPO担任网络优化项目负责人兼架构师,核心任务之一便是推动QUIC协议的业务落地。HTTP/3与QUIC协议有着密不可分的关系:HTTP/3并非孤立的协议升级,而是将HTTP语义与QUIC传输能力深度结合的产物——它保留并优化了HTTP/2的核心设计,同时将多路复用等关键特性迁移至QUIC协议层,通过QUIC协议的零往返时间(0-RTT)连接、流隔离、连接迁移等优势,从根本上解决了HTTP/2基于TCP传输的固有缺陷。协议落地的过程远比想象中曲折:QUIC 协议的端到端特性,要求客户端应用与云端四层、七层负载均衡器等组件全面适配,而当时关于QUIC协议与HTTP/3的公开资料极度匮乏,唯一的参考是晦涩的RFC文档。

每一次遇到技术卡点,每一次需要从零推导解决方案,我都深切感受到开发者的困境:想要引入HTTP/3优化业务,却苦于没有清晰的原理讲解和实践指南;面对RFC文档中的复杂表述和源代码中的零散逻辑,多数开发者只能望而却步。随着HTTP/3的普及,越来越多的团队开始面临决策难题:当前业务的传输痛点是否能通过HTTP/3解决?升级过程需要承担哪些成本与风险?如何平稳完成协议迁移与落地?这些问题,仅靠碎片化的资料难以找到答案。

正是这种亲身经历的困境与行业的需求,让我萌生了写作本书的想法。我希望以一线实践经验为桥梁,打通理论与实操的壁垒:既清晰梳理QUIC协议的底层原理,阐明它与HTTP/3的内在关联,让读者理解“为何HTTP/3能带来性能飞跃”;也系统拆解HTTP/3的核心特性,对比其与HTTP/1.1、HTTP/2的关键差异;更重要的是,通过真实业务落地案例,提供从协议选型、环境适配到代码实现、迭代优化的完整路径。

本书力求用通俗的语言拆解复杂协议,避免堆砌专业术语,无论是寻求技术升级的软件开发/测试工程师,还是专注网络优化的从业者,都能快速理解QUIC协议与HTTP/3的核心价值。如果本书能为你在协议选型时提供参考,在落地实践中规避坑点,助力业务实现传输效率的提升,便是我最大的心愿。

本书组织架构

本书围绕“原理→应用→代码实现”的逻辑展开,共分为4部分,帮助读者系统掌握QUIC协议与HTTP/3的核心知识。

第一部分(第1~2章):网络协议基础知识。

本部分为QUIC协议与HTTP/3的学习打基础,若你已具备Web应用网络协议的全面认知,可直接跳转至第二部分阅读。

第1章:讲解TCP/IP基础知识(QUIC协议基于UDP实现,但借鉴了TCP的诸多机制),涵盖网络协议概念、TCP/IP协议栈及网站加载流程。

第2章:梳理HTTP基础知识,包括HTTP/1.1、HTTP/2、HTTP/3这三大版本的核心特性(缓存、重定向、cookie),以及HTTP优化的常用手段。

第二部分(第3~9章):QUIC协议。

本部分共7章,建议按章节顺序阅读,全面覆盖QUIC协议的核心内容与实践方案。

第3章:是QUIC协议概述,分析HTTPS的缺点、QUIC协议的解决方案,以及QUIC协议与HTTP/3的关联,帮助读者理解技术背景。

第4~7章:详解QUIC协议的流、连接建立、连接迁移与传输机制这四大核心特性,同时总结协议应用中的常见问题与解决方案。此部分会涉及多个QUIC帧类型,读者无须记忆,按需查阅即可。

第8~9章:分别对QUIC帧类型、QUIC协议与HTTP/3错误码进行系统总结,方便读者快速检索。

第三部分(第10~13章):HTTP/3。

本部分共4章,建议按章节顺序阅读,聚焦HTTP/3的特性、应用与优化,尤其适合计划将HTTP/3落地业务的读者。

第10章:讲解HTTP/3的核心特性,包括连接管理、消息与帧类型。

第11~13章:分别介绍HTTP/3的应用、实践和发展,以及性能优化策略,帮助读者判断业务升级的必要性、成本与收益。

第四部分(第14~15章):QUIC协议的实现。

本部分通过源代码解析QUIC客户端与服务端实现,配套详细注释与图表,降低源码阅读难度。若你需深入理解协议实现,或负责相关开发、维护工作,本部分为必读内容。

第14章:介绍QUIC客户端的代码实现。以Google开源库Cronet为例,讲解连接建立、连接迁移、流量控制及PING帧的客户端实现逻辑。

第15章:介绍QUIC服务端的代码实现。以Nginx 1.25.0为例,介绍连接建立、连接迁移及拥塞控制算法的服务端实现方式。

核心术语说明

为统一阅读认知,本书对高频术语作如下说明:

(1)“理解”与“了解”。

“理解”:代表此部分内容是核心原理、关键机制或实战重点,是后续学习、应用的基础。读者需深入掌握其逻辑架构、运行流程、关联关系,能独立分析场景、解决问题(如推导机制差异、实现核心功能),需做到“吃透原理、会用会辨”。

“了解”:代表此部分内容是辅助认知、场景补充或非核心细节,无须深入钻研原理。读者只需知晓其基本概念、核心作用、与其他知识的关联(如知道功能场景、常见类型),后续实际应用时可按需查阅,做到“知其大意、用时有方向”即可。

(2)“服务端”与“服务器”。

服务端:指协议中被动响应连接的角色。

服务器:指承担“服务端”角色的物理或虚拟机器。

读者对象

本书适合但不限于以下人群阅读。

QUIC协议或HTTP/3的开发者与维护者:可掌握协议开发、优化及工程部署方法。

互联网业务软件开发/测试工程师:可了解协议特性、应用与实现,同时补充“网络协议基础知识”(此为相关岗位面试高频考点)。

运维工程师:可学习QUIC协议与HTTP/3的部署流程。

计算机相关专业的学生:可辅助理解计算机网络课程的核心知识。

配套资源

如需获取本书配套的插图、完整的代码和视频课程,请访问“异步社区”本书对应的网页。

勘误和支持

本书筹备过程中,我复盘了在做项目时遇到的问题,研读了QUIC协议相关的RFC文档,并分析了Cronet库(Google QUIC实现)、Nginx-QUIC库(Nginx官方QUIC实现)、Quiche库(Cloudflare QUIC实现)等的源代码,但仍难免存在疏漏。若你对本书有任何建议、疑问或想法,欢迎通过邮箱联系我:quichttp3@163.com。

致谢

首先感谢微信公众号“跟我一起学网络”的关注者们。几年前当我提笔在微信公众号写下第一篇文章后,仅有数十位关注者,后因时间与精力有限一度停更。停更一年后的一个午后,我偶然登录后台,发现仍有人阅读旧文、私信探讨知识点——虽人数寥寥,却让我深受触动,也让我决心继续分享知识与经验。此后,我开启“跟我一起学QUIC”专题写作,公众号关注者也随之呈几倍、十几倍的增长。尽管文章质量仍有提升空间,但正是大家的认可与鼓励,支撑我走到现在。

其次要感谢人民邮电出版社的编辑们。在我写作过程中,他们给予了非常专业的指导,在他们的帮助和鼓励下,本书才得以完成。

最后感谢我的家人。在持续一年多的时间里,由于工作繁忙,我的业余时间几乎全用于书稿筹备。家人的适时鼓励,总能缓解我孤灯下的疲劳与困倦,这份支持,我始终铭记。

第一部分 网络协议基础知识

HTTP/3是在HTTP/2和HTTP/1.1的基础上发展而来的,学习HTTP/3之前需要熟悉网络协议的基础知识,尤其是TCP、UDP、TLS协议、QUIC协议等与HTTP/3密切相关的网络协议。

因此,第一部分将介绍网络协议的基础知识,相关的知识点主要包括TCP/IP分层、HTTP的主要版本,以及HTTP的重要通用特性。

这些知识点不仅是理解HTTP/3的基础,也是众多互联网公司的面试考点。通过本部分的学习,读者将对网络协议栈有初步认识,对Web应用中常用的网络协议有基本了解,并对HTTP的特性和版本发展过程有一定的了解。

本部分的知识地图如下。

第1章 TCP/IP基础知识

协议栈(protocol stack)是指一组按照特定顺序排列在一起的网络通信协议的集合。TCP/IP(transmission control protocol/internet protocol,传输控制协议/互联网协议)是一个以TCP和IP为核心,还包含ARP、ICMP、UDP、HTTP等协议的网络协议栈。

本章要点

介绍网络协议的概念

使用自顶向下方法介绍TCP/IP

以网站的加载过程为例,讲解每层协议的作用和交互过程

1.1 网络协议简介

如同房屋的买卖双方需要签署同一套合同一样,在复杂的网络通信中,所有的数据在经过任何网络设备时也都必须遵从同一套网络通信的规则,这种规则就叫作网络协议。如若不然,A发过来的数据B无法正确解析,A和B就无法通信。可见,网络协议在数据传输中的作用至关重要。

网络协议必须具备以下特性。

统一性:网络协议提供了一套统一的方式和规范来实现数据的传输和交换。

权威性:网络协议通常是由国际标准化组织(ISO)或制定协议的组织发布的,全世界所有的设备和软件都必须按照这个协议来实现,否则将无法互相通信。

透明性:网络协议对用户透明,即用户在使用网络时感知不到协议的实现和细节。

公平性:网络协议必须做到公平,确保在同一个网络中传输数据的所有用户都能公平地使用网络资源,避免出现网络资源分配不均衡的问题。

多种适配不同规范的网络协议组合在一起,就形成了网络协议栈。网络通信的场景复杂,需要多种协议来约束网络设备间的通信行为,在Web应用中最常用的就是TCP/IP。

1.2 TCP/IP简介

为了让网络协议标准化,ISO定义了一种计算机网络协议体系——开放系统互连(OSI)。在OSI的众多软件实现中,TCP/IP是由IETF建议的一个软件体系架构。

OSI参考模型将网络通信分为7层,包括应用层、表示层、会话层、传输层、网络层、数据链路层和物理层,每层都有自己的功能和协议;在TCP/IP的实现中,OSI参考模型的应用层、表示层和会话层被合并为应用层,OSI参考模型的数据链路层和物理层被合并为网络接口层,OSI参考模型的传输层和网络层仍是单独的两层,如此便形成了TCP/IP四层协议栈,如图1-1所示。

图1-1 网络协议栈示意

可以看到,TCP/IP协议栈并非只有TCP和IP这两个协议,而是以TCP和IP为核心的网络协议栈。下面自顶向下地介绍TCP/IP协议栈的每一层。

1.2.1 应用层

应用层在TCP/IP中位于最顶层,用于用户的应用程序和服务。应用层的数据是真正给用户提供服务的,应用层下面的所有协议层(传输层、网络层和网络接口层)都是为了传输应用层的数据而设计的。超文本传输协议(hyper text transfer protocol,HTTP)和域名服务(domain name service,DNS)协议是应用层的两个常用协议。

HTTP是一种用于分布式、协作式和超媒体信息系统的应用层协议,是万维网(world wide web,WWW)数据通信的基础。

HTTP的工作流程,需要有客户端和服务端的参与,通常情况下用户的浏览器、应用程序等是HTTP的客户端,用户访问的网站、应用程序的后台及数据部署在HTTP的服务端。通过HTTP,客户端可以从服务端获取网页等资源,也可以上传本地数据到服务端中,如图1-2所示。

图1-2 HTTP的工作流程示意

DNS协议(一个基于UDP的应用层协议)的作用是将主机域名解析为IP地址,以及做相反解析。在访问网站时,通常会在浏览器的地址栏中输入域名(如www.baidu.com),但是计算机并不知道这个域名的服务器在哪里、要将请求发送到哪里,计算机的网络层只认识IP地址。这时,就需要获取域名对应的IP地址,DNS的作用就是在域名和IP地址之间建立起映射关系,将用户输入的域名转换为相应的IP地址,以实现对某特定网站的访问。用户对DNS解析的过程是无感知的,只需要在浏览器中输入域名即可访问特定网站,而至于浏览器如何把数据包发送到目的地,用户无须知道。

我们可以把DNS服务器想象成一个电话簿,里面记录着所有人的姓名(域名)和手机号(IP地址)。作为客户端的浏览器向DNS服务器发送查询域名的请求,就可以得到该域名对应的IP地址,也就是该域名对应的服务端的地址,整个查询过程被称为DNS解析。以访问域名www.baidu.com为例,DNS解析过程的示意如图1-3所示。

图1-3 DNS解析过程的示意

客户端向DNS服务端发送DNS请求报文,报文内容是“www.baidu.com”;

DNS服务端向客户端返回DNS应答报文,报文内容是“www.baidu.com对应的IP地址是183.240.×.×(此处省略了IP地址后两段)”。

实际上,DNS解析过程要比图1-3中描述得复杂,目前常用的DNS解析方式有本地DNS(Local DNS)和HTTPDNS两种,将在1.3.1节详述。

需要注意的是,我们要访问的网站或系统的服务器通常会被部署在全球各地,当进行DNS解析时,DNS服务器返回的是离我们最近的服务器的IP地址。例如,在深圳通过浏览器访问www.baidu.com,DNS服务器返回的IP地址就是183.240.×.×,该IP地址的归属地为中国广东省。

1.2.2 传输层

传输层的作用,是保证应用层的数据能在互联网上正确地从源地传输到目的地。在TCP/IP中,传输层有两个常见协议:TCP和UDP。一句话总结这两个协议的区别——TCP是可靠传输协议[1],UDP是不可靠传输协议。

[1]可靠传输协议,是指协议能够保证数据完整且安全地从发送方到达接收方。

如果把应用层的数据比作一批存放在深圳的货物,现在有个北京的顾客想要购买这批货物,那么将这批货物顺利地从深圳运往北京就是传输层要做的事情。深圳的发货人如何确定接收货物的北京的顾客是正确的接收人,北京的顾客又如何相信深圳的发货人的身份是真实的?货物在运输途中,如何保证货物不会被其他人截获、调包或窃取,又如何保证货物能按照约定时间送到?

以上这些问题都是TCP要解决的,而UDP只负责将这批货物发出,并不负责解决这些问题。UDP不保证数据传输的可靠性,但其传输效率要远远高于TCP。

TCP和UDP各有适用的场景,什么样的数据使用TCP来传输,什么样的数据使用UDP来传输,主要取决于应用层的需求。如果应用层要保证数据可靠性,就会选择TCP,否则就会选择UDP。

就TCP而言,传输层的职责归纳起来有以下几点。

安全性:保证传输数据的安全,不可被截获、调包或窃取,为此要使用传输层安全(transport layer security,TLS)协议。

可靠性:要保证数据完整地到达目的地,如果有丢失就需要重传。

公平性:需要公平地对待每个请求,即把有限的网络资源公平地分给每个请求。

有序性:数据必须按照发送顺序到达目的地,否则需要按照每个数据包的序号按序排列。

HTTP的数据传输过程要求可靠传输,因为要保证用户访问网站资源和传输资源的过程是安全、可靠、公平和有序的。在HTTP/2及以前版本的HTTP中,数据传输的可靠性都是使用TCP来保障的,而在HTTP/3中,是采用QUIC协议来保障的。

QUIC协议基于UDP,但由于UDP是不可靠传输协议,因此QUIC协议在实现时借鉴了TCP的安全、可靠、公平和有序的特性,并且在传输效率上进行了优化。

1.2.3 网络层

在TCP/IP中,网络层也叫作IP层,或者路由层,决定了数据传输走哪条路更合适。还是以北京的顾客想要购买深圳的货物为例,货物的运输是走京九线更合适,还是走京广线更合适?经过武汉后,下一站要不要经过郑州?这些问题是由网络层来解决的。网络层中应用最广泛的协议就是IP。

网络层的路由功能实现了不同网络的互联,形成了互联网。连接到互联网的所有设备都带有IP地址,每个数据包都附加有IP信息,这能帮助路由器将这些数据包发送到正确的位置。数据包到达目的地后,被交给传输层协议处理。

除了路由功能,网络层还有一个功能是IP分片。网络传输过程中用最大传输单元(maximum transmission unit,MTU)来限制所能传输的数据包大小,MTU是指一次传送数据的最大长度。当发送的IP数据包的大小超过了MTU时,网络层就需要对数据进行分片,否则数据将无法被成功发送。IP分片发生在网络层,不仅源端主机会进行分片,中间的路由器也有可能进行分片,因为不同网络的MTU是不一样的。如果传输路径上的某个网络的MTU比源端网络的MTU小,路由器就可能对数据包再次进行分片。而分片数据的重组只会发生在目的端的网络层。

在网络编程中要避免IP分片,原因是网络层没有超时重传机制,如果网络层对一个数据包进行了分片,只要有一个分片丢失了,就只能依赖传输层重传所有的分片,这个代价相对较大。

网络层还有一个常见的协议是互联网控制报文协议(internet control message protocol,ICMP),主要用于检测网络通不通、主机是否可达、路由是否可用。ICMP虽然不传输用户数据,但是对于用户数据的传输起着重要作用。

1.2.4 网络接口层

在互联网中,数据包在客户端和服务端之间的传输往往需要经过很多个网络站点进行转发。如何从本机把数据包转发到下一个网络站点,是TCP/IP的网络接口层要做的事情。网络接口层不仅要把下一个网络站点的IP地址转换为MAC地址(因为MAC地址才是唯一的),还要确定从本机哪个网络接口把这个数据包发出去。网络接口层常见的协议是地址解析协议(address resolution protocol,ARP),其工作原理如图1-4所示。

图1-4 ARP的工作原理示意

(1)主机34.2.11.17[2]需要把数据包发送到主机34.2.11.12上,但是它不知道34.2.11.12的MAC地址是多少,所以需要发送一个ARP请求报文到网关中。在该例子中,ARP请求的内容是“我的IP地址是34.2.11.17、MAC地址是00:00:AD:3F:89:1F,谁的IP地址是34.2.11.12”。

[2]图1-4中出现的IP地址均非真实IP地址。

(2)ARP请求报文到达网关后,网关会将ARP请求报文广播到局域网中所有的主机上。由此可见,ARP请求报文是一个广播报文。

(3)主机34.2.11.12收到ARP请求报文后,返回ARP应答报文,内容是“我的IP地址是34.2.11.12、MAC地址是A5:22:88:5F:66:2B”。由此可见,ARP应答报文是一个单播报文。

(4)主机34.2.11.17收到ARP应答报文,即查找到与目标IP地址对应的MAC地址后,ARP过程结束。

需要注意的是,ARP仅适用于IPv4中,IPv6中有地址解析功能的协议是邻居发现协议(neighbor discovery protocol)。

知识拓展:IPv4和IPv6

IP协议有两个版本,IPv4(第四个版本)和IPv6(第六个版本),IPv4使用32位地址,可以表示约42.9亿个不同的地址。然而,由于地址分配的不均衡及网络技术的快速发展,IPv4地址已基本用尽。IPv6解决了这一问题,它使用128位地址,理论上拥有3.4×1038个地址,几乎可以满足无限数量的设备连接需求。

1.3 网站是如何加载的

本节将以访问百度的官方网站为例,介绍用户在浏览器地址栏中输入https://www.baidu.com之后都发生了什么。

网页加载过程可以分为4个阶段:DNS解析、TCP连接建立、TLS连接建立,以及HTTP请求及应答,如图1-5所示。

下面分别介绍这4个阶段。

图1-5 网页加载过程的4个阶段

1.3.1 DNS解析

1.2.1节提到目前互联网中常用的DNS解析方式有两种——本地DNS和HTTPDNS。本地DNS是传统的DNS解析过程,使用的是DNS协议。随着时代的发展,DNS解析过程也在逐步优化,近几年HTTPDNS[3]技术发展很快,很多公司都在部署自己的HTTPDNS服务器,大有替代本地DNS的趋势。下面分别介绍本地DNS和HTTPDNS的原理。

[3]相较于本地DNS使用UDP,HTTPDNS使用HTTP进行DNS解析,避免了DNS劫持的安全风险。

1.本地DNS的原理

以在浏览器地址栏中输入https://www.baidu.com为例,浏览器是客户端,www.baidu.com的服务器是服务端。在向域名服务器发起DNS请求之前,浏览器需要查找浏览器的缓存中是否有此域名的解析结果,如果有则DNS解析结束,如果没有则继续查找操作系统的缓存中是否有这个域名对应的解析结果,如果也没有,则需要向本地DNS服务器(Local DNS Server)发起DNS请求。这就是本地DNS解析的工作原理。

本地DNS解析过程,如图1-6所示。

图1-6 本地DNS解析过程

(1)浏览器向本地DNS服务器(系统网络配置中已经配置好的)发送DNS请求,请求中携带要解析的域名。这个DNS服务器之所以称为本地DNS服务器,是因为该服务器通常离我们所在地不会太远。

(2)如果本地DNS服务器中没有该域名对应的IP地址,就向根DNS服务器(Root DNS Server)发起DNS请求。

(3)根DNS服务器会向本地DNS服务器返回该域名的一个通用顶级域名(gTLD)对应的地址(图1-6中的顶级DNS服务器的地址)。gTLD是国际顶级域名(包含“.com”“.cn”“.org”等后缀),所有提供域名注册的注册商必须在根DNS服务器中注册。

(4)本地DNS服务器拿到顶级DNS服务器的地址后,再带着要解析的域名向顶级DNS服务器发起DNS请求。

(5)顶级DNS服务器查找并返回此域名对应的域名服务器(也叫作二级DNS服务器)的地址。

(6)本地DNS服务器获得二级DNS服务器的地址后,向二级DNS服务器发起DNS请求。

(7)二级DNS服务器查询本地存储的所有域名与IP地址映射的表单,得到要查询的域名后,将其对应的IP地址和一个生存时间(time to live,TTL)[4]值一起返回给本地DNS服务器。

[4]TTL指的是解析记录在本地DNS服务器中的缓存时间。

(8)本地DNS服务器拿到域名对应的IP地址和TTL值后,先根据TTL值缓存此IP地址,最后将IP地址和TTL值返回给浏览器,浏览器根据TTL值将域名及其解析得到的IP地址缓存在本地缓存中。

2.HTTPDNS的原理

本地DNS的解析过程使用的是DNS协议,传输层使用UDP向DNS服务器发起请求,请求过程会经过运营商的本地DNS服务器,而且它是将DNS请求通过明文传输的,使用的服务端口号固定为53,这个过程有很严重的DNS劫持风险!而HTTPDNS技术则使用HTTP报文直接向DNS服务器发送DNS请求,它绕开了运营商的本地DNS服务器,简化了DNS请求的复杂性,同时也避免了使用运营商本地DNS服务器带来的DNS劫持风险和跨网问题。

虽然HTTPDNS简化了本地DNS解析的过程,但是解析的耗时未必比本地DNS解析的耗时低。因为发起HTTPDNS请求需要先建立TCP连接等,在网络较差或者往返路程时间(round trip time,RTT)[5]较长的情况下,HTTPDNS解析过程耗时就会比较长。

[5]RTT指的是数据从发送方传到接收方,又从接收方返回发送方所用的时间。

HTTPDNS解析过程(见图1-7)可以分为如下5步。

(1)在本机浏览器缓存中查找是否有这个域名的缓存,如果有则解析成功(如图1-7中的Q1和A1),否则浏览器继续在本机操作系统缓存中查找是否有这个域名对应的IP地址(如图1-7中的Q2和A2)。

(2)如果在本机浏览器和本机操作系统中都没有查到这个域名的缓存,浏览器会向HTTPDNS服务器发送HTTP请求(如图1-7中的Q3)。这里默认浏览器可以直接访问HTTPDNS服务器的IP地址,如果本机浏览器没有缓存HTTPDNS服务器的IP地址,则需要使用本地DNS解析的方式去解析HTTPDNS的域名。

图1-7 HTTPDNS解析过程

(3)HTTPDNS服务器返回应答报文,将域名解析结果通过HTTP应答报文返回浏览器(如图1-7中的A3)。

(4)浏览器收到域名解析结果,将其缓存下来(在实际业务中,域名解析的结果可以缓存在内存中,也可以缓存在磁盘中,不同业务可以根据不同情况选择缓存在哪里)。HTTPDNS解析过程结束。

(5)HTTPDNS解析过程结束后,浏览器获取业务服务器的IP地址,即可向业务服务器发起业务请求。业务请求的过程更为复杂,将在1.3.2~1.3.4节中进行详细介绍。

1.3.2 TCP连接建立

经过DNS解析之后,浏览器获得了www.baidu.com的服务器地址,接下来需要建立一条能够通往服务器的连接。按照1.2.2节的例子来看,远在北京的顾客想要购买深圳的货物,就要先建设一条能够连接深圳和北京的道路,以让装满货物的卡车通行。TCP连接建立的过程就是建设这条道路的过程。在数据的传输过程中,TCP连接使用网络四元组(源IP地址、源端口号、目的IP地址、目的端口号)来表达其唯一性。

TCP连接建立阶段是为数据的传输做准备工作。因为TCP是可靠传输协议,所以进行数据传输的双方需要先“认识”一下彼此,确认彼此的身份,并协商传输所需要的一些初始化参数。而UDP是不可靠传输协议,因此进行数据传输时没有建立连接这个阶段。

在TCP连接建立之前,服务端一直处于监听(Listening)状态,时刻在监听来自客户端的建立连接请求,这在程序上通常使用while(1)来实现。TCP连接建立的过程需要经过三次握手,如图1-8所示。

图1-8 TCP连接建立过程

第一次握手:客户端向服务端发送SYN(SYN=1,Seq=x)包,并进入SYN已发送(SYN_ SENT)状态,等待服务端确认。其中,SYN=1表示TCP包中的SYN标志位被置为1,表示该TCP包是SYN包。

第二次握手:当服务端收到客户端发送的SYN包时,必须回复一个ACK包(ACK=1,表示TCP包中的ACK标志位被置为1)以通知客户端“本端已经收到SYN包”,并发送一个SYN包(Seq=y)给客户端。在实际应用中,ACK包和SYN包往往被合并在同一个数据包中传输,所以本次握手服务器发送ACK+SYN包给客户端。此时,服务端进入收到SYN包(SYN_RCVD)状态。ack=x+1表示此ACK报文是对客户端发送的SYN(SYN=1,Seq=x)包的确认。

第三次握手:客户端收到服务端发来ACK(ack=x+1)+SYN包后,回复ACK(ACK=1,Seq=x+1,ack=y+1)包来响应服务端,此时客户端进入连接已建立(Established)状态。ack=y+1表示此ACK报文是对服务端发送的Seq=y的包的确认。

知识拓展:SYN包、Seq和ACK报文、ack号

同步序列编号(synchronize sequence number,SYN)包,是TCP连接建立过程中的发送第一个包。在TCP连接建立的第一次握手中,客户端发出的SYN包中只有SYN报文,所以SYN包也被称为SYN报文。

序列编号(sequence number,Seq),是指TCP包的序列号。TCP为保证数据的有序性,使用Seq来标识TCP包的顺序。在图1-8中Seq=x表示该TCP包的序列号是x。

ACK报文,即确认包(acknowledge packet)。在图1-8中,在第二次握手中ACK和SYN均被置为1,所以这个包既包含SYN报文也包含ACK报文,被称为SYN+ACK包。

ack,代表确认号(acknowledge number),即TCP包的确认号,表示接收端已经收到了发送端的某个包,并告诉发送端接下来的TCP包的Seq要从这次的ack开始。在图1-8中,第二次握手时ack=x+1,表示服务端已经收到了客户端发送的序列号为x的TCP包。

本书后续使用“ACK”代表ACK报文,使用“ack”代表ACK报文中的确认号。

1.3.3 TLS连接建立

HTTP采用的是明文传输,所谓明文就是客户端与服务端通信的内容没有进行加密,使用任何一个抓包工具都可以截获通信内容,这样一来通信内容被窃听或被篡改,以及客户端或服务端被冒充的风险就非常大。TLS协议的主要作用便是抵御这些安全风险。TLS协议的解决方式主要是以下3种。

身份认证:通过证书认证来确认对方身份,防止中间人攻击,并防止客户端或服务端被冒充的风险。

数据私密性:使用对称加密算法对被传输的数据进行加密以防止被窃听,而密钥只有客户端和服务端有,第三方无法窥探。

数据完整性:使用摘要算法对报文进行计算,接收方收到消息后校验该值以防止数据被篡改或丢失。

TLS连接建立是HTTPS传输的前提,HTTPS(HTTPS的相关内容将在3.1节介绍)要求所有发送的请求数据都必须是加密的。而在互联网初期没有这样的要求,所有的网络数据都是明文的。

这是因为在互联网发展初期还没有网络攻击,A发送数据给B根本不用担心数据被窃听或篡改,A和B之间可以进行明文通信。随着互联网技术和应用的发展,网络攻击逐渐频繁,目前在互联网中存在多种类型的网络攻击。下面以中间人攻击为例来说明TLS协议的作用。

假设A与B之间正在进行通信,在二者的网络中存在中间人C,中间人C要拦截A发送给B的数据再将数据进行篡改后发给B,这将导致B做出错误处理。

这时,如果A和B之间发送的数据是加密过的,且只有A和B拥有该密钥,即使中间人C拦截了数据也无法进行解密,更无法篡改数据。具体来说,A和B使用一个共享的密钥key,A发送数据之前用密钥key对数据进行加密,B收到数据之后使用同一份密钥key对数据进行解密。因为数据的加密和解密用的是同一个密钥,所以这种加密算法称为对称加密算法。

如何将A和B共享的密钥key协商出来,并保证协商过程不会被第三方破解,是TLS连接建立过程中要解决的最重要的问题。TLS协议使用非对称加密算法(也称密钥交换算法)来解决这一问题。之所以叫作“非对称”,是因为在算法中使用了公钥(public key)和私钥(private key)两个密钥,使用公钥加密的数据只能通过对应的私钥来解密。通信的两端(客户端和服务端)使用公钥和私钥再经过复杂的数学计算,最终计算出一个共享的密钥key。

在TLS连接建立阶段使用非对称加密算法的好处在于,A将私钥保存在本地,通过网络将自己的公钥发送给B。这样即使公钥被中间人C拦截了,只要对应的私钥没有被泄露,中间人C也无法破解A和B通信的内容。

知识拓展:常见的对称加密算法和非对称加密算法

在对称加密算法中,加密和解密过程使用的是同一个密钥,因此对密钥的保护非常重要。常见的对称加密算法有DES(数据加密标准)、AES(高级加密标准)等。

(1)DES是IBM开发的一种对称加密算法,被美国政府采用并标准化。它的密钥长度为56位,数据块大小为64位。DES由于密钥长度和数据块长度都比较短,所以安全性不够强,当前已经被淘汰。

(2)AES是正被广泛使用的一种对称加密算法,其密钥长度有128位、192位和256位3种可选,数据块大小为128位。它采用了多种加密技术,如SPN结构等,比DES的安全性更高。

在非对称加密算法中,加密和解密过程使用的是两个密钥——公钥和私钥,其中公钥用于加密数据,私钥用于解密数据。常见的非对称加密算法有RSA算法、ECDHE算法等。

(1)RSA算法由3位科学家Ron Rivest、Adi Shamir和Leonard AdlemanRivest-Shamir-Adleman提出,是一种比较传统的算法,曾经应用非常广泛。但因为它不具备前向安全(当前会话使用的主密钥被泄露,不会导致历史的会话密钥也被泄露)的性质,已经逐渐被ECDHE算法代替。

(2)ECDHE算法,即椭圆曲线临时迪菲-赫尔曼(Elliptic Curve Diffie-Hellman Ephemeral)算法。其中“临时”(“Ephemeral”),意味着每次通信都会生成一个新的临时密钥,从而实现前向安全。

在实际应用中,通常会组合使用对称加密算法和非对称加密算法。例如,在HTTPS中,首先使用非对称加密算法进行安全的握手并协商一个密钥,然后将其作为对称加密算法的密钥进行数据传输,以兼顾数据传输的安全性和效率。

从SSL协议到TLS协议,安全协议发展至今,已经迭代了很多版本(从SSL 1.0、SSL 2.0、SSL 3.0到TLS 1.0、TLS 1.1、TLS 1.2、TLS 1.3),它的安全性在每次版本迭代中都得到了增强。目前,业界常用的TLS协议版本是TLS 1.2和TLS 1.3,而QUIC连接建立推荐使用TLS 1.3协议,所以本节只介绍TLS 1.2连接建立的过程,而TLS 1.3连接建立的过程将在第5章介绍。

客户端如果是第一次与服务端建立连接,必须经过一次完整的TLS 1.2连接建立过程,否则可以使用TLS 1.2的会话复用(session reuse)功能直接复用之前的会话密钥等参数简化TLS 1.2连接建立的过程。下面先介绍TLS 1.2连接建立的过程,再介绍TLS 1.2的会话复用功能。

1.TLS 1.2连接建立的完整过程

在TLS 1.2协议中,需要用到的算法有非对称加密算法、消息认证算法(对建立连接的过程进行完整性检查)和对称加密算法,它们组成了TLS 1.2协议算法套件,如图1-9所示。

图1-9 TLS协议算法套件

目前,常用的非对称加密算法主要有RSA算法和ECDHE算法,TLS 1.2协议对这两种算法都支持,而TLS 1.3协议只支持ECDHE算法。本节介绍使用RSA算法的TLS 1.2连接建立的过程,而第5章介绍使用ECDHE算法的TLS 1.3连接建立的过程。

一次完整的TLS 1.2连接建立的过程总共需要4次握手,如图1-10所示。

图1-10 TLS 1.2连接建立过程示意

第一次握手:客户端发送一个Client Hello报文,这个报文包含客户端使用的TLS版本号(TLS Version)、一个由客户端生成的随机数(Client Random),客户端支持的密钥套件列表(Cipher Suites),如图1-11所示。其中,Client Random很重要,会被服务端保留,是生成对称加密密钥的元素之一,如图1-11所示。

第二次握手:服务端收到Client Hello报文后,先进行如下操作,再发送相关数据给客户端。

确认TLS版本号;

从客户端支持的密钥套件列表中选择一个密钥套件;

生成一个服务端的随机数(Server Random);

生成一个会话ID(Session ID),它的作用将在介绍TLS 1.2的会话ID机制时进一步介绍。

图1-11 第一次握手客户端发送的Client Hello报文示例

服务端发送给客户端的数据,分为Server Hello、Certificate、Server Key Exchange和Server Hello Done共4条消息,如图1-12所示。

图1-12 服务端发送给客户端的数据

Server Hello报文,包含服务端确认选择的TLS版本号、服务端选择使用的密钥套件,以及服务端生成的随机数等内容;

Certificate报文,包含用于验证服务端的身份的服务端的数字证书;

Server Key Exchange报文(可选),如果Certificate消息没有包含足够的数据导致在第三次握手时客户端无法与服务端交换预主(pre-master)密钥,服务端需要发送Server Key Exchange报文;

Server Hello Done报文的作用是通知客户端已完成握手消息的发送,第二次握手结束。

第三次握手:客户端发送一个携带着加密的预主密钥的报文Client Key Exchange给服务端,如图1-13所示。在第二次握手后,客户端验证收到的服务端的数字证书通过后生成一个新的随机数,即预主密钥,并使用服务端的数字证书的公钥对预主密钥进行加密,从而得到加密的预主密钥,再通过Client Key Exchange报文发送给服务端。

图1-13 客户端发送的Client Key Exchange报文示例

至此,客户端有3个随机数,分别是客户端生成的随机数、服务端生成的随机数和客户端生成的预主密钥。以这3个随机数作为非对称加密算法RSA的参数计算出主密钥(Master Key),再以主密钥为参数经过复杂的运算生成会话密钥(Session Key),会话密钥即是用来加密客户端和服务端的通信数据的对称密钥。

计算出会话密钥后,客户端发送一个Change Cipher Spec报文通知服务端开始使用加密的方式发送数据,并发送一个Finished报文用来对整个握手过程进行完整性校验和通知服务端第三次握手完成。

知识拓展:Change Cipher Spec报文

Change Cipher Spec报文标志着通信双方已经协商好加密算法和密钥,并准备使用这些参数进行加密通信。这个报文本身并不包含任何加密数据,只是一个简单的通知用来告诉对方从现在开始所有的通信数据都将使用新的加密算法和密钥进行加密。

第四次握手:服务端收到Client Key Exchange报文后,用自己的数字证书的私钥对加密的预主密钥进行解密,得到客户端生成的预主密钥。至此,服务端也有了3个随机数,分别是客户端生成的随机数、服务端生成的随机数和客户端生成的预主密钥。与第三次握手过程中客户端使用的加密算法相同,服务端以这3个随机数作为算法参数生成与客户端相同的会话密钥。

服务端计算出会话密钥后,发送一个Change Cipher Spec报文通知客户端开始使用加密方式发送数据,并发送Finished报文通知客户端第四次握手完成。

在TLS 1.2连接建立的4次握手期间,出现了3个名词:预主密钥、主密钥和会话密钥。预主密钥是第三次握手中客户端生成的随机数,主密钥是由非对称加密算法RSA生成的随机数,它们都是中间密钥,用于计算会话密钥。客户端和服务端双方一旦生成了主密钥,就会立即删除预主密钥,但是主密钥会被双方保存下来,这是因为主密钥是TLS 1.2进行会话复用的必要元素。

会话复用,又称会话恢复(session resumption),可以简化TLS连接建立的过程,使服务端不再需要发送数字证书给客户端。

TLS 1.2的会话复用有两种方式:会话ID(session ID)机制和会话票据(session ticket)机制。其中,会话ID机制比会话票据机制出现的时间早,但由于会话ID机制对服务器内存的消耗比较大,因此目前使用比较广泛的是会话票据机制。

然而在实际应用中,有些比较老旧的服务器不支持会话票据机制,所以在使用TLS 1.2会话复用功能建立连接的过程中,即使使用会话票据机制也会传输会话ID机制需要的数据,以做好会话复用功能降级(从会话票据机制降级为会话ID机制)的准备。下面分别介绍这两种会话复用方式。

2.TLS 1.2的会话复用:会话ID机制

客户端和服务端通过4次握手进行TLS 1.2连接建立时,服务端发给客户端的Server Hello报文中有一个会话ID字段,这个字段的值会被客户端和服务端保存起来——以会话ID为索引键、以协商成功后的主密钥为索引值,保存为一个键值对。对于客户端,不仅会保存会话ID和主密钥,还会保存本次会话的服务端的IP地址和端口号,这些数据共同形成了一条会话记录。

使用会话ID机制进行会话复用,TLS 1.2连接建立的过程总共需要三次握手,如图1-14所示。在第三次握手的时候,客户端除了发送Change Cipher Spec和Finished报文还发送了应用数据(Application Data),所以TLS 1.2连接建立的整个过程的耗时只需要1个RTT,这比未使用会话复用功能的TLS 1.2连接建立的过程节省了1个RTT。

图1-14 使用会话ID机制,TLS 1.2连接建立的流程

第一次握手:客户端发送Client Hello报文给服务端。

客户端根据要访问的服务端的IP地址和端口号找到会话ID(如图1-14中的Session ID),再把会话ID、TLS版本号和生成的随机数Client Random一起放在Client Hello报文中发送给服务端。

第二次握手:服务端发送Server Hello报文、Change Cipher Spec报文和Finished报文给客户端。

服务端收到客户端的Client Hello报文后解析出会话ID,并查找本地是否有缓存该会话ID。在分布式系统中,一般使用Redis来存储会话ID,这样该集群中的所有服务器都可以共享这些会话ID。

服务端查找到客户端的会话ID指定的会话之后,需要先判断当前的密钥套件和上个会话的密钥套件是否一致,如果一致则允许使用会话复用,于是服务端将Server Hello报文中的会话ID字段的值配置为和收到的Client Hello报文中的会话ID字段的值一样,然后服务端再生成一个随机数Server Random,连同TLS版本号一起发送给客户端。

如果服务端没有查找到客户端的会话ID指定的会话(可能是因为会话老化[6]),则会重新发起一次完整的TLS 1.2连接建立的过程,要么重新计算会话ID(和Client Hello报文中会话ID的值不一样),要么直接将会话ID的值设置为0,并通知客户端这次会话不能使用TLS 1.2的会话复用功能。

[6]会话老化(session aging,又称会话过期):服务端为每个会话ID设置了一个过期时间,当到达过期时间时这个会话会被服务端从缓存中删除。

至此为止,客户端和服务端根据Client Random、Server Random和主密钥计算本次的会话密钥。接下来服务端发送Change Cipher Spec报文通知客户端再进行通信的数据都使用会话密钥进行加密,最后服务端发送Finished报文给客户端通知客户端本次握手完成。

第三次握手:在经过前两次握手后,客户端和服务端都生成了本次会话的会话密钥,所以在第三次握手中,客户端发送Change Cipher Spec报文和Finished报文给服务端通知服务端本次握手完成,同时发送应用数据。这里的应用数据就是HTTP请求报文。

以上是使用会话ID机制时,TLS 1.2连接建立的过程,在这个过程中,因为要传输和存储会话ID,所以有以下两个缺点。

在实践中,会话老化时间通常会被配置为数小时,这很容易引起大量会话的堆积,进而占用过高的服务器内存。

在分布式系统中,需要使用Redis等存储会话ID,这也是不小的成本。如果服务器是集群模式,那么客户端和服务器A建立连接后会话ID将会被服务器A缓存,这个客户端再次发起请求时可能是向集群中的服务器B发起建立连接的请求,如果在这个集群中没有使用Redis等存储会话ID且服务器B中也没有缓存会话ID,会导致会话复用失败。因此,为了提高整个分布式系统的会话复用效率,就需要额外的Redis等来存储会话ID。

3.TLS 1.2的会话复用:会话票据机制

会话票据机制相比于会话ID机制是一种新的会话复用机制。客户端和服务端在进行完整的TLS 1.2连接建立时,客户端会在Client Hello报文的扩展字段中携带Session Ticket字段(字段内容为空)以表明客户端支持会话票据机制,在TLS 1.2连接建立完成后,服务端会发送一个New Session Ticket报文,该报文中包含了Session Ticket字段,它的值是服务端对主密钥进行编码、加密[7]后的值。客户端收到New Session Ticket报文后,将服务端的IP地址、端口号、主密钥及报文中的Session Ticket字段的值关联起来,保存在本地。

[7]服务端通常有一个ticket.key文件,在这个文件中包含了一个密钥对,服务端使用其中的公钥对主密钥进行加密,使用其中的私钥对主密钥进行解密。

在会话ID机制中会话ID需要被同时保存在客户端和服务端,而在会话票据机制中Session Ticket字段的值只由客户端保存即可,这就是两种机制的主要不同。

使用Session Ticket字段进行会话复用,TLS 1.2连接建立的过程只需要3次握手,并且在第三次握手的时候,客户端除了发送Change Cipher Spec报文、Finished报文还发送了应用数据,所以TLS 1.2连接建立的整个过程的耗时只需要1个RTT,如图1-15所示。

图1-15 使用会话票据机制,TLS 1.2连接建立的流程

第一次握手:客户端发送Client Hello报文。

客户端根据要访问的服务端的IP地址和端口号查找本地缓存的主密钥和Session Ticket,找到后将Session Ticket的值放在Client Hello报文的扩展字段中的Session Ticket字段中。如果客户端无法找到本地缓存的主密钥或Session Ticket,则无法使用会话票据机制进行会话复用。

随后客户端生成一个随机数Client Random,将其连同TLS版本号和Session ID放在Client Hello报文中发送给服务端。

第二次握手:服务端收到客户端发送的Client Hello报文后,先将Session Ticket字段从报文中取出,并使用本端的私钥进行解密从而得到主密钥。

接下来服务端校验密钥套件、协议版本号等,如果校验成功则表示本次可以使用会话复用功能,服务端将按照会话复用流程发送Server Hello报文给客户端。

客户端和服务端通过Client Random、Server Random和Session Ticket字段中的主密钥计算出用于本次会话的会话密钥。计算出会话密钥后,服务端发送Change Cipher Spec报文和Finished报文给客户端。

为了保证前向安全,无论是以会话ID机制还是会话票据机制进行会话复用,每次会话生成的会话密钥都是不同的。所以在会话票据机制中主密钥生成后的一段时间内,尽管主密钥不会发生变化,但是每次会话复用都不会直接使用这个主密钥作为会话密钥,而是利用这个主密钥和Client Random、Server Random生成新的会话密钥来对本次会话的数据进行加密和解密。

第三次握手:客户端发送Change Cipher Spec报文、Finished报文和应用数据。

1.3.4 HTTP请求及应答

经历了DNS解析、TCP连接建立和TLS连接建立,浏览器已经和Web服务器之间建立了一条安全、可靠的传输通道,接下来就是请求网站资源,也就是进入HTTP请求及应答过程。

客户端发送HTTP请求给服务端,服务端通过HTTP请求中的URL(uniform resource locator,统一资源定位符)字段返回对应的资源数据给客户端。这些资源数据将通过HTTP应答报文来发送。在请求百度的首页www.baidu.com后,百度的服务器会响应首页所需要的资源(HTML、CSS、JavaScript代码和图片等),如图1-16所示。

可以看到,百度的首页共需要发送62个请求,整个请求-响应过程需要1.05 s。一个复杂的网页需要发送的请求的数量将更多,如果串行发送这些请求(一个请求-响应过程结束了,再进行下一个请求-响应过程)那么耗时将非常长,如果使用多个连接并行发送请求将会消耗很多客户端和服务端资源。如何并行地发送这些请求而又不造成过多资源消耗是HTTP/2要解决的问题,这部分内容将在2.1.2节中详述。

浏览器负责处理服务器返回的响应,例如解析HTML代码,并在内存中构建DOM,在整个处理期间浏览器可能会发现正常显示页面还需要CSS、JavaScript代码和图片等资源。

在获取了足够多的资源后,浏览器开始在屏幕上进行页面渲染。页面渲染技术是Web技术的重要部分,选用合理的页面渲染技术能够提升网站的使用体验。页面渲染相关的技术不是本书的重点,故不详述。

图1-16 百度首页所需要的资源展示

1.4 小结

本章介绍了网络协议和TCP/IP的一些基础知识,其中包括TCP/IP的应用层、传输层、网络层和网络接口层的内容和作用,并重点介绍了在浏览器地址栏中输入一个网址之后,网页加载过程的4个阶段——DNS解析、TCP连接建立、TLS连接建立,以及HTTP请求及应答分别发生了什么。

相关图书

Agent设计模式 图解可复用智能体架构
Agent设计模式 图解可复用智能体架构
AI Agent 开发实战:MCP+A2A+LangGraph 驱动的智能体全流程开发
AI Agent 开发实战:MCP+A2A+LangGraph 驱动的智能体全流程开发
Coze入门:7天玩转扣子智能体
Coze入门:7天玩转扣子智能体
计算流体力学大串讲轻松解锁CFD     从公式到代码的奇妙之旅
计算流体力学大串讲轻松解锁CFD 从公式到代码的奇妙之旅
内网攻防实战图谱:从红队视角构建安全对抗体系
内网攻防实战图谱:从红队视角构建安全对抗体系
计算机组成原理(基于x86-64架构)
计算机组成原理(基于x86-64架构)

相关文章

相关课程