当前位置: 首页 > article >正文

网络应用层

网络应用层

image-20241024171725837

DNS

DNS服务器

​ DNS 服务器自底向上可以依次分为以下几个层级(所有 DNS 服务器都属于以下四个类别之一):

  • 根 DNS 服务器。根 DNS 服务器提供 TLD 服务器的 IP 地址。
  • 顶级域 DNS 服务器(TLD 服务器)。顶级域是指域名的后缀,如com、org、net和edu等。国家也有自己的顶级域,如uk、fr和ca。TLD 服务器提供了权威 DNS 服务器的 IP 地址。
  • 权威 DNS 服务器。在因特网上具有公共可访问主机的每个组织机构必须提供公共可访问的 DNS 记录,这些记录将这些主机的名字映射为 IP 地址。
  • 本地 DNS 服务器。每个 ISP(互联网服务提供商)都有一个自己的本地 DNS 服务器。当主机发出 DNS 请求时,该请求被发往本地 DNS 服务器,它起着代理的作用,并将该请求转发到 DNS 层次结构中。严格说来,不属于 DNS 层级结构。

DNS工作流程(简述下 DNS 域名解析的过程。★★★★★)

​ DNS 域名解析协议,将域名映射成为IP ,基于 UDP 协议(当客户端需要域名解析时,通过本机的 DNS 客户端构造一个DNS 请求报文,以UDP数据报方式发往本地域名服务器)。DNS 的查询解析过程分为两种模式:迭代与递归

​ 现在,主机 cis.poly.edu 想知道 gaia.cs.umass.edu 的 IP 地址。假设主机cis.poly.edu 的本地 DNS 服务器为dns.poly.edu,并且gaia.cs.umass.edu的权威 DNS 服务器为dns.cs.umass.edu。

  1. 首先,先检查浏览器中的 DNS 缓存,如果浏览器中有对应的记录会直接使用,并完成解析;如果浏览器没有缓存,那就去查询操作系统的缓存,如果查询到记录就可以直接返回 IP 地址,完成解析;如果操作系统没有 DNS 缓存,就会去查看本地 host 文件,Windows 操作系统下,host 文件一般位于 “C:\Windows\System32\drivers\etc\hosts”,如果 host 文件有记录则直接使用;
  2. 如果以上都没有,主机cis.poly.edu向本地 DNS 服务器dns.poly.edu发送一个 DNS 请求,该查询报文包含被转换的域名gaia.cs.umass.edu(本地 DNS 服务器一般是由本地网络服务商如移动、联通等提供。通常情况下可通过 DHCP 自动分配,当然也可以自己手动配置;目前用的比较多的是谷歌提供的公用 DNS 是 8.8.8.8 和国内的公用 DNS 是 114.114.114.114)。
  3. 本地 DNS 服务器dns.poly.edu检查本机缓存发现并无记录,也不知道gaia.cs.umass.edu的 IP 地址该在何处,不得不向根服务器发送请求
  4. 根服务器注意到请求报文中含有edu顶级域因此告诉本地 DNS,你可以向edu的 TLD DNS 发送请求,因为目标域名的 IP 地址很可能在那里。
  5. 本地 DNS 获取到了edu的 TLD DNS 服务器地址向其发送请求,询问gaia.cs.umass.edu的 IP 地址
  6. edu的 TLD DNS 服务器仍不清楚请求域名的 IP 地址,但是它注意到该域名有umass.edu前缀,因此返回告知本地 DNS,umass.edu的权威服务器可能记录了目标域名的 IP 地址。
  7. 这一次,本地 DNS 将请求发送给权威 DNS 服务器dns.cs.umass.edu。
  8. 终于,由于gaia.cs.umass.edu向权威 DNS 服务器备案过,在这里有它的 IP 地址记录,权威 DNS 成功地将 IP 地址返回给本地 DNS
  9. 最后,本地 DNS 获取到了目标域名的 IP 地址,将其返回给请求主机

📒(图一为迭代式查询,图二为递归式查询,具体过程类似,只是顺序有所不同)

image-20241024181754604

image-20241024181814301

​ 另外,DNS 的缓存位于本地 DNS 服务器。由于全世界的根服务器甚少,只有 600 多台,分为 13 组,且顶级域的数量也在一个可数的范围内,因此本地 DNS 通常已经缓存了很多 TLD DNS 服务器,所以在实际查找过程中,无需访问根服务器。根服务器通常是被跳过的,不请求的。这样可以提高 DNS 查询的效率和速度,减少对根服务器和 TLD 服务器的负担

DNS报文格式

image-20241024182130583

DNS 报文分为查询和回答报文,两种形式的报文结构相同。

  • 标识符。16 比特,用于标识该查询。这个标识符会被复制到对查询的回答报文中,以便让客户用它来匹配发送的请求和接收到的回答。
  • 标志。1 比特的”查询/回答“标识位,0表示查询报文,1表示回答报文;1 比特的”权威的“标志位(当某 DNS 服务器是所请求名字的权威 DNS 服务器时,且是回答报文,使用”权威的“标志);1 比特的”希望递归“标志位,显式地要求执行递归查询;1 比特的”递归可用“标志位,用于回答报文中,表示 DNS 服务器支持递归查询。
  • 问题数、回答 RR 数、权威 RR 数、附加 RR 数。分别指示了后面 4 类数据区域出现的数量。
  • 问题区域。包含正在被查询的主机名字,以及正被询问的问题类型。
  • 回答区域。包含了对最初请求的名字的资源记录。在回答报文的回答区域中可以包含多条 RR,因此一个主机名能够有多个 IP 地址。
  • 权威区域。包含了其他权威服务器的记录。
  • 附加区域。包含了其他有帮助的记录

DNS记录

​ DNS 服务器在响应查询时,需要查询自己的数据库,数据库中的条目被称为资源记录(Resource Record,RR)。RR 提供了主机名到 IP 地址的映射。RR 是一个包含了Name, Value, Type, TTL四个字段的四元组

image-20241024182243909

TTL是该记录的生存时间,它决定了资源记录应当从缓存中删除的时间。

