地址栏输入 url 后发生了什么

最近面试很多问题都跟这个问题息息相关,所以我决定写一篇文章好好梳理一下,借这个问题发散一下,将面试中可能会涉及到的知识点都尽量覆盖到。

我们以 http://www.baidu.com 为例

1. DNS解析

Domain Name System,域名系统,简而言之就是将我们的域名翻译为 IP 地址。

DNS 服务器分为四类,分别是根域名服务器、顶级域名服务器、权威域名服务器、本地域名服务器。

dns解析过程

dns解析详细过程

Tips:

  1. CNAME 作用:允许您将多个名字映射到同一台计算机,相当于域名的别名,好处是当域名发生变化时,用户侧的访问方式可以不发生变化。

  2. 常见的 DNS 记录类型:

    A : 地址记录(Address),返回域名对应的 IP 地址;

    NS : 域名解析服务器记录(Name Server),如果要将子域名指定某个域名服务器来解析,需要设置NS记录。

    AAAA : 对应的 IP 地址为 IPV6。

2. HTTP 连接

http -> https

这里是 http 的访问方式,但是我们知道,我们在浏览器输入 http://www.baidu.com 之后,按下回车键,地址会变为 https://www.baidu.com,看一下 network,我们会发现状态码是 302,那这里到底做了什么呢?

由于我们键入的是 http,所以浏览器会首先找到服务器的80端口,进行 tcp 连接,然后服务器会返回一个 301/302「下文会普及状态码」,表示重定向,同时在服务器响应头还会添加HTTP-Strict-Transport-Security「简称 HSTS」,里面有 max-age,用户访问时,服务器种下这个头,下次如果使用 http 访问,只要 max-age 未过期「客户端检验」,客户端会进行内部跳转,可以看到 307 Redirect Internel 的响应码。然后就直接变成和 443 端口建立连接,走 https 连接。

所以,下次看到状态码如果是307,不要惊讶,这说明对应的网站的 max-age 还没到期,浏览器内部进行了跳转,直接和服务器的443端口进行连接了。

状态码

Tip:

状态码-1

状态码-2

状态码-3

https 连接过程

ssl的全过程

运行机制详解

为何需要数字证书

https = tls/ssl + http,我们来看一下 tls 所在的层级:

七层常用协议

需要明确一点的是,https 其实主要是两个过程:

  1. 验证过程,使用 RSA 非对称加密 + Hash 算法;
  2. 传输过程,使用 AES 对称加密。

我们首先来看第一个过程:验证过程,分为了 4 步:

  1. 客户端给出版本协议号、一个客户端生成的随机数(random)以及客户端支持的加密方式;
  2. 服务器端确认双方使用的加密方式和加密通信协议版本,并给出数字证书「包含了服务器的公钥」,以及服务器生成的一个随机数(random);
  3. 客户端确认数字证书的有效性,然后生成一个新的随机数,并且这个随机数使用数字证书中的公钥加密,发给服务器,客户端握手结束通知,表示客户端的握手阶段已经结束。这一项同时也是前面发送的所有内容的hash值,用来供服务器校验。
  4. 服务器使用自己的私钥,进行解密。然后通知客户端握手阶段结束,同时将之前的信息 Hash 后发给客户端,让客户端校验。

至此,验证过程就结束了,客户端会和服务器根据约定的加密方式,使用前面三个随机数,生成“对话密钥”,然后根据这个对话密钥进行对称加密,传输数据。

ssl验证过程-来自阮一峰老师

问题:

  1. 数字证书的意义是什么?没有数字证书会发生什么?

在四次握手中,如果没有数字证书,那么可能会出现中间人挟持的现象,如下图所示:

中间人挟持

我们详细阐述中间人获取对称密钥的过程:

  • 1、中间人在收到Server发给Client的公钥后,并没有发给客户端,而是将它保存起来,同时将中间人自己的公钥发给Client;
  • 2、Client使用中间人的公钥将对称密钥加密后发送出去;
  • 3、中间人截获到这个信息,由于是使用中间人的公钥加密的,因而使用它的私钥可以解密获取到对称密钥并保存;之后,中间人使用之前保存的Server的公钥将对称密钥加密发回给Server;
  • 4、此时,客户端、中间人、服务器都拥有了一样的对称密钥,后续客户端和服务器的所有加密数据,中间人都可以通过对称密钥解密出来。

