网络交互之网络接入| 青训营

260 阅读6分钟

刷抖音网络是怎么交互的?

·网络接入

先让手机能够访问抖音的服务器:进行互联网连接

动态路由(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,模块化设计,具有较好的拓展性和可靠性,支持热部署