NameValue 字段的取值取决于 Type

image-20241024182300006

  • 如果Type=A,则Name是主机名信息,Value 是该主机名对应的 IP 地址。这样的 RR 记录了一条主机名到 IP 地址的映射。

  • 如果 Type=AAAA (与 A 记录非常相似),唯一的区别是 A 记录使用的是 IPv4,而 AAAA 记录使用的是 IPv6。

  • 如果Type=CNAME (Canonical Name Record,真实名称记录) ,则Value是别名为Name的主机对应的规范主机名。Value值才是规范主机名。CNAME 记录将一个主机名映射到另一个主机名。CNAME 记录用于为现有的 A 记录创建别名。下文有示例。

  • 如果Type=NS,则Name是个域,而Value是个知道如何获得该域中主机 IP 地址的权威 DNS 服务器的主机名。通常这样的 RR 是由 TLD 服务器发布的。

  • 如果Type=MX ,则Value是个别名为Name的邮件服务器的规范主机名。既然有了 MX 记录,那么邮件服务器可以和其他服务器使用相同的别名。为了获得邮件服务器的规范主机名,需要请求 MX 记录;为了获得其他服务器的规范主机名,需要请求 CNAME 记录

CNAME记录总是指向另一则域名,而非 IP 地址。假设有下述 DNS zone:

NAME                    TYPE   VALUE
--------------------------------------------------
bar.example.com.        CNAME  foo.example.com.
foo.example.com.        A      192.0.2.23

​ 当用户查询 bar.example.com 的时候,DNS Server 实际返回的是 foo.example.com 的 IP 地址。

为什么 DNS 采用分布式层次数据库

集中式的问题包括:单点故障通信容量有限远距离的集中式数据库查询慢、不便于维护可扩展性差

HTTP

点击一下网页会发生什么(点击网页一次 HTTP 请求过程?(在浏览器里输入一个网址后执行的全部过程)★★★)

  1. 域名解析(域名 www.baidu.com 解析为 ip 地址),通过 DNS 协议,获取域名对应的 IP 地址(配合DNS域名解析协议过程?食用更佳)。
    • 浏览器搜索自己的DNS缓存(维护一张域名与IP的对应表);
    • 若没有,则搜索操作系统的DNS缓存(维护一张域名与IP的对应表);
    • 若没有,则搜索操作系统的hosts文件(维护一张域名与IP的对应表)。
    • 若都没有,则找 tcp/ip 参数中设置的首选 dns 服务器,即本地 dns 服务器(递归查询),本地域名服务器查询自己的dns缓存,如果没有,则进行迭代查询。将本地dns服务器将IP返回给操作系统,同时缓存IP。
  2. **浏览器根据 IP 地址发起 tcp 的三次握手,建立 tcp 连接。浏览器会以一个随机端口(1024-65535)向服务端的 web 程序 80 端口发起 tcp 的连接。
  3. 建立 tcp 连接后,向服务器发送一个 HTTP 请求报文,请求获取网页的内容:GET /chn/index.htm 。
  4. 服务器 web 应用程序收到 http 请求后,就开始处理请求,处理之后就返回给浏览器 index.html 文件。
  5. 浏览器解析 html 代码,并请求 html 中的资源(浏览器收到 HTTP 响应报文后,解析响应体中的 HTML 代码,渲染网页的结构和样式,同时根据 HTML 中的其他资源的 URL(如图片、CSS、JS 等),再次发起 HTTP 请求,获取这些资源的内容,直到网页完全加载显示)
  6. 浏览器对页面进行渲染,并呈现给用户。
  7. 浏览器在不需要和服务器通信时,可以主动关闭 TCP 连接,或者等待服务器的关闭请求。

image-20241024182759453

HTTP 状态码有哪些?

HTTP 状态码用于描述 HTTP 请求的结果,状态码开头代表类型:image-20241024182846205

1xx Informational(信息性状态码)

相比于其他类别状态码来说,1xx 你平时你大概率不会碰到,所以这里直接跳过。

🍸2xx Success(成功状态码)

  • 200 OK:请求被成功处理。比如我们发送一个查询用户数据的 HTTP 请求到服务端,服务端正确返回了用户数据。这个是我们平时最常见的一个 HTTP 状态码。
  • 201 Created:请求被成功处理并且在服务端创建了一个新的资源。比如我们通过 POST 请求创建一个新的用户。
  • 202 Accepted:服务端已经接收到了请求,但是还未处理。
  • 204 No Content:服务端已经成功处理了请求,但是没有返回任何内容。

这里格外提一下 204 状态码,平时学习/工作中见到的次数并不多。

简单来说,204 状态码描述的是我们向服务端发送 HTTP 请求之后,只关注处理结果是否成功的场景。也就是说我们需要的就是一个结果:true/false。

举个例子:你要追一个女孩子,你问女孩子:“我能追你吗?”,女孩子回答:“好!”。我们把这个女孩子当做是服务端就很好理解 204 状态码了。

🍹3xx Redirection(重定向状态码)

  • 🥔301 Moved Permanently:资源被永久重定向了。比如你的网站的网址更换了。
  • 🥕302 Found:资源被临时重定向了。比如你的网站的某些资源被暂时转移到另外一个网址。

🍺4xx Client Error(客户端错误状态码)

  • 🌽400 Bad Request:发送的 HTTP 请求存在语法问题。比如请求参数不合法、请求方法错误。
  • 401 Unauthorized:未认证却请求需要认证之后才能访问的资源。
  • 🌶️403 Forbidden:服务器收到 HTTP 请求,但是拒绝提供服务。一般用来针对非法请求。
  • 🥒404 Not Found:你请求的资源未在服务端找到。比如你请求某个用户的信息,服务端并没有找到指定的用户。
  • 409 Conflict:表示请求的资源与服务端当前的状态存在冲突,请求无法被处理。

🍻5xx Server Error(服务端错误状态码)

  • 🥬500 Internal Server Error:服务端出问题了(通常是服务端出 Bug 了)。比如你服务端处理请求的时候突然抛出异常,但是异常并未在服务端被正确处理。
  • 502 Bad Gateway:我们的网关将请求转发到服务端,但是服务端返回的却是一个错误的响应