那这个时候,就需要数字证书了,服务器首先生成公私钥,然后将公钥提供给相关机构(CA),CA将公钥放入数字证书并将数字证书颁布给服务器(其实主要就是利用CA的私钥给Server的公钥打上标签,由于私钥无法伪造,从而可保证唯一性),此时,即使中间人想伪造一个数字证书,但是由于CA不会给它颁发这个证书(因为它没有经营这个网站的资质嘛,所以CA的信誉、对申请者的审核、对自己私钥的保管这3点非常重要,任何一环出问题,都会导致中间人有机可乘)。或者中间人发送自己网站的数字证书,那么必然会不能通过校验,从而导致会话中断。

img

  1. 随机数的意义是什么?为什么需要三个随机数?

如果没有之前两个随机数,那被猜出来的可能性会很大。

“不管是客户端还是服务器,都需要随机数,这样生成的密钥才不会每次都一样。由于SSL协议中证书是静态的,因此十分有必要引入一种随机因素来保证协商出来的密钥的随机性。

对于RSA密钥交换算法来说,pre-master-key本身就是一个随机数,再加上hello消息中的随机,三个随机数通过一个密钥导出器最终导出一个对称密钥。

pre master的存在在于SSL协议不信任每个主机都能产生完全随机的随机数,如果随机数不随机,那么pre master secret就有可能被猜出来,那么仅适用pre master secret作为密钥就不合适了,因此必须引入新的随机因素,那么客户端和服务器加上pre master secret三个随机数一同生成的密钥就不容易被猜出了,一个伪随机可能完全不随机,可是是三个伪随机就十分接近随机了,每增加一个自由度,随机性增加的可不是一。”

  1. 如果握手阶段中断了,是否需要重新建立连接?

不需要,有 session ID 和 session ticket,session ID 优点是浏览器都支持,缺点是往往只保留在一台服务器上,如果客户端的请求发送到了另外一台服务器上,就无法恢复了,而 session ticket 就是用来解决这个问题的。

  1. 非对称加密除了 RSA,还有哪些?

RSA:由 RSA 公司发明,是一个支持变长密钥的公共密钥算法,需要加密的文件块的长度也是可变的。RSA在国外早已进入实用阶段,已研制出多种高速的RSA的专用芯片。

DSA(Digital Signature Algorithm):数字签名算法,是一种标准的 DSS(数字签名标准),严格来说不算加密算法。

ECC(Elliptic Curves Cryptography):椭圆曲线密码编码学。ECC和RSA相比,具有多方面的绝对优势,主要有:抗攻击性强。相同的密钥长度,其抗攻击性要强很多倍。计算量小,处理速度快。ECC总的速度比RSA、DSA要快得多。存储空间占用小。ECC的密钥尺寸和系统参数与RSA、DSA相比要小得多,意味着它所占的存贮空间要小得多。这对于加密算法在IC卡上的应用具有特别重要的意义。带宽要求低。当对长消息进行加解密时,三类密码系统有相同的带宽要求,但应用于短消息时ECC带宽要求却低得多。带宽要求低使ECC在无线网络领域具有广泛的应用前景。

  1. 对称加密除了 AES,还有哪些?

对称性加密算法有:AES、DES、3DES
用途:对称加密算法用来对敏感数据等信息进行加密

DES(Data Encryption Standard):数据加密标准,速度较快,适用于加密大量数据的场合。

3DES(Triple DES):是基于DES,对一块数据用三个不同的密钥进行三次加密,强度更高。

AES(Advanced Encryption Standard):高级加密标准,是下一代的加密算法标准,速度快,安全级别高;AES是一个使用128为分组块的分组加密算法,分组块和128、192或256位的密钥一起作为输入,对4×4的字节数组上进行操作。众所周之AES是种十分高效的算法,尤其在8位架构中,这源于它面向字节的设计。AES 适用于8位的小型单片机或者普通的32位微处理器,并且适合用专门的硬件实现,硬件实现能够使其吞吐量(每秒可以到达的加密/解密bit数)达到十亿量级。同样,其也适用于RFID系统。

  1. MD5、Hash 算不算加密算法?

