刷抖音网络是怎么交互的?
·网络接入
先让手机能够访问抖音的服务器:进行互联网连接
动态路由(BGP,OSPF)
ARP协议找下一跳的MAC,请求是广播,应答是单播。
免费ARP:
免费 ARP(Gratuitous ARP)包是一种特殊的 ARP 请求,它并非期待得到 IP 对应的 MAC 地址,而是当主机启动的时候,发送一个 Gratuitous ARP 请求,即请求自己的 IP 地址的 MAC 地址。 免费 ARP 报文与普通 ARP 请求报文的区别在于报文中的目标 IP 地址。普通 ARP 报文中的目标 IP 地址是其他主机的 IP 地址;而免费 ARP 的请求报文中,目标 IP 地址是自己的 IP 地址。
IP+端口 唯一确定一个进程。
数据包
struct pkt{
something
}
void send_one_pkt()
{
p = malloc(sizeof(pkt))
p = append(p,sizeof(l2))
p = append(p,sizeof(l3))
p = append(p,sizeof(l4))
}
send(p)
·网络传输
DNS请求:进行域名解析。递归查询以及迭代查询。
TCP三次握手
TCP option 进行协商MSS,时间戳
MSS(Maximum Segment Size)是一种TCP选项,用于协商TCP连接中每个数据段的最大大小。在建立TCP连接时,通信双方可以通过MSS选项告知对方每个数据段的最大大小,从而避免由于数据段过大而导致的分片和重组,从而提高传输效率。
时间戳(Timestamp)是一种TCP选项,用于记录TCP连接中每个数据段的发送时间和接收时间,从而计算网络延迟和时钟漂移等参数。时间戳选项可以帮助TCP协议更精确地控制数据传输速率和重传机制,从而提高传输效率和可靠性。
在TCP连接建立时,通信双方可以协商是否使用MSS选项和时间戳选项。如果双方都支持这些选项,那么就会在TCP连接的头部中添加这些选项,从而进行更加精细的控制。如果双方不支持这些选项,那么就会默认使用TCP协议的标准选项。
HTTP依然是TCP,1.1做了HOST、缓存等优化
课后作业:UDP socket编程,实现感知丢包重传
package main
import (
"fmt"
"net"
"time"
)
const (
MaxPacketSize = 65535
RetransmitTime = 2 * time.Second
)
type Packet struct {
SeqNum uint32
Data []byte
}
func main() {
conn, err := net.ListenUDP("udp", &net.UDPAddr{IP: net.IPv4zero, Port: 12345})
if err != nil {
fmt.Println(err)
return
}
defer conn.Close()
var buffer [MaxPacketSize]byte
var expectedSeqNum uint32
for {
conn.SetReadDeadline(time.Now().Add(RetransmitTime))
n, addr, err := conn.ReadFromUDP(buffer[:])
if err != nil {
fmt.Println(err)
continue
}
packet := Packet{}
if err := packet.UnmarshalBinary(buffer[:n]); err != nil {
fmt.Println(err)
continue
}
if packet.SeqNum != expectedSeqNum {
fmt.Printf("Packet %d dropped\n", expectedSeqNum)
continue
}
fmt.Printf("Received packet %d from %s\n", expectedSeqNum, addr)
expectedSeqNum++
conn.SetWriteDeadline(time.Now().Add(RetransmitTime))
if _, err := conn.WriteToUDP(packet.MarshalBinary(), addr); err != nil {
fmt.Println(err)
continue
}
}
}
func (p *Packet) MarshalBinary() ([]byte, error) {
buf := make([]byte, 4+len(p.Data))
copy(buf[:4], []byte(fmt.Sprintf("%04x", p.SeqNum)))
copy(buf[4:], p.Data)
return buf, nil
}
func (p *Packet) UnmarshalBinary(data []byte) error {
if len(data) < 4 {
return fmt.Errorf("Packet too short")
}
p.SeqNum = uint32(data[0])<<24 | uint32(data[1])<<16 | uint32(data[2])<<8 | uint32(data[3])
p.Data = data[4:]
return nil
}
这段代码实现了一个基于UDP的数据包传输程序。它使用UDP套接字监听端口 12345,并通过UDP连接接收和发送数据包。以下是代码的主要部分和注释:
Packet结构体表示一个数据包,包含一个序列号和数据字段。main函数是程序的入口点。它创建一个UDP监听器,并循环等待接收数据包。- 在循环中,首先设置读取超时时间,然后从UDP连接中读取数据到
buffer中。- 接下来,创建一个空的
Packet实例,并使用UnmarshalBinary方法将接收到的数据包解析到该实例中。- 如果接收到的数据包的序列号与期望的序列号不匹配,将打印一条消息并继续下一个循环。
- 如果序列号匹配,将打印接收到的数据包的信息,并将期望的序列号增加。
- 接着,设置写入超时时间,并使用
WriteToUDP方法将接收到的数据包发送回客户端。MarshalBinary方法将Packet结构转换为二进制数据。UnmarshalBinary方法从二进制数据中解析并填充Packet结构。这段代码的功能是在接收到的数据包序列号正确时,将其返回给发送者,并丢弃任何不匹配的数据包。它可以用于简单的可靠数据传输场景,但不提供丢包重传或其他高级特性。
2.接入HTTP
2.1 常见加密
- 对称加密,公用一份密钥
- 非对称加密,有私钥和公钥,公钥加密只能私钥解密,若使用私钥加密只能用公钥解密
HTTPS:通信建立前使用非对称加密,通过公钥,私钥进行加密通信交换密钥,通信建立后使用对称加密,通过密钥加密通信,非对称加密速度慢,但可以安全交换密钥,对称加密速度快但无法安全交换密钥,因此使用混合加密模式
2.2 数字证书
数字证书唯一,由CA(数字证书认证机构)颁发,只要证书是可信的,公钥和私钥就是可信的,即通过数字证书验证公钥和私钥是否被伪造
本质还是数字签名算法,由CA持有私钥并颁发公钥,不同的是CA颁发的公钥已事先存储在客户端中,不会在通信过程中被篡改
数字证书通过证书链认证
2.3 接入全站加锁
背景:源站容量低,经过节点越多,丢包等问题就会越多,导致卡顿和响应慢
解决方案:
- 增加源站容量(静态加速)
- DCDN加速(动态加锁)
- 全站加速:增加源站容量并使用CDN
用户首次登录抖音并注册时,使用的是动态加速DCDN
用户打开某个特定的短视频加载后观看是静态加速CDN
用户打卡头条官网进行网页浏览是静态加速CDN+动态加速CDN
3.四层负载均衡
服务多而杂,只使用一台物理机接入IP会导致出现问题,而且若该物理机故障,所有服务都不可用
什么是负载均衡:
- 基于IP+端口,利用某种算法加报文转发给某个后端服务器,实现负载均衡地落到每一个后端服务器上
三个主要功能: 解耦VIP和RS,NAT和防攻击
3.1 常见调度算法原理
- RR轮查询
- 加强RR轮查询
- 最小连接
- 五元组hash
- 一致性hash
4.七层负载均衡
四层负载均衡对IP只能bind一个端口,若有多个外部站点需要使用,该如何解决
开源七层负载均衡:Nginx,模块化设计,具有较好的拓展性和可靠性,支持热部署