状态码301和302的区别是什么?

  • 共同点:301和302状态码都表示重定向,就是说浏览器在拿到服务器返回的这个状态码后会自动跳转到一个新的URL地址,这个地址可以从响应的Location首部中获取(用户看到的效果就是他输入的地址A瞬间变成了另一个地址B)。
  • 不同点:301表示旧地址A的资源已经被永久地移除了(这个资源不可访问了),搜索引擎在抓取新内容的同时也将旧的网址交换为重定向之后的网址;302表示旧地址A的资源还在(仍然可以访问),这个重定向只是临时地从旧地址A跳转到地址B,搜索引擎会抓取新的内容而保存旧的网址。 SEO中302好于301。

补充,重定向原因

  1. 网站调整(如改变网页目录结构);
  2. 网页被移到一个新地址;
  3. 网页扩展名改变(如应用需要把.php改成.Html或.shtml)。

HTTP请求报文和响应报文的格式?

请求报文格式

  1. 请求行(请求方法+URI协议+版本):包括请求方法,访问的资源URL,使用的HTTP版本。GET和POST是最常见的HTTP方法,除此以外还包括DELETE、HEAD、OPTIONS、PUT、TRACE
  2. 请求头部(属性名:属性值):服务端根据请求头获取客户端的信息,主要有cookie、host、connection、accept-language、accept-encoding、user-agent
  3. 空行
  4. 请求主体:用户的请求数据如用户名,密码等
GET/sample.jspHTTP/1.1 请求行
Accept:image/gif.image/jpeg, 请求头部
Accept-Language:zh-cn
Connection:Keep-Alive
Host:localhost
User-Agent:Mozila/4.0(compatible;MSIE5.01;Window NT5.0)
Accept-Encoding:gzip,deflate

username=jinqiao&password=1234 请求主体

响应报文

  1. 状态行(版本+状态码+原因短语)
  2. 响应首部(响应头字段主要有connection、content-type、content-encoding、content-length、set-cookie、Last-Modified,、Cache-Control、Expires)
  3. 空行
  4. 响应主体(服务器返回给客户端的内容)
HTTP/1.1 200 OK
Server:Apache Tomcat/5.0.12
Date:Mon,6Oct2003 13:23:42 GMT
Content-Length:112

<html>
    <head>
        <title>HTTP响应示例<title>
    </head>
    <body>
        Hello HTTP!
    </body>
</html>

HTTP Header 中常见的字段有哪些?

请求头字段名说明示例
Accept能够接受的回应内容类型(Content-Types)。Accept: text/plain
Accept-Charset能够接受的字符集Accept-Charset: utf-8
Accept-Datetime能够接受的按照时间来表示的版本Accept-Datetime: Thu, 31 May 2007 20:35:00 GMT
Accept-Encoding能够接受的编码方式列表。参考 HTTP 压缩。Accept-Encoding: gzip, deflate
Accept-Language能够接受的回应内容的自然语言列表。Accept-Language: en-US
Authorization用于超文本传输协议的认证的认证信息Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==
Cache-Control用来指定在这次的请求/响应链中的所有缓存机制 都必须 遵守的指令Cache-Control: no-cache
Connection该浏览器想要优先使用的连接类型Connection: keep-alive Connection: Upgrade
Content-Length以 八位字节数组 (8 位的字节)表示的请求体的长度Content-Length: 348
Content-MD5请求体的内容的二进制 MD5 散列值,以 Base64 编码的结果Content-MD5: Q2hlY2sgSW50ZWdyaXR5IQ==
Content-Type请求体的 多媒体类型 (用于 POST 和 PUT 请求中)Content-Type: application/x-www-form-urlencoded
Cookie之前由服务器通过 Set- Cookie (下文详述)发送的一个 超文本传输协议 CookieCookie: $Version=1; Skin=new;
Date发送该消息的日期和时间(按照 RFC 7231 中定义的"超文本传输协议日期"格式来发送)Date: Tue, 15 Nov 1994 08:12:31 GMT
Expect表明客户端要求服务器做出特定的行为Expect: 100-continue
From发起此请求的用户的邮件地址From:user@example.com
Host服务器的域名(用于虚拟主机 ),以及服务器所监听的传输控制协议端口号。如果所请求的端口是对应的服务的标准端口,则端口号可被省略。Host:en.wikipedia.org:80
If-Match仅当客户端提供的实体与服务器上对应的实体相匹配时,才进行对应的操作。主要作用时,用作像 PUT 这样的方法中,仅当从用户上次更新某个资源以来,该资源未被修改的情况下,才更新该资源。If-Match: “737060cd8c284d8af7ad3082f209582d”
If-Modified-Since允许在对应的内容未被修改的情况下返回 304 未修改( 304 Not Modified )If-Modified-Since: Sat, 29 Oct 1994 19:43:31 GMT
If-None-Match允许在对应的内容未被修改的情况下返回 304 未修改( 304 Not Modified )If-None-Match: “737060cd8c284d8af7ad3082f209582d”
If-Range如果该实体未被修改过,则向我发送我所缺少的那一个或多个部分;否则,发送整个新的实体If-Range: “737060cd8c284d8af7ad3082f209582d”
If-Unmodified-Since仅当该实体自某个特定时间已来未被修改的情况下,才发送回应。If-Unmodified-Since: Sat, 29 Oct 1994 19:43:31 GMT
Max-Forwards限制该消息可被代理及网关转发的次数。Max-Forwards: 10
Origin发起一个针对 跨来源资源共享 的请求。Origin: http://www.example-social-network.com
Pragma与具体的实现相关,这些字段可能在请求/回应链中的任何时候产生多种效果。Pragma: no-cache
Proxy-Authorization用来向代理进行认证的认证信息。Proxy-Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==
Range仅请求某个实体的一部分。字节偏移以 0 开始。参见字节服务。Range: bytes=500-999
Referer表示浏览器所访问的前一个页面,正是那个页面上的某个链接将浏览器带到了当前所请求的这个页面。Referer: http://en.wikipedia.org/wiki/Main_Page
TE浏览器预期接受的传输编码方式:可使用回应协议头 Transfer-Encoding 字段中的值;TE: trailers, deflate
Upgrade要求服务器升级到另一个协议。Upgrade: HTTP/2.0, SHTTP/1.3, IRC/6.9, RTA/x11
User-Agent浏览器的浏览器身份标识字符串User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:12.0) Gecko/20100101 Firefox/21.0
Via向服务器告知,这个请求是由哪些代理发出的。Via: 1.0 fred, 1.1 example.comopen in new window (Apache/1.1)
Warning一个一般性的警告,告知,在实体内容体中可能存在错误。Warning: 199 Miscellaneous warning