不算,因为他们是单向的。

严格来说:MD5、sha-1只是散列算法,或者叫摘要算法,不能算加密算法。

也就是说,MD5 是不可逆的,你根本解不了,而对称非对称加密算法是可逆的,可以通过密文得到明文,也可以通过明文得到密文。

加密对应解密,即加密后的密文可以解密成明文,但是MD5无法从密文(散列值)反过来得到原文,即没有解密算法。

大家知道加密算法分为对称加密和非对称加密,不管对称加密和非对称加密,都是能够从密文解密得到明文的。从这点上讲MD5不是加密算法,更谈不上属于对称加密、非对称加密。所以不要再讨论MD5是属于对称加密、非对称加密了,MD5既不属于对称加密也不属于非对称加密,MD5根本就没法解密,也没有秘钥(加盐并不是秘钥),所以可以认为MD5不属于加密算法。

一些人认为MD5处理后看不到原文,即已经将原文加密,所以认为MD5属于加密算法。如果这么看的,那么求余也可以算加密算法了。

  1. 这三种加密方式的区别是什么?

加密技术通常分为两大类:”对称式”和”非对称式”。

对称性加密算法:对称式加密就是加密和解密使用同一个密钥。信息接收双方都需事先知道密匙和加解密算法且其密匙是相同的,之后便是对数据进行加解密了。对称加密算法用来对敏感数据等信息进行加密。

非对称算法:非对称式加密就是加密和解密所使用的不是同一个密钥,通常有两个密钥,称为”公钥”和”私钥”,它们两个必需配对使用,否则不能打开加密文件。发送双方A,B事先均生成一堆密匙,然后A将自己的公有密匙发送给B,B将自己的公有密匙发送给A,如果A要给B发送消息,则先需要用B的公有密匙进行消息加密,然后发送给B端,此时B端再用自己的私有密匙进行消息解密,B向A发送消息时为同样的道理。

散列算法:散列算法,又称哈希函数,是一种单向加密算法。在信息安全技术中,经常需要验证消息的完整性,散列(Hash)函数提供了这一服务,它对不同长度的输入消息,产生固定长度的输出。这个固定长度的输出称为原输入消息的”散列”或”消息摘要”(Message digest)。散列算法不算加密算法,因为其结果是不可逆的,既然是不可逆的,那么当然不是用来加密的,而是签名。

3. tcp 传输

我们知道,http 连接在传输层是通过 tcp 来实现的,所以我决定深挖一点,顺带回顾一下 tcp 常考的高频面试点。

三次握手

这个可能是面试中出现频率最高的问题了…

img

  1. 最开始的 Client 和 Server 都是处于 Closed,由于服务器端不知道要跟谁建立连接,所以其只能被动打开,然后监听端口,此时 Server 处于 Listen 状态;
  2. 而 Client 会主动打开,然后构建好 TCB 「SYN= 1,seq = x」,发送给服务器端,此时 Client 会将状态置为 SYN_SEND 「同步已发送」;
  3. 服务器端收到客户端发来的同步请求后,会将状态置为 SYN_RECV「同步已接收」,同时会构建好 TCB「SYN = 1,seq = y,ACK = 1,ack = x + 1」发送给客户端;
  4. 客户端接收到了服务器端发来的传输控制块之后,会将自己的状态改为 ESTABLISHED「建立连接」,然后发送确认报文(ACK= 1,seq = x + 1,ack = y + 1);
  5. 服务器端在收到了客户端发来的报文之后,也将状态置为 ESTABLISHED「建立连接」,至此,三次握手结束,当然在这里,可以带 tcp 报文段信息过来了,因为此时客户端已经可以保证是可靠的传输了,所以在这一端可以发送报文段了。

常见面试题:

  1. 为何不直接在第一次握手就带上报文段消息,非要第三次才可以带?

因为 TCP 是要保证数据的不丢失且可靠,如果在第一次就带上报文段消息,此次建立连接很有可能就会失败,那么就不能保证数据的不丢失了,在不可靠的机制上进行这种操作,换来的代价太大,每次发送报文段的资源也会增大,得不偿失;

而第三次握手的时候,客户端已经知道服务器端准备好了,所以只要告诉服务器端自己准备好了就okay了,所以此时带上报文段信息没有任何问题。

  1. 可不可以只握手两次?

