这是我参与「第三届青训营 -后端场」笔记创作活动的第1篇笔记
打开抖音会发生什么
-
客户端向Local DNS发送递归请求,请求内容为www.douyin.com
-
假设Local DNS服务器无缓存机制
- 向根服务器发送迭代请求,请求内容为www.douyin.com ;得到
com.对应dns服务器的ip地址 - 向顶级域名服务器发送迭代请求,请求内容为www.douyin.com ;得到
toutiao.com.对应dns服务器的ip地址 - 向权威服务器发送迭代请求,请求内容www.douyin.com ;得到CNAME记录
www.toutiao.com.bytedns1.com. - 向权威服务器继续发送迭代请求,请求内容为www.toutiao.com.bytedns1.com ;得到CNAME记录
www.toutiao.com.w.kunluncan.com - 向权威服务器继续发送迭代请求,请求内容为www.toutiao.com.w.kunluncan.com ;AUTHORITY数量为0,说明不是最终的权威服务器
- 向顶级域名服务器重新发送迭代请求,请求内容为www.toutiao.com.w.kunluncan.com ;得到
kunluncan.com.对应dns服务器的ip地址 - 向次级域名服务器发送迭代请求,请求内容为www.toutiao.com.w.kunluncan.com ;得到
w.kunluncan.com.对应dns服务器的ip地址 - 向最终的权威服务器发送迭代请求,请求内容为www.toutiao.com.w.kunluncan.com ;得到A或AAAA类型记录
- 向根服务器发送迭代请求,请求内容为www.douyin.com ;得到
-
客户端向得到的IP发送TCP报文建立连接
- 客户端向服务端发送[SYN]报文请求建立连接
- 服务端向客户端发送[SYN ACK]报文同意建立连接
- 客户端向服务端发送[ACK]报文确认建立连接
-
客户端向网关发送HTTP请求报文
- 如果用户请求的是视频/图片等静态资源,命中CDN缓存时边缘机房会直接返回资源,未命中时边缘机房从核心机房将资源取回并缓存
- 如果用户请求的是POST等非静态请求,DCDN会利用可控节点做路径探测和规划从而选择最优传输链路
-
HTTP报文对于TCP来说只是payload,TCP报文对IP来说也是payload
-
路由器通过查表确定目标IP的下一跳,将源MAC修改为自己的物理地址,将目标MAC修改为下一跳的物理地址
-
报文在经过四层负载和七层负载转发后最终到达后端服务器。
附录
| 设备 | 位置 | 功能 |
|---|---|---|
| 集线器 | 物理层 | 中继,让其链接的设备工作在同一网段 |
| 桥接器 | 数据链路层 | 网络桥接,将多个网段在数据链路层连接起来 |
| 交换机 | 数据链路层 | 依据MAC地址在第二层转发网络帧 |
| 路由器 | 网络层 | 路由,决定数据包传输的路径;转发,将数据包从输入端移送到输出端 |
课后作业
课后作业1- UDP socket 实现 ack,感知丢包重传
-
学会 UDP socket 编程
-
先从简单的 ack 学习,客户端等待 ack 再发包
-
什么时候客户端认为是丢包?
-
重传怎么考虑效率?
-
能不能不阻塞只穿丢掉的中间的段?
课后作业2- 三台同网段内的服务器,模拟实现一个路由器
用户态 socket 编程实现简易 route 软件
-
收到指定的包后,做转发
-
注意是修改报文的 MAC ,不是修改 IP
-
实现一个对称路由。这样可以实现 TCP 交互
-
可以通过 ping 来验证
-
可以支持 traceroute 吗?
课后作业3- DNS搭建实验
- 使用开源软件bind9作为DNS服务的server(或使用UDP socket实现)
- 使用dig @命令验证
课后作业4- 四层负载均衡实验
-
将到达本机的53端口的udp报文转发到DNS服务
-
将到达本机的80端口的tcp报文转发到自己准备的hello_world后端服务上
课后作业5- 七层负载均衡实验
使用nginx的http模块在四层负载均衡和后端服务之间添加七层负载均衡服务
http {
include mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
keepalive_timeout 65;
upstream backend {
server 10.227.89.58:8080;
}
server {
listen 880;
server_name www.example.com;
location / {
proxy_pass http://backend;
proxy_set_header HOST $host;
proxy_connect_timeout 60;
proxy_send_timeout 60;
proxy_read_timeout 60;
}
}
}