HTTP 和 HTTPS 有什么区别?

image-20241024183115611

HTTP:超文本传输协议,定义了浏览器怎样向万维网服务器请求万维网文档,以及服务器怎样把文档传送给浏览器,基于 TCP

​ HTTP的特点:无状态(不记录用户访问状态,一般用cookie记录)、可以是持久性连接(所有请求和响应经相同的 TCP 连接发送),也可以是非持久性连接(每个请求/响应对是经一个单独的TCP 连接发送)

🍙区别:

  • 端口号:HTTP 默认是 80,HTTPS 默认是 443。

  • URL 前缀:HTTP 的 URL 前缀是 http://,HTTPS 的 URL 前缀是 https://

  • 安全性和资源消耗:HTTP 协议运行在 TCP 之上,所有传输的内容都是明文,客户端和服务器端都无法验证对方的身份。HTTPS 是运行在 SSL/TLS 之上的 HTTP 协议,SSL/TLS 运行在 TCP 之上。所有传输的内容都经过加密,加密采用对称加密,但对称加密的密钥用服务器方的证书进行了非对称加密。所以说,HTTP 安全性没有 HTTPS 高,但是 HTTPS 比 HTTP 耗费更多服务器资源

    • HTTP 运行在 TCP 之上,所有信息是明文传输,客户端和服务器端都无法验证对方的身份,存在安全风险的问题。HTTPS 则解决 HTTP 不安全的缺陷,在 TCP 和 HTTP 传输层之间加入入 SSL/TLS 安全协议,使得报文能够加密传输(SSL/TLS 运行在 TCP 之上。所有传输的内容都经过加密,加密采用对称加密,但对称加密的密钥用服务器方的证书进行了非对称加密)。
      • HTTP 连接建立相对简单,TCP 三次握手之后便可进行 HTTP 的报文传输。而 HTTPS 在 TCP 三次握手之后,还需要进行 SSL/TLS 的握手过程,才可进入加密报文传输,HTTPS 比 HTTP 耗费更多服务器资源
      • HTTPS 协议需要向 CA (证书权威机构)申请数字证书,来保证服务器的身份是可信的。
  • SEO(搜索引擎优化):搜索引擎通常会更青睐使用 HTTPS 协议的网站,因为 HTTPS 能够提供更高的安全性和用户隐私保护。使用 HTTPS 协议的网站在搜索结果中可能会被优先显示,从而对 SEO 产生影响。

image-20241024183341752

HTTPS 的原理?

HTTPS 的核心—SSL/TLS 协议

image-20241024183450120

加密流程按图中的序号分为:

  1. 客户端请求 HTTPS 网址,然后连接到 server 的 443 端口 (HTTPS 默认端口,类似于 HTTP 的80端口)。
  2. 采用 HTTPS 协议的服务器必须要有一套数字 CA (Certification Authority)证书。颁发证书的同时会产生一个私钥和公钥。私钥由服务端自己保存,不可泄漏。公钥则是附带在证书的信息中,可以公开的。证书本身也附带一个证书电子签名,这个签名用来验证证书的完整性和真实性,可以防止证书被篡改。
  3. 服务器响应客户端请求,将证书传递给客户端,证书包含公钥和大量其他信息,比如证书颁发机构信息,公司信息和证书有效期等。
  4. 客户端解析证书并对其进行验证。如果证书不是可信机构颁布,或者证书中的域名与实际域名不一致,或者证书已经过期,就会向访问者显示一个警告,由其选择是否还要继续通信。

如果证书没有问题,客户端就会从服务器证书中取出服务器的公钥A。然后客户端还会生成一个随机码 KEY,并使用公钥A将其加密。

  1. 客户端把加密后的随机码 KEY 发送给服务器,作为后面对称加密的密钥。
  2. 服务器在收到随机码 KEY 之后会使用私钥B将其解密。经过以上这些步骤,客户端和服务器终于建立了安全连接,完美解决了对称加密的密钥泄露问题,接下来就可以用对称加密愉快地进行通信了。
  3. 服务器使用密钥 (随机码 KEY)对数据进行对称加密并发送给客户端,客户端使用相同的密钥 (随机码 KEY)解密数据。
  4. 双方使用对称加密愉快地传输所有数据。

HTTP1 到 HTTP3 的工程优化

这里也推荐一个视频简述从HTTP1到HTTP3协议的发展史

HTTP/1.0和HTTP/1.1的区别?