不可以,三次握手主要是解决这样一个常见的问题,客户端发送了第一个请求连接并且没有丢失,只是因为在网络结点中滞留的时间太长了,由于TCP的客户端迟迟没有收到确认报文,以为服务器没有收到,此时重新向服务器发送这条报文,此后客户端和服务器经过两次握手完成连接,传输数据,然后关闭连接。此时此前滞留的那一次请求连接,网络通畅了到达了服务器,这个报文本该是失效的,但是,两次握手的机制将会让客户端和服务器再次建立连接,这将导致不必要的错误和资源的浪费。

如果采用的是三次握手,就算是那一次失效的报文传送过来了,服务端接受到了那条失效报文并且回复了确认报文,但是客户端不会再次发出确认。由于服务器收不到确认,就知道客户端并没有请求连接。

四次挥手

img

  1. 最开始客户端和服务器端都是 ESTABLISHED 的状态,然后客户端会主动关闭,而服务器端则是被动关闭。
  2. 客户端发送一个 FIN 报文段,seq = 结束的报文段序号 + 1「假设为 u」,告诉服务器端,客户端需要关闭了,此时将客户端的状态变为 FIN-WAIT-1,等待服务器端的反馈;
  3. 服务器在接收到了客户端发来的 FIN 包之后,会发一条 ack报文反馈给客户端,其中报文中包括 ACK = 1,seq = v,ack = u+1,告诉客户端收到了客户端要关闭的消息了,同时服务器端会通知应用进程需要关闭连接了,并将自己的状态置为 CLOSE-WAIT;
  4. 由于服务器端可能还有一些数据没处理完,所以需要一段时间的等待,当处理完了之后,会再发一条报文,其中 FIN = 1,ACK = 1,seq = w,ack = u+1,告知客户端,服务器端现在可以关闭了,并将服务器端的状态由 CLOSE-WAIT 变为 LAST-ACK;
  5. 客户端在收到了服务器端发来的消息之后,会发一条ack报文「ACK = 1,seq = u+1,ack = w+1」回去,告知服务器端,客户端已经知道了你准备好关闭了,此时会将客户端的状态由 FIN-WAIT-2 置为 TIME-WAIT,在两个最长报文段传输时间过后,会自动将客户端的状态由 TIME-WAIT 置为 CLOSED。
  6. 服务器端收到消息之后,就将状态由 LAST-ACK 置为了 CLOSED,自此,四次挥手全部结束。

常见面试题:

  1. 为什么不能三次挥手?
  • 首先如果去掉最后一次挥手,那么服务器端就不知道自己要关闭的报文有没有传输成功,可能半路上就失败了,但是此时客户端不知道,导致客户端一直在等待服务器关闭,但是此时服务器端直接就关闭了;
  • 如果中间的两次挥手合并,那是肯定不行的,因为此时服务器端可能还有很多报文未处理完,此时直接关闭肯定会对传输有很大影响。
  1. 为什么客户端在收到 服务器端发来的 FIN 包后要等 2 个最长报文段传输时间?

防止最后自己发去的 ack 没传送到服务器,如果服务器没收到客户端的 ack,肯定会选择重发一次 FIN 包,那么此时如果客户端已经关闭了,客户端就不能再发 ack 确认收到了,至于为何是 2 个报文段传输时间,因为刚好一去一回嘛… 2 个最长报文传输时间没有 FIN 包发来,就说明服务器已经关闭了,客户端也就可以安心关闭了。

  1. 什么情况下会导致服务器有大量处于 close_wait 状态的 tcp 连接?会造成什么问题?如何解决?

正常来说,close_wait 状态的出现是在接收到了客户端的 FIN 包,但是服务器端还未 close 的状态,一般情况下出现大量处于该状态的 tcp 连接原因就是服务器端没有主动去关闭连接,可能有忘写 close()、I/O线程被意外阻塞等等,这样可能会导致socket资源被打满,因为端口是有限的啊,解决方案就是找到为何服务器没有 close 的原因。

  1. 什么情况下客户端会存在大量 time_wait 状态的 tcp 连接?为何需要 time_wait?会造成什么问题?如何解决?

