以打开抖音会发生什么作为切入点
刷抖音网络是如何交互的?
常见的刷抖音的操作需要涉及到比如域名解析DNS、图片下载HTTP、视频下载HTTP、评论API/HTTP等等,这些需求的实现的前提包括两个功能的实现:
① 网络接入,以 抖音客户端 --> 抖音服务器 为例
宏观来说,需要经过通信运营商的骨干网络,实现通信,移动设备->路由器->中国电信网/中国联通网->服务器机房
中间需要路由往往是必须的,包括网段内/外设备的通信,相同网段内简单就是直连,或者集线器、交换机甚至依托SDN技术实现,不同网络内就需要路由器的网关来实现
路由也可以不是对称的,它工作在网络IP层(一般回答,但是一些动态路由协议比如BGP/OSPF其实属于传输层协议),而且路由并不会修改目的IP地址,它会修改 MAC 地址,找到发包口(找到下一跳 IP 之后,通过 ARP 去获取设备的 MAC 地址,然后通过网卡端口发送过去,kernel 中以网卡为单位发送数据)
ARP 协议通过 IP 获取 MAC 地址,广播 ARP 请求,单播 ARP 响应,注意只有逻辑同网段才可以发送 ARP 请求报文,跨网段则不能,因此 ARP 其实是获取下一跳的 MAC,而不是直接就获取目的 IP 的 MAC
免费 ARP:不用请求就给出自己的 MAC 地址,实际应用中比如出现新加服务器节点的场景,可以通过免费 ARP 告诉其他节点自身的 MAC 地址,让其他节点更新自己的 MAC 地址记录表。同时在 IPv6 中也存在一个类似的 免费ARP 的功能,当给服务器新增 IP 地址时,也会主动告诉其他服务器,如果存在 IP 冲突,那么就可以提前预警,降低风险
ARP 代理:劫持 ARP 请求,发往另外指定的一个地方,由那个地方来响应 ARP 的请求
IP协议:是互联网通用的唯一标识,但是为什么不能够使用 MAC 地址去代替 IP地址,原因在于这是有向下兼容的问题,MAC 工作在2层,但是2层协议还有很多,并不是所有设备都支持 MAC,因此需要进一步封装到 IP 层来解决
NAT:解决 IPv4 地址不够用的问题,分为内网外网吧啦吧啦。问题:如果多个内网客户端访问同一目标地址+端口,源端口是一样的,会不会发生冲突?其实不是只改 IP 地址,同时修改 IP 地址 + 端口
②网络传输(计网传输层、应用层协议)
DNS 获取 IP 地址,了解解析过程根域名->权威域名->顶级域名->目的域名得到 IP 地址
TCP 传输协议,理解三次握手,序列号 (seq) 表示发送方发送的这个包的数据部分的第一位应该位于整个数据流中哪个位置,确认号 (ack) 表示期望的对方的下一个序列号是多少
HTTP/HTTPS 协议的具体细节,包括HTTP协议的演进、SSL/TLS握手的细节等等(看小林coding理解就行)
网络架构怎么给抖音提质?
①网络提速
协议优化
HTTP2.0 可以在一个 TCP 连接上实现多路复用,传输多个使用标号区分的 stream,以此来代表的不同的数据传输,实现并发,但是存在对头阻塞的问题还是会导致网络传输出现阻塞,HTTP3.0 可以解决这个问题
QUIC/HTTP3.0 是基于 UDP 协议来实现,原因包括 TCP 协议很复杂而且应用太广泛,目前的 TCP 协议栈在 Linux 系统上是不可插拔的,如果依托于 TCP 协议来解决对头阻塞问题,有可能出现很多问题,如何推广、解决bug、多种系统协议栈的替换等等;而且是实现在用户态的,因为如果是实现在内核态,不同的操作系统内核都要重做,比较麻烦;
它的优势就是解决了对头阻塞问题,存在弱网优势
路径优化
数据中心的分布
核心机房:存储核心数据的地方,比如常见的 MYSQL 数据库等等
POP 接入点:和各大运营商、外网 Internet 交互的机房
边缘机房:更靠近用户,但是数据不是核心的关键数据
同运营商访问:通过解析域名得到 IP,根据 IP 地址来判断属于来自哪个运营商的用户数据,然后选择对应运营商机房
静态资源(图片资源)的路径优化 (CDN) :静态资源很少会发生动态变换,因此可以通过在靠近客户端的服务器中缓存数据,然后访问这些静态资源时,先查询这些边缘机房是否已经缓存了这些数据,如果存在就返回对应的,不存在就汇聚机房,再不存在就核心机房,找到返回并将数据缓存到边缘机房
动态API(播放/评论接口)路径优化 (DSA) :每个人访问不同的接口获取到的数据都不一样或者随着时间变化这些内容在变,比如评论信息。可以通过建立网络拓扑中相邻机房之间的网络探测,来选择时延最小的路径,从靠近客户端的边缘机房到存储核心数据的核心机房,来获取实际的评论数据
②网络稳定
容灾:大致分为4个关键流程,故障发生(产生故障)、故障感知(通过一定的反馈或者监控感知到故障)、自动切换(把故障节点从系统中去掉)、服务恢复(系统功能恢复)
网络容灾具体案例1--专线容灾:专线概念就是指可以直接通过物理连接实现通信,但是一旦专线故障就需要考虑走外网,所以容灾时比如主备切换就需要考虑外网容灾点的实现
网络容灾具体案例2--调度容灾:一个服务节点出现故障,需要将服务节点的服务转移到其它节点上,同时将该故障节点从服务节点中去除。需要考虑故障感知,探测承载节点(确定另外转移的节点有没有能力承载原始节点的数据)
网络容灾具体案例3--云控:客户端软件中包含SDK,SDK可以和云端通信,知道哪个节点出现故障,然后客户端主动降级/容灾就不去使用故障节点,场景局限型:SDK需要用户授权有限制、或者通过浏览器访问web没办法嵌入SDK等
网络容灾具体案例4--类缓存兜底:出现 bug 导致多级网络某一级后面的网络链路不通时,可以在这一级前置一段兜底逻辑(cache文件),也就是发现后面不通时,就去调用之前缓存的处理结果作为返回
故障排查:大致分为3个流程,
故障明确(故障业务是什么?什么接口故障?访问其他目标是否正常?是否修改导致的异常?)
故障止损(止损是优先级最高的,止损完之后再排查,组件是否存在容灾,有容灾就先上容灾没有就尝试降级止损)
分段排查(客户端排查:客户端访问其他服务、其他客户端访问目标服务等,服务端排查:服务端监控/指标是否正常、手动访问是否正常、分组件排查问题等,中间链路排查:确定前面没有问题之后,排查中间网络设备问题等)
常用指令包括:
dig 查询 DNS 问题、ping/telnet/nmap 查询三层/四层连通性、使用 traceroute 排查中间链路、tcpdump 等等
网路故障排查案例1--健康检查异常:实际网络设备中,接入网络的应用服务端时需要给每个节点做健康检查,也就是判断服务端节点是否可用,不可用就需要去除。但本身健康检查机制是可能出错的,即把正常的节点去掉,异常出现
网络故障排查案例2--个别网络用户报障:电信故障报错,出现流量突然降低
网络故障排查案例3--客户端个例异常:个别用户报故障,客户端自身问题
网络故障排查案例4--非对称路由问题:网络转发设备做 fastExmit 转换,即快速发包(默认路由是对称的,往下一跳发包时,默认返回路径就是原本去的那一条路径,所以返回时的目标 MAC 就是发送时的源 MAC,不对称就会导致发送到错误的 MAC 地址上,不会被识别)
课后作业:
企业接入升级打怪之路
域名系统
host 管理:常规方式采用 host -> ip 映射的方式来实现,但是当业务规模和员工数量大幅增长时,本身维护映射关系的 host 表文件会越来越大,统一分发会引起较大的网络流量和 CPU 负载,而且还存在名称冲突,也就是无法保证主机名称的唯一性,添加同名主机会导致服务故障,分发通过人工上传,这样的方式时效性很差
另一种解决思路就是域名系统来代替 hosts 映射表文件,将域名空间组织为树形结构,使用根域名服务器作为查询节点,逐级向下查询顶级域名、权威域名等等
自行搭建时可以去云厂商购买域名,然后经过域名备案,然后将网站开放给外部服务访问,如下图所示
自建 DNS 服务器
为什么需要自建 DNS 服务器?原因在与内网域名的解析也需要去公网获取,效率较低,而且外部用户可以看到内网 IP 地址,这样容易遭受到网络攻击,而不是直接使用云厂商提供的权威 DNS 服务器,原因在于承载过大,容易故障,因此一些大公司需要从公有云托管转向搭建自己的DNS系统
DNS 的查询过程:本地DNS服务器查询->没有就根域名服务器->顶级域名服务器->权威域名服务器->缓存在本地,可以通过 dig {$domain} +trace 查看实际的 DNS 的查询过程
从企业的角度,往往时需要自建权威 DNS 服务器的,常见的开源 DNS 服务器结构 bind 是可以参考的例子,如上图右
接入 HTTPS 协议
HTTP 明文传输的不安全性因此需要使用 HTTPS 来解决这一问题,了解 HTTPS 中混合加密的实现方式,包括非对称加密 SSL 是如何三次握手的,以及证书摘要信息,数字签名,CA证书链的解析等等实现(查看小林Coding)
接入全站加速
外网用户访问源站时可能出现以下问题:①由于源站容量低可承载的并发请求数很低,容易被打垮②报文经过的网络设备越多,出现的概率越大比如丢包、劫持、MTU等等③自主选路网络链路很长,导致时延高。总体现就是响应慢、卡顿
常用解决方案:①源站容量问题通过后端机器扩容,对于静态内容,则开启静态加速缓存,②对于网络传输问题则通过动态加速DCDN来改善
全站加速就是指静态加速+动态加速
静态加速 CDN:如上图所示,左图为不使用静态加速,直接通过授权服务器告诉客户端到指定的站点服务器群获取数据,而右边是使用静态加速,会额外访问一个智能调度 DNS,他会告诉客户端到对应的已经缓存过需要的静态文件的 CDN 节点(可能其他客户端已经访问过并缓存到 CDN 节点上)上直接获取静态数据,而不是直接去源站点服务器群
这样做的好处在于:①解决服务器端第一公里的问题,也就是用户可以从最靠近用户的节点获取数据,②缓解各运营商之间互联的瓶颈压力,原因在于不再是访问源站,更多的是 CDN 节点,③优化网上热点内容的分布情况,热点内容分布在靠近用户的 CDN 节点上
动态加速 DCDN:动态内容不能够在 CDN 节点上进行缓存,因此动态加速则是基于智能选路技术来实现的,从众多回源线路中择优选择一条线路进行传输(大概就是每到一个 DCDN 节点都要进行探测,找到最优路径快速回源)上图中的右图为使用 DCDN 动态加速的例子,通过算法实现最优路径搜索,左图为总的接入全站加速之后的网络结构
接入四层负载均衡
问题:在运营商处租用的公网IP应该在公司内部如何合理使用?最简单的直接找物理机,通过 ifconfig 将网卡配置为这个公网 IP,然后服务器开始监听请求,应用多的时候,可以起多个 server 监听不同的端口,但是还是很麻烦
租多个公网 IP 来实现太奢侈而且数量有限,需要考虑尽可能充分利用和管理有限的公网 IP 资源,因此提出负载均衡
四层负载均衡工作在网络的传输层(TCP/IP 模型中的第四层,对应 OSI 模型的传输层)。它主要关注的是传输层的协议,如 TCP 和 UDP。四层负载均衡器根据 IP 地址和端口号来转发请求,而不关心应用层的数据内容。它利用某种算法将报文转发给某个后端服务器,实现负载均衡地落到后端服务器上,其主要的功能就是①解耦 vip (暴露给外部的 IP 地址) 和 rs (实际服务器物理机配置的 IP 地址),②可以作为NAT,实现反向代理,③可以避免直接将物理机的 IP 地址直接暴力给公网,防止受到攻击,上图左图为四层负载均衡的示意图,右图是具体实现例子 fullnet
四层负载均衡的特点:①大多通过 dpdk 技术实现,大厂使用广泛,②属于纯用户态协议栈,可以缓解内核态 C10M 问题,消除协议栈瓶颈,③无缓存、零拷贝、大页内存,可以减少 cache miss,④仅针对4层数据包转发,小包转发可以达到限速,可承受高 cps(纯念 PPT,没听懂一点)
常见的调度算法:RR 轮询、加权 RR 轮询、最小连接、五元组 hash (sip\sport\proto\dip\dport)、一致性 hash (需重点在后面两种,可以额外了解)
接入七层负载均衡
七层负载均衡工作在网络的应用层(TCP/IP 模型中的第七层,对应 OSI 模型的应用层)。它不仅关注传输层的信息,还深入解析应用层的数据,如 HTTP 请求的 URL、头部信息、Cookie 等。因此,比如多个站点都需要服务器节点的80端口,四层负载均衡中一个节点只能绑定一个80端口,就无法实现这个要求,但是通过接入七层负载均衡就可以解决。
常见的 Nginx 就是包含了七层负载均衡的功能,是应用最广的七层反向代理,Nginx 内容需要单独学习,这里不展开叙述,只需要知道它是基于事件驱动的(上图右图所示)、异步非阻塞(一个进程/线程处理多个连接请求,可以减少 OS 进程的切换)的模型,然后采用 master/worker 架构设计的高性能webserver
整体所有流程如下图所示