在这里插入图片描述

  • 连接方式:HTTP/1.0 为短连接,HTTP 1.1支持长连接(Persistent Connection)和请求的流水线(Pipelining)处理,在一个TCP连接上可以传送多个HTTP请求和响应,减少了建立和关闭连接的消耗和延迟,在HTTP1.1中默认开启Connection: keep-alive,一定程度上弥补了HTTP1.0每次请求都要创建连接的缺点。

  • 状态响应码 : HTTP/1.1 中新加入了大量的状态码,光是错误响应状态码就新增了 24 种。比如说,

    • 100 (Continue)——在请求大资源前的预热请求
      • 206 (Partial Content)——范围请求的标识码
      • 409 (Conflict)——请求与当前资源的规定冲突
      • 410 (Gone)——资源已被永久转移,而且没有任何已知的转发地址。
  • **缓存处理:**在HTTP1.0中主要使用header里的If-Modified-Since,Expires来做为缓存判断的标准,HTTP1.1则引入了更多的缓存控制策略,例如 Entity tag,If-Unmodified-Since, If-Match, If-None-Match 等更多可供选择的缓存头来控制缓存策略。

  • **带宽优化及网络连接的使用:**HTTP1.0中,存在一些浪费带宽的现象,例如客户端只是需要某个对象的一部分,而服务器却将整个对象送过来了,并且不支持断点续传功能,HTTP1.1则在请求头引入了range头域,它允许只请求资源的某个部分,即返回码是206(Partial Content),这样就方便了开发者自由的选择以便于充分利用带宽和连接。

  • **Host头处理:**在HTTP1.0中认为每台服务器都绑定一个唯一的IP地址,因此,请求消息中的URL并没有传递主机名(hostname)。但随着虚拟主机技术的发展,在一台物理服务器上可以存在多个虚拟主机(Multi-homed Web Servers),并且它们共享一个IP地址。HTTP1.1的请求消息和响应消息都应支持Host头域,且请求消息中如果没有Host头域会报告一个错误(400 Bad Request)。

HTTP/1.1和HTTP/2.0的区别?

image-20241024184033234

  • **多路复用(Multiplexing):**HTTP/1.1 使用串行方式,每个请求和响应都需要独立的连接,而浏览器为了控制资源会有 6-8 个 TCP 连接都限制。HTTP/2.0 在同一连接上可以同时传输多个请求和响应(可以看作是 HTTP/1.1 中长链接的升级版本),互不干扰。这使得 HTTP/2.0 在处理多个请求时更加高效,减少了网络延迟和提高了性能。(连接共享,即每一个request都是用作连接共享机制的。一个request对应一个id,这样一个连接上可以有多个request,每个连接的request可以随机的混杂在一起,接收方可以根据request的 id将request再归属到各自不同的服务端请求里面)

    • HTTP/2.0 的多路复用使得不同的请求可以共用一个 TCP 连接,避免建立多个连接带来不必要的额外开销,而 HTTP/1.1 中的每个请求都会建立一个单独的连接

image-20241024184051414

  • 二进制帧(Binary Frames):HTTP/1.1是基于文本格式的报文。基于文本协议的格式解析存在天然缺陷,文本的表现形式有多样性,要做到健壮性考虑的场景必然很多,HTTP/2.0 使用二进制帧进行数据传输,二进制帧更加紧凑和高效,减少了传输的数据量和带宽消耗。

  • **头部压缩(Header Compression):**HTTP/1.1 支持 Body 压缩,Header不支持压缩,HTTP1.1的头部(header)带有大量信息,而且每次都要重复发送;HTTP/2.0 支持使用encoder 对 Header 压缩,使用了专门为Header压缩而设计的 HPACK 算法,减少了网络开销,通讯双方各自 cache 一份 header fields 表,既避免了重复 header 的传输,又减小了需要传输的大小。

  • **服务器推送(Server Push):**HTTP/1.1 需要客户端自己发送请求来获取相关资源。HTTP/2.0 支持服务器推送,可以在客户端请求一个资源时,将其他相关资源一并推送给客户端,从而减少了客户端的请求次数和延迟

HTTP/2.0和HTTP/3.0的区别?

image-20241024184126878

  • 传输协议:HTTP/2.0 是基于 TCP 协议实现的,HTTP/3.0 新增了 QUIC(Quick UDP Internet Connections) 协议来实现可靠的传输,提供与 TLS/SSL 相当的安全性,具有较低的连接和传输延迟。你可以将 QUIC 看作是 UDP 的升级版本,在其基础上新增了很多功能比如加密、重传等等。HTTP/3.0 之前名为 HTTP-over-QUIC,从这个名字中我们也可以发现,HTTP/3 最大的改造就是使用了基于 UDP 的 QUIC 协议。
  • 连接建立:HTTP/2.0 需要经过经典的 TCP 三次握手过程(由于安全的 HTTPS 连接建立还需要 TLS 握手,共需要大约 3 个 RTT)。由于 QUIC 协议的特性(TLS 1.3,TLS 1.3 除了支持 1 个 RTT 的握手,还支持 0 个 RTT 的握手)连接建立仅需 0-RTT 或者 1-RTT。这意味着 QUIC 在最佳情况下不需要任何的额外往返时间就可以建立新连接。
  • 队头阻塞:HTTP/2.0 多请求复用一个 TCP 连接,一旦发生丢包,就会阻塞住所有的 HTTP 请求。由于 QUIC 协议的特性,HTTP/3.0 在一定程度上解决了队头阻塞(Head-of-Line blocking, 简写:HOL blocking)问题,一个连接建立多个不同的数据流,这些数据流之间独立互不影响,某个数据流发生丢包了,其数据流不受影响(本质上是多路复用+轮询)。
  • **错误恢复:**HTTP/3.0 具有更好的错误恢复机制,当出现丢包、延迟等网络问题时,可以更快地进行恢复和重传。而 HTTP/2.0 则需要依赖于 TCP 的错误恢复机制。
  • 安全性:HTTP/2.0 和 HTTP/3.0 在安全性上都有较高的要求,支持加密通信,但在实现上有所不同。HTTP/2.0 使用 TLS 协议进行加密,而 HTTP/3.0 基于 QUIC 协议,包含了内置的加密和身份验证机制,可以提供更强的安全性。

image-20241024184144034

HTTP 基于 TCP 还是 UDP?

HTTP/3.0 之前是基于 TCP 协议的,而 HTTP/3.0 将弃用 TCP,改用 基于 UDP 的 QUIC 协议

​ 此变化解决了 HTTP/2 中存在的队头阻塞问题。队头阻塞是指在 HTTP/2.0 中,多个 HTTP 请求和响应共享一个 TCP 连接,如果其中一个请求或响应因为网络拥塞或丢包而被阻塞,那么后续的请求或响应也无法发送,导致整个连接的效率降低。这是由于 HTTP/2.0 在单个 TCP 连接上使用了多路复用,受到 TCP 拥塞控制的影响,少量的丢包就可能导致整个 TCP 连接上的所有流被阻塞。HTTP/3.0 在一定程度上解决了队头阻塞问题,一个连接建立多个不同的数据流,这些数据流之间独立互不影响,某个数据流发生丢包了,其数据流不受影响(本质上是多路复用+轮询)。