首先需要明确一点,处于 time_wait 状态的 tcp 连接是不能够被复用的,必须等其变为 close 状态才能复用。

那什么情况下客户端会有大量的 time_wait 状态的 tcp 连接呢?当然是突然有大量连接的时候啊,因为 time_wait 的时间是 2MSL,也就是 60 s,如果在这 60 s 内有非常多的连接,自然就会产生大量处于该状态的 tcp 连接。

那没有 time_wait 行不行啊?

答案是不可以!原因有两点:

  • 1.允许老的重复报文分组在网络中消逝。
  • 2.保证TCP全双工连接的正确关闭。

第一个理由是假如我们在192.168.1.1:500039.106.170.184:6000建立一个TCP连接,一段时间后我们关闭这个连接,再基于相同插口建立一个新的TCP连接,这个新的连接称为前一个连接的化身。老的报文很有可能由于某些原因迟到了,那么新的TCP连接很有可能会将这个迟到的报文认为是新的连接的报文,而导致数据错乱。为了防止这种情况的发生TCP连接必须让TIME_WAIT状态持续2MSL,在此期间将不能基于这个插口建立新的化身,让它有足够的时间使迟到的报文段被丢弃。

第二个理由是因为如果主动关闭方最终的ACK丢失,那么服务器将会重新发送那个FIN,以允许主动关闭方重新发送那个ACK。要是主动关闭方不维护2MSL状态,那么主动关闭将会不得不响应一个RST报文段,而服务器将会把它解释为一个错误,导致TCP连接没有办法完成全双工的关闭,而进入半关闭状态。

那为何一定要 2MSL呢,第一个理由其实 1MSL 就可以了啊?

是的,第一个理由的确 1 MSL 就可以了,但是第二个理由是需要 2 MSL,因为首先服务器要通过 1 MSL判断客户端的 close 是否正确到达,如果没有正确到达,需要重传,那此时客户端也是需要 1 MSL 获得重传的 FIN 包的,所以需要 2MSL。

那大量的 time_wait 会造成什么问题呢?

TIME_WAIT socket对于系统资源的消耗影响非常小,而真正需要考虑因为TIME_WAIT多而触碰到限制的是如下几个方面:

  • 源端口数量 (net.ipv4.ip_local_port_range)
  • TIME_WAIT bucket 数量 (net.ipv4.tcp_max_tw_buckets)
  • 文件描述符数量 (max open files)

那如何解决呢?

  • 方案一:使用 TCP 长连接替代短连接
  • 方案二:增加端口数量、使用 net.ipv4.tcp_tw_reuse 选项,通过 TCP 的时间戳选项允许内核重用处于 TIME_WAIT 状态的 TCP 连接;
  • 方案三:开启tw回收: net.ipv4.tcp_tw_recycle = 1,直接回收。

tcp 和 udp

这个也是面试中常问的。

tcp:面向连接的传输控制协议,提供了一条全双工的可靠传输信道,主要解决传输可靠、有序、无丢失和不重复的问题,主要特点有:

  1. 面向连接;
  2. 每一条 tcp 连接都是点对点;
  3. 提供可靠的交付服务,保证传送数据的无差错、不丢失、不重复且有序;
  4. 提供全双工通信,两端都设有接收缓存和发送缓存;
  5. 面向字节流。

udp:无连接的非可靠的传输控制协议,在 IP 层上提供两个附加功能:多路复用和对数据的错误检查。主要特点:

  1. 无连接;
  2. 提供最大努力交付,但是不提供可靠的交付服务,没有流量控制、拥塞控制,也是点对点的;
  3. 分组首部开销小,tcp 有 20 个字节的首部开销,但是 udp 只有 8 个;
  4. 面向报文(datagram)。

tcp 可靠传输

除了建立连接,tcp为了可靠的交付服务,还使用了校验「通过校验和字段确认」、序号「每个报文段(segment)都会有一个序号,供上层的应用层检验」、确认「tcp的首部的确认号是希望对方传的下一个报文段的第一个字节的序号」以及重传机制「超时以及冗余ack,超时很好理解,冗余 ack 在拥塞控制中也有用到,也就是快速重传机制」来保证可靠性。

tcp 流量控制

tcp 提供了一种基于滑动窗口协议的流量控制协议。

image-20200819112504540

常用的流量控制协议有:

  1. GBN 协议,后退 N 帧协议,可以连续发送多个帧。
  2. SR 协议,选择重传,可以先缓存下那些还不需要接收的数据帧。

tcp 拥塞控制

流量控制主要是针对发送方和接收方速率的不同而采取的方案,拥塞控制则是一个全局性的控制,涉及所有主机、路由器,一个是点对点的控制,一个是全局性的控制。

为了更好的对传输层进行拥塞控制,主要采用了四种算法:

  1. 慢开始:从拥塞窗口「发送方根据自己估算的网络拥塞程度而设置的窗口值」 cwnd = 1 开始,然后指数形式增加到慢开始的阈值 ssthresh。
  2. 拥塞避免:从阈值开始,加法增大,当出现一次超时时,将慢开始的阈值置为当前 cwnd 的一半,令当前 cwnd = 1,重新慢开始。

image-20200819113354194

快重传和快恢复是对慢开始和拥塞避免算法的改进

  1. 快重传:出现三个冗余 ack,执行快重传机制,不必等到超时;

  2. 快恢复:当拥塞避免出现超时时,不需要重新让拥塞窗口慢开始,直接从当前 cwnd/2 开始加法增大。

image-20200819113958523

4. 五层模型补充

物理层

物理层

链路层

数据链路层

重点在于流量控制、介质访问以及交换机!!!

  • 介质访问

介质访问

CSMA协议

网络层

网络层

传输层

传输层

应用层

应用层

5. 流量是如何打到服务器上的

  1. 访问相应的域名,域名解析,经过 LVS 负载均衡层;
  2. LVS 负载均衡后,进入接入层,一般都是 nginx;
  3. 经过接入层后,就直接打到服务器上了

LVS

  • 简介

Linux Virtual Server,LVS 由前端的负载均衡器 (Load Balance,LB,或者称 DS) 和后端的真实服务器 (Real Server) 组成,这种结构对用户来说是透明的,用户只能看到一台虚拟服务器的 ip「VIP」,但是看不到后面的提供服务的 RS 集群,所以在用户的请求来到 LB 后,LB 可以用包转发策略和负载均衡算法合理分配到对应的 RS 集群中,RS 将结果返回给用户。

LVS 目前已经是 linux 内核标准的一部分。是基于4层的网络协议,也就是传输层之上,可以对 tcp/udp 做一个分流。

  • 既然谈到了负载均衡,那常见的负载均衡有哪几种类型呢?

大致分为 3 类,包括:

  1. DNS 方式实现负载均衡,主要是做一个入口流量的基础负载均衡,因为其虽然实现简单并且成本低,但是其服务器故障切换延迟大、调度太粗粒度、分配策略太过简单、支持的IP列表也有限;
  2. 硬件方式实现负载均衡,例如 F5 和 A10,就一个缺点:贵,一般也没啥公司用;
  3. 软件方式实现负载均衡,最常见的就是 LVS 和 Nginx、haproxy。Nginx 是 7 层负载均衡,支持 HTTP 等协议,而 LVS 在上文也讲了是 4 层负载均衡,运行在内核态,所以性能最为强大。大概总结一下使用场景:
    • nginx 适用于高并发并且对网络要求不严格的场景,对网络要求较小,并且http分流做得很好,正则规则强大;
    • lvs 是主流的负载均衡的实现方式,性能很强悍,只做分发功能,所以很稳;
    • haproxy 不了解,也是专门的负载均衡软件,对nginx有进一步的补充。例如支持 Session 的保持还可以对 mysql 进行负载均衡。
  • lvs 是如何工作的呢?
  1. 用户向 VIP 发送请求,然后调度器接收到请求后发至内核空间;
  2. 确认目标 IP 没问题后,开始分发并且修改数据包中的目标地址和端口;
  3. 找到真正的后端服务器,进行请求的响应
  • lvs 中的负载均衡模式又有哪几种呢,各有什么优缺点呢?
  • NAT

    这个实现起来很简单,就是对外只有 VIP,至于真正的 DIP 在内部可以使用私有地址,所以这里的 LVS 服务器可以在不同的网段,使用起来比较灵活,但是由于整个流量都需要经过 LVS 调度器进行数据包的转换,所以这块是一个流量瓶颈。

  • DR(Direct Routing)

    这块就不是替换 IP 了,而是直接在内部替换数据报的 MAC 地址,所以这里 DS 和 RS 必须要在一个网段,好处就是 RS 响应时直接向源 IP 返回即可,不需要再通过 LVS 进行数据包的替换了。现在这个应该是用的最多的。

  • TUN(Tunneling)

    在原有的 IP 报文中再加一层 IP 首部,这样直接拆解就行了。但是这样 RIP、VIP等都必须是公网地址,并且 RS 必须要支持隧道,所以又叫 IPIP 模型

  • 既然是负载均衡软件,那最为关键的调度算法有哪些呢?
  1. Round Robin — 轮询
  2. Weighted Round Robin — 权值轮询
  3. Least Connection — 最少连接调度
  4. Weighted Least Connection — 权值越大,承担责任越重
  5. Locality-Based Least Connections — 基于局部性的最小连接调度,找 ip 最近的 最小连接
  6. Locality-Based Least Connections With Replication…不知道这个干啥的
  7. Destination Hashing — 目标 地址散列调度
  8. Source Hashing — 源 IP 地址散列调度