​ 除了解决队头阻塞问题,HTTP/3.0 还可以减少握手过程的延迟。在 HTTP/2.0 中,如果要建立一个安全的 HTTPS 连接,需要经过 TCP 三次握手和 TLS 握手:

  1. TCP 三次握手:客户端和服务器交换 SYN 和 ACK 包,建立一个 TCP 连接。这个过程需要 1.5 个 RTT(round-trip time),即一个数据包从发送到接收的时间。
  2. TLS 握手:客户端和服务器交换密钥和证书,建立一个 TLS 加密层。这个过程需要至少 1 个 RTT(TLS 1.3)或者 2 个 RTT(TLS 1.2)。

​ 所以,HTTP/2.0 的连接建立就至少需要 2.5 个 RTT(TLS 1.3)或者 3.5 个 RTT(TLS 1.2)。而在 HTTP/3.0 中,使用的 QUIC 协议(TLS 1.3,TLS 1.3 除了支持 1 个 RTT 的握手,还支持 0 个 RTT 的握手)连接建立仅需 0-RTT 或者 1-RTT。这意味着 QUIC 在最佳情况下不需要任何的额外往返时间就可以建立新连接

解释一下HTTP长连接和短连接?

在HTTP/1.0中,默认使用的是短连接。也就是说,浏览器和服务器每进行一次HTTP操作,就建立一次连接,但任务结束就中断连接。如果客户端浏览器访问的某个HTML或其他类型的 Web页中包含有其他的Web资源,如JavaScript文件、图像文件、CSS文件等;当浏览器每遇到这样一个Web资源,就会建立一个HTTP会话。

​ 但从 HTTP/1.1起,默认使用长连接,用以保持连接特性。使用长连接的HTTP协议,会在响应头有加入这行代码:Connection:keep-alive

​ 在使用长连接的情况下,当一个网页打开完成后,客户端和服务器之间用于传输HTTP数据的 TCP连接不会关闭,如果客户端再次访问这个服务器上的网页,会继续使用这一条已经建立的连接。Keep-Alive不会永久保持连接,它有一个保持时间,可以在不同的服务器软件(如Apache)中设定这个时间。实现长连接要客户端和服务端都支持长连接。

HTTP协议的长连接和短连接,实质上是TCP协议的长连接和短连接。

HTTP 是不保存状态的协议, 如何保存用户状态?

​ HTTP 是一种不保存状态,即无状态(stateless)协议。也就是说 HTTP 协议自身不对请求和响应之间的通信状态进行保存。那么我们如何保存用户状态呢?Session 机制的存在就是为了解决这个问题,Session 的主要作用就是通过服务端记录用户的状态。典型的场景是购物车,当你要添加商品到购物车的时候,系统不知道是哪个用户操作的,因为 HTTP 协议是无状态的。服务端给特定的用户创建特定的 Session 之后就可以标识这个用户并且跟踪这个用户了(一般情况下,服务器会在一定时间内保存这个 Session,过了时间限制,就会销毁这个 Session)。

​ 在服务端保存 Session 的方法很多,最常用的就是内存和数据库(比如是使用内存数据库 redis 保存)。既然 Session 存放在服务器端,那么我们如何实现 Session 跟踪呢?大部分情况下,我们都是通过在 Cookie 中附加一个 Session ID 来方式来跟踪。

Cookie 被禁用怎么办? (具体看Cookie 与 Session部分)

​ 最常用的就是利用 URL 重写把 Session ID 直接附加在 URL 路径的后面

URI 和 URL 的区别是什么?

  • URI(Uniform Resource Identifier) 是统一资源标志符,可以唯一标识一个资源。
  • URL(Uniform Resource Locator) 是统一资源定位符,可以提供该资源的路径。它是一种具体的 URI,即 URL 可以用来标识一个资源,而且还指明了如何 locate 这个资源。

URI 的作用像身份证号一样,URL 的作用更像家庭住址一样。URL 是一种具体的 URI,它不仅唯一标识资源,而且还提供了定位该资源的信息。

HTTP 常用的请求方式?

为了方便记忆,可以将PUT、DELETE、POST、GET理解为客户端对服务端的增删改查。

  • PUT:上传文件,向服务器添加数据,可以看作增
  • DELETE:删除文件
  • POST:传输数据,向服务器提交数据,对服务器数据进行更新。
  • GET:获取资源,查询服务器资源
方法作用
GET获取资源
POST传输实体主体
PUT上传文件
DELETE删除文件
HEAD和GET方法类似,但只返回报文首部,不返回报文实体主体部分
PATCH对资源进行部分修改
OPTIONS查询指定的URL支持的方法
CONNECT要求用隧道协议连接代理
TRACE服务器会将通信路径返回给客户端

GET 和 POST 的区别

🍇知乎讨论:https://www.zhihu.com/question/28586791

🍈使用上的区别

  • GET使用URL或Cookie传参,而POST将数据放在BODY中”,这个是因为HTTP协议用法的约定。

  • 规范(主要区别):**在规范中,定义 GET 请求是用来获取资源的,也就是进行查询操作的;而 POST 请求是用来传输实体对象的,因此会使用 POST 来进行添加、修改和删除等操作。

  • 格式:GET 请求的参数通常放在 URL 中或Cookie传参,形成查询字符串(querystring),而 POST 请求的参数通常放在请求体(body)中,可以有多种编码格式,如 application/x-www-form-urlencoded、multipart/form-data、application/json 等

  • 数据限制:GET方式提交的数据受到浏览器和服务器的长度限制,则POST 请求的 body 大小则则没有明确的限制

  • 缓存:由于 GET 请求是幂等的,它可以被浏览器或其他中间节点(如代理、网关)缓存起来,以提高性能和效率。而 POST 请求则不适合被缓存,因为它可能有副作用,每次执行可能需要实时的响应。

  • 安全性:GET 请求和 POST 请求如果使用 HTTP 协议的话,那都不安全,因为 HTTP 协议本身是明文传输的,必须使用 HTTPS 协议来加密传输数据。另外,GET 请求相比 POST 请求更容易泄露敏感数据,因为 GET 请求的参数通常放在 URL 中

  • GET产生一个TCP数据包;POST产生两个TCP数据包。对于GET方式的请求,浏览器会把请求头和请求体一并发送出去;而对于POST,浏览器先发送请求头,服务器响应100 continue,浏览器再发送请求体。

  • GET请求参数会被完整保留在浏览器历史记录里,而POST中的参数不会被保留。

  • GET 请求可以直接进行回退和刷新,不会对用户和程序产生任何影响;而 POST 请求如果直接回滚和刷新将会把数据再次提交。