统一接入层

  1. API 的聚合

    可以将一些服务进行聚合。

  2. 服务发现和动态负载均衡

    接入层有责任自动的发现后端拆分、聚合、扩容、缩容的服务集群,可以实现健康检查「VIPServer」和动态的负载均衡「nginx」。

  3. 动态资源缓存

    可以在接入层使用 redis 或者 memcached,对动态资源进行缓存。

  4. 统一鉴权、认证、过滤

  5. 限流

6. 传统前后端交互过程 & 前后端分离后交互过程

请求路径:

eg: xingge.baidu.com/ppp/

传统交互过程

浏览器输入地址后,会先将 xingge.baidu.com/ppp/ 对应为一个 vip,然后经过 LVS 负载均衡层,再进入到 统一接入层,然后通过 vipserver 对应到 tegine 服务器,tegine 服务器会将我们的请求打到对应的后端代码的服务器上,然后服务器接收到请求,返回一个 vm 模板,其实也就是一个 html 页面,浏览器接受到了 html 页面后,进行解析,碰到了一些静态资源,如图片等,就去相应的链接去找对应的资源,这里的链接都是 cdn 有关的链接,dns 解析 这个链接,对应到离其最近的服务器,拿到这些资源,如果碰到 js 资源,也是去 cdn 上找,因为 js 资源也是放在了 cdn 上,所以这样我们就能加载出一个完整的页面了,后期如果需要切换页面,就不会将请求打到后端了,因为此时浏览器已经有了 js 文件「在第一次访问后端时,后端给的 vm 模板中就有 js 链接,浏览器一开始就把所有的 js 文件加载了」,所以这时如果不需要新的数据,此时切换页面的 uri 会先由 js 文件进行路由,拿到对应的页面,如果页面需要数据,js 会去发起 ajax 请求,后端会将数据返回给浏览器。

总结一下:此时前后端没有分离,这里的前端还是属于后端的,html 文件无法进行改动,而且要提前给出对应的 js 文件到后端,灵活性比较差。

前后端分离交互过程

现在比较流行的前后端分离,大概步骤如下:

我们还是以这个例子为例,在地址栏输入 xingge.baidu.com/ppp/,这里的 dns 会解析到 Nginx 服务器的 ip,然后一般前端代码就是放在这个 Nginx 服务器下的,也就是说,所有的请求,是先给到前端的,比如我们这里是要获取 plp 的首页,Nginx 就会去找服务器下对应的 index.html,拿到之后会返回给浏览器,如果此时需要鉴权或者获取数据,再由前端向后端端口发起请求。所以一个很明显的区别,就是前后端分离,我们的请求是先给到前端,前端直接做路由的,并且前端可以自由修改 html 页面,但是 vm 模板的方式就比较笨了。请求是给到后端的,先由后端路由到对应的 vm 模板,然后把所有文件交给浏览器后,浏览器才能根据拿到的 js 文件做相应的路由处理。

Thank you for your accept. mua!
-------------本文结束感谢您的阅读-------------