🍉本质区别

GET和POST最大的区别主要是GET请求是幂等性的,即多次重复执行不会改变资源的状态;POST请求不是,即每次执行可能会产生不同的结果或影响资源的状态。这个是它们本质区别。

幂等性是指一次和多次请求某一个资源应该具有同样的副作用。简单来说意味着对同一URL的多个请求应该返回同样的结果。

Cookie 与 Session

认证授权基础概念详解

什么是 Cookie 和 Session ?

由于HTTP协议是无状态的协议,需要用某种机制来识具体的用户身份,用来跟踪用户的整个会话。常用的会话跟踪技术是Cookie 和 Session。

♨️简单来说:Cookie 存放在客户端,一般用来保存用户信息

Cookie是服务器发送到用户浏览器并保存在本地的一小块数据,它会在浏览器下次向同一服务器再发起请求时被携带并发送到服务器上。通常,它用于告知服务端两个请求是否来自同一浏览器,如保持用户的登录状态。Cookie 使基于无状态的 HTTP 协议记录稳定的状态信息成为了可能。

简要解释一下原理:

Cookie 的一些应用案例:

  1. 我们在 Cookie 中保存已经登录过的用户信息,下次访问网站的时候页面可以自动帮你登录的一些基本信息给填了。除此之外,Cookie 还能保存用户首选项,主题和其他设置信息。
  2. 使用 Cookie 保存 SessionId 或者 Token ,向后端发送请求的时候带上 Cookie,这样后端就能取到 Session 或者 Token 了。这样就能记录用户当前的状态了,因为 HTTP 协议是无状态的。
  3. Cookie 还可以用来记录和分析用户行为。举个简单的例子你在网上购物的时候,因为 HTTP 协议是没有状态的,如果服务器想要获取你在某个页面的停留状态或者看了哪些商品,一种常用的实现方式就是将这些信息存放在 Cookie

Cookie 主要用于以下三个方面:

  • 会话状态管理(如用户登录状态、购物车、游戏分数或其它需要记录的信息)
  • 个性化设置(如用户自定义设置、主题等)
  • 浏览器行为跟踪(如跟踪分析用户行为等)

♨️Session 的主要作用就是通过服务端记录用户的状态。

Session 代表着服务器和客户端一次会话的过程。Session 对象存储特定用户会话所需的属性及配置信息。这样,当用户在应用程序的 Web 页之间跳转时,存储在 Session 对象中的变量将不会丢失,而是在整个用户会话中一直存在下去。 当Session 超时失效时会话结束

简要解释一下原理:

Session 的应用案例:

典型的场景是购物车,当你要添加商品到购物车的时候,系统不知道是哪个用户操作的,因为 HTTP 协议是无状态的。服务端给特定的用户创建特定的 Session 之后就可以标识这个用户并且跟踪这个用户了。

Cookie 数据保存在客户端(浏览器端),Session 数据保存在服务器端。相对来说 Session 安全性更高。如果使用 Cookie 的一些敏感信息不要写入 Cookie 中,最好能将 Cookie 信息信息加密然后使用到的时候再去服务器端解密(这部分可以具体看 “3.3、Cookie 和 Session 有什么区别?”)

如何使用 Session-Cookie 方案进行身份验证?

很多时候我们都是通过 SessionID 来实现特定的用户,SessionID 一般会选择存放在 Redis 中。举个例子:

  1. 用户成功登陆系统,然后返回给客户端具有 SessionID 的 Cookie 。
  2. 当用户向后端发起请求的时候会把 SessionID 带上,这样后端就知道你的身份状态了。

关于这种认证方式更详细的过程如下:

image-20241024184625524

  1. 用户向服务器发送用户名、密码、验证码用于登陆系统。
  2. 服务器验证通过后,服务器为用户创建一个 Session,并将 Session 信息存储起来。
  3. 服务器向用户返回一个 SessionID,写入用户的 Cookie。
  4. 当用户保持登录状态时,Cookie 将与每个后续请求一起被发送出去。
  5. 服务器可以将存储在 Cookie 上的 SessionID 与存储在内存中或者数据库中的 Session 信息进行比较,以验证用户的身份,返回给用户客户端响应信息的时候会附带用户当前的状态。

使用 Session 的时候需要注意下面几个点:

  • 依赖 Session 的关键业务一定要确保客户端开启了 Cookie。
  • 注意 Session 的过期时间。

Cookie 和 Session 有什么区别?

  • 作用范围不同,Cookie 保存在客户端,Session 保存在服务器端。

  • 有效期不同,Cookie 可设置为长时间保持,比如我们经常使用的默认登录功能,Session 一般失效时间较短,Session 超时会失效。

  • 隐私策略不同,Cookie 存储在客户端,容易被窃取;Session 存储在服务端,安全性相对 Cookie 要好一些。

  • 存储大小不同, 单个 Cookie 保存的数据不能超过 4K;可存储数据远高于 Cookie,但出于对服务器的性能考虑,Session 内不要存放过多的数据,并且需要设置 Session 删除机制。

  • 存取方式的不同,Cookie 只能保存 ASCII,Session 可以存任意数据类型,一般情况下我们可以在 Session 中保持一些常用变量信息,比如说 UserId 等。

  • 会话机制不同

如何考虑分布式 Session 问题?(多服务器节点下 Session-Cookie 方案如何做?)

​ Session-Cookie 方案在单体环境是一个非常好的身份认证方案。但是,当服务器水平拓展成多节点时,Session-Cookie 方案就要面临挑战了。

​ 假如我们部署了两份相同的服务 A,B,用户第一次登陆的时候 ,Nginx 通过负载均衡机制将用户请求转发到 A 服务器,此时用户的 Session 信息保存在 A 服务器。结果,用户第二次访问的时候 Nginx 将请求路由到 B 服务器,由于 B 服务器没有保存 用户的 Session 信息,导致用户需要重新进行登陆。

我们应该如何避免上面这种情况的出现呢?

有几个方案可供参考:

  1. 每一个服务器保存的 Session 信息都是互相同步的,也就是说每一个服务器都保存了全量的 Session 信息。每当一个服务器的 Session 信息发生变化,我们就将其同步到其他服务器。这种方案成本太大,并且,节点越多时,同步成本也越高。
  2. 单独使用一个所有服务器都能访问到的数据节点(比如缓存)来存放 Session 信息。为了保证高可用,数据节点尽量要避免是单点。
  3. Spring Session 是一个用于在多个服务器之间管理会话的项目。它可以与多种后端存储(如 Redis、MongoDB 等)集成,从而实现分布式会话管理。通过 Spring Session,可以将会话数据存储在共享的外部存储中,以实现跨服务器的会话同步和共享。

分布式 Session 一般会有以下几种解决方案:

  • 客户端存储: 直接将信息存储在cookie中,cookie是存储在客户端上的一小段数据,客户端通过http协议和服务器进行cookie交互,通常用来存储一些不敏感信息

  • Nginx ip_hash 策略: 服务端使用 Nginx 代理,每个请求按访问 IP 的 hash 分配给同一个服务器处理,这样来自同一 IP 固定访问一个后台服务器,避免了在服务器 A 创建 Session,第二次分发到服务器 B 的现象。但是这样的话,每个服务器都保存了一部分用户的 Session 信息。服务器宕机,其保存的所有 Session 信息就完全丢失了。

  • Session 复制: 任何一个服务器上的 Session 发生改变(增删改),该节点会把这个 Session 的所有内容序列化,然后广播给所有其它节点。

共享 Session: 服务端无状态话,将用户的 Session 等信息使用缓存中间件(如Redis)来统一管理,保障分发到每一个服务器的响应结果都一致。

建议采用共享 Session的方案。

如果没有 Cookie 的话 Session 还能用吗?

这是一道经典的面试题!

一般是通过 Cookie 来保存 SessionID ,假如你使用了 Cookie 保存 SessionID 的方案的话, 如果客户端禁用了 Cookie,那么 Session 就无法正常工作。

但是,并不是没有 Cookie 之后就不能用 Session 了,比如你可以将 SessionID 放在请求的 url 里面 https://javaguide.cn/?Session_id=xxx 。这种方案的话可行,但是安全性和用户体验感降低。当然,为了安全你也可以对 SessionID 进行一次加密之后再传入后端

如何在项目中使用 Cookie 呢?

如何详细使用Cookie,可以看这个文档How to use cookies in Spring Boot

设置Cookie 返回给客户端

@GetMapping("/change-username")
public String setCookie(HttpServletResponse response) {
    // 创建一个 cookie
    Cookie cookie = new Cookie("username", "Jovan");
    //设置 cookie过期时间
    cookie.setMaxAge(7 * 24 * 60 * 60); // expires in 7 days
    //添加到 response 中
    response.addCookie(cookie);

    return "Username is changed!";
}

使用 Spring 框架提供的 @CookieValue 注解获取特定的 cookie 的值

// 使用 Spring 框架提供的 @CookieValue 注解获取特定的 cookie 的值
@GetMapping("/")
public String readCookie(@CookieValue(value = "username", defaultValue = "Atta") String username) {
    return "Hey! My username is " + username;
}

读取所有的 Cookie 值

// 读取所有的 Cookie 值
@GetMapping("/all-cookies")
public String readAllCookies(HttpServletRequest request) {

    Cookie[] cookies = request.getCookies();
    if (cookies != null) {
        return Arrays.stream(cookies)
                .map(c -> c.getName() + "=" + c.getValue()).collect(Collectors.joining(", "));
    }

    return "No cookies";
}

能不能直接在应用层把数据交给网络层

如果直接给IP层,就会导致数据包无法交给指定的进程

了解 Socket 吗?什么是 socket?

image-20241024185209940


http://www.kler.cn/news/363531.html

相关文章:

  • GO excelize 读取excel进行时间类型转换(自动转换)
  • 安全见闻(4)——开阔眼界,不做井底之蛙
  • 批量合并PDF 文件的 5 大解决方案
  • Redis底层和缓存雪崩,击穿,穿透
  • Claude 3.5:人工智能的新突破
  • 详解如何使用WGCLOUD监测日志文件
  • 深入浅出理解BLE AUDIO CSIS
  • 深入探究安卓 Binder 机制及其应用
  • 学习虚幻C++开发日志——TSet
  • Oracle 更换监听端口
  • 大模型涌现判定
  • 每天五分钟深度学习pytorch:L1和L2范数、L1和L2归一化
  • Spring面试题
  • Deformable Detr
  • 几张图就让你掌握InnoDB 存储引擎底层逻辑架构
  • linux_c IPC消息队列练习
  • OpenHarmony 目前所有体系详细介绍
  • Git的多人协作模式与企业级开发模型
  • 【NodeJS】NodeJS+mongoDB在线版开发简单RestfulAPI (三):Cors的设置及.env文件的设置
  • 2024年03月中国电子学会青少年软件编程(图形化)等级考试试卷(四级)答案 + 解析
  • java字段判空方法Assert.hasText()详细讲解
  • 智慧城市垃圾分类可视化
  • 提示词高级阶段学习day3.1什么是结构化 Prompt ?
  • 算法魅力-双指针之滑动窗口的叛逆
  • 吴恩达深度学习笔记:卷积神经网络(Foundations of Convolutional Neural Networks)3.9-3.10
  • 【vue + mockjs】Mockjs——数据接口模拟