计算机网络和HTTP框架 | 青训营笔记

252 阅读10分钟

这是我参与「第三届青训营 -后端场」笔记创作活动的的第8篇笔记

GO-学习笔记

网络是怎么交互的

  • 结构 image.png

路由

  • 同网段,ip在子码掩码以内
  1. 同一个ip的设备,通过交换机互通
  2. SDN,Software Defined Network,软件定义网络,网络虚拟化,集中管理范围内的网络资源(交换组),并进行转发
  3. 修改目标IP的MAC地址即可发送
  • 跨网段
  1. A通过路由,先到能到达目的地的路由
  2. 配置默认网关,与路由表进行匹配,如果没有优先选择的路由,选择默认网关
  • 路由不是对称的,去路,不一定是回路
  • 路由总体上工作在IP层,但是也涉及数据链路层和传输层
  • 目标IP地址一直不变,通过修改MAC地址,找到下一个的物理网关

通过ARP协议,通过IP获取MAC地址

  • 传输过程中,四元组中,源/目标IP不变,源/目标MAC改变
  • 发包时,指定网卡,以网卡为单位,才能发送
  • 动态路由 BGP/OSPF
  1. 动态路由,路由器能够根据路由器之间的信息交换,进行路由表的维护
  2. BGP,Border Getway Protocol,边界网关协议,传递路由信息
  3. OSPF,Open Shortest Path First,开发最短路径优先,定期与建立邻接关系的路由进行交互,根据链路状态数据库表(全网的网络拓扑),经过SPF算法,计算出到达每个相连网络的最佳路径

怎么找下一跳MAC

  • ARP协议
  • 逻辑同网段才能发送ARP
  • 不断通过发送ARP请求广播,收到ARP应答单播,获得对应的MAC,进行下一跳

广播不能跨网段

  • 免费ARP,Gratuitous RAP
  1. 新增IP,告诉同频段的设备,新增设备的IP和MAC
  2. 防止IP冲突
  3. 更新其他主机的ARP缓存表
  • ARP代理
  1. 中介作用,扩充边界
  2. ARP请求劫持,修改真正要访问的MAC
  3. 路由器拦截客户端的ARP请求,返回自己的MAC地址,代理访问真实的主机
  4. 针对没有路由的主机,代理其与网络通信

IP协议

  • 为什么不能用MAC地址代替IP地址
  1. MAC协议在第2层,数据链路层,有些设备不支持MAC协议,通过IP协议来封装一层,进行兼容
  2. 地址统一
  • IPv4不够用
  1. IPv6扩充
  2. NAT,内部IP可以重复,用统一的IP连接互联网
  • NAT,多个内网客户端访问同一个目标地址+端口,该端口与内网某个客户端重复怎么办
  1. NAT,同时修改IP和端口
  2. 维护一张表,冲突了,就修改对外网的端口

数据包

  • 结构,层层包装 image.png
  • 发送 image.png

DNS协议

  • 将域名映射为IP
  • 递归迭代,解析域名
  1. 根域服务器,写死的
  2. 顶级域服务器. .com
  3. douyin.com
  4. www.douyin.com
  5. 找到目标ip

UDP协议

  • 源/目标端口+长度/校验+数据
  • QUIC,基于UDP的可靠协议
  1. 无队头阻塞,每个数据包都有唯一的标签,当数据包丢失后,只阻塞该数据包的流
  2. 更快的建立连接,基于ECDHE算法,TLS1.3,一个RTT就能开始数据传输,第二次连接时,只需携带QUIC信息和数据包,达到0RTT建立连接
  3. 网络迁移无需重新连接,连接时会生成连接ID,只需验证连接ID

TCP协议

  • 本质上就是一个TCP连接的状态
  • 拔了网线,不一定会断
  1. 如果有保活机制,那么会发送探测报文,检查是否有回应
  2. 如果没有,长时间不互通消息,不一定会断

三次握手

  • 三次握手时,确认MSS,通过TCP中option字段,协商出最小值,作为MSS image.png
  • 时间戳交互
  1. 计算往返时延,a向b发,记录t1;b向a回复,记录t2,RTT = t2 - t1
  2. 防止序列号回绕,如果出现序列号相同的包,利用时间戳进行区分,忽略过期的包
  • sequence number,这部分数据第一位,应该在数据流的位置索引
  • acknowledge number,期望对方下一次的sequence number是多少
  • SYN/FIN,没有传输数据,但是会让下一次的seq增加1,ACK,则不会

传输

  • 有限状态机 image.png
  • TIME_WAIT
  1. 出现在四次挥手的过程中
  2. 2MSL,确保双方的包,都能够消失,防止复用连接时数据混乱
  • 滑动窗口
  1. 接收方窗口,根据内核为TCP划分的缓存空间,进行动态变化
  2. 发送方窗口,根据接收方窗口和网络阻塞情况,取最小值
  • 流量控制/拥塞机制
  1. 流量控制,发送数据时,在tcp头部,表明窗口大小,发送方根据窗口大小进行发送,防止接收方处理不过来
  2. 拥塞控制,发送发需要探知网络拥塞程度,对发送窗口进行控制,慢启动/拥塞避免/拥塞发生/快速恢复

HTTP/HTTP1.1

  • 分层,在TCP上多加了一层规范
  • TCP负责的内容本身就够过了
  • 关注业务本身
  • HTTP1.1
  1. 长连接
  2. 部分传输,返回码206
  3. HOST,区分同一个服务器,不同的服务
  4. 缓存,访问过的资源,可以在本地进行缓存,优先在缓存中查找,如果过期,再访问服务器

HTTPS

  • 解密出来依然是HTTP
  • 非对称加密 SSL/TLS
  1. 客户端发送,TLS版本/支持的密码套件列表/随机数
  2. 服务端,确认TLS版本/选择的密码套件(RSA/AES)/数字证书/随机数
  3. 客户端,校验数字证书,获取RSA公钥,并对新的随机数进行加密;根据AES算法和随机数,生成会话密钥,将内容摘要加密
  4. 服务端,校验摘要,RSA私钥解密随机数,生成会话密钥
  5. 开始通信

网络优化

HTTP2.0

  • 多路复用,一个连接中并发多个请求和响应,不用按照顺序响应
  1. A请求耗时,可以先回应A处理好的部分,处理好B后,再处理A
  • 头部压缩,客户端和服务端同时维护一张表,用赫夫曼编码
  • 数据均为二进制格式
  • 并发传输,一个TCP连接中有多个流,一个流中包含着请求和响应
  1. 客户端,流编号奇数;服务端,流编号偶数
  2. 一个TCP连接上,进行多个HTTP连接
  • sack方法,标记接收到的数据包
  • 缺点
  1. 其中一个stream中丢包了,需要全部重发,导致队头阻塞,会阻塞在TCP层
  2. 网络迁移需要重新连接

QUIC/HTTP3.0

  • 基于UDP,在用户态实现
  • 弱网传输
  1. 无队头阻塞,每个数据包都有唯一的标签,当数据包丢失后,只阻塞该数据包的流
  2. 更快的建立连接,基于ECDHE算法,TLS1.3,一个RTT就能开始数据传输,第二次连接时,只需携带QUIC信息和数据包,达到0RTT建立连接
  3. 网络迁移无需重新连接,连接时会生成连接ID,只需验证连接ID

数据中心的分布

  • 服务器集合的地方
  • 核心机房,存储核心数据
  • POP接入,跟运营商和互联网交互
  • 边缘机房,更靠近用户,绑定运营商

同运营商访问

  • 电信访问电信的服务器,移动访问移动的服务器
  • 国内跨网访问比较慢
  • 通过域名解析,解析到目标的运营商

CDN路径优化

  • 针对静态资源
  • 在边缘机房中进行缓存,是否有其他用户访问过的内容
  • 层层上去找

DSA路径优化

  • 针对动态资源,使用一个小文件放置在源服务器上进行探测
  • 路径访问的距离和时间最快
  • 对周围的机房做网络探测,结合延时通过算法,找到最优路径

容灾概念

  • 故障发生
  • 鼓掌感知,通过监控,感知故障
  • 自动切换,及时下线故障节点
  • 服务恢复

案例

  • 外网容灾,专线不可用,通过外网 image.png
  • 调度容灾,同一个域名对应多个具体机房,如果一个节点发生故障,分配给另一个节点
  1. GTM,Global Traffic Manager,全局流量管理,DNS解析给用户返回最佳的IP,会对所有资源进行健康检查,发现故障就从其中删除
  2. 在分配前,进行探测,要确保另一个节点能承载故障节点的流量 image.png
  • TNC云控系统,云到端,通过内嵌的AppSKD控制,主动降级/容灾
  1. 用户禁止执行某些节点切换命令
  2. 通过web访问节点,SDK不能控制
  • 代码有bug,APP崩了,在最前端,做逻辑兜底,进行降级 image.png

故障排查

  • 故障明确
  1. 故障体现在哪里
  2. 访问其他目标是否正常
  3. 是否是修改导致的异常
  • 故障止损
  1. 用户体验第一
  2. 降级/组件系统容灾
  • 分段排查
  1. 客户端排查,客户端访问其他服务是否有问题;其他客户端访问本服务
  2. 服务端排查,监控/指标,手动访问,分组件排查
  3. 中间链路排查,中间网络设备/旁路DNS

案例

  • 健康检查服务异常,错误下线健康的服务器节点
  • 客户端个例异常,防火墙配置问题
  • 硬件传输电缆被挖断
  • 服务正常,网络设备异常,抓包查看

快速发包,默认路由对称,导致不能解析MAC地址 image.png

HTTP框架

  • 字节内部Hertz
  • HTTP,Hypertext Transfer Protocol,超文本传输协议,属于第七层应用层
  1. 超文本,视频/声音/图片/超链接也可以作为文本内容
  2. 协议,双方均能解析出对应的内容,明确的边界
  • 结构
  1. 请求行,方法名/URL/协议版本;状态行,协议版本/状态码/状态码描述
  2. 请求头;响应头,请求/响应参数
  3. 请求体;响应体
  • 版本迭代
  1. HTTP1,队头阻塞,传输效率低,明文传输不安全
  2. HTTP2,多路复用,头部压缩,二进制协议
  3. HTTP3/QUCI,基于UDP,解决对头压缩,加密次数减少

分层

  • 应用层
  1. 合理的API,可理解性、简单性、去冗余性、兼容性、可测性、可见性
  • 中间件层,将核心逻辑和通用逻辑解耦
  1. 完整的请求处理完整周期
  2. 拥有预处理逻辑和后处理逻辑
  3. 可以注册多中间件
  4. 对上层模块用户模块易用
  • 路由,为URL,匹配对应的处理函数

map<mehod, 路由前缀树>的形式,构建方法与url的关系

  • 协议层
  1. 抽象出合适的接口
  • 传输层
  1. BIO,阻塞式IO
  2. NIO,非阻塞IO,netpoll

性能

网络库的优化

  • 为每个连接绑定一块缓冲区
  • 存下全部的header,拷贝出完整的body

根据历来的请求,估算buffer大小,用足够大的buffer,减少拷贝

针对协议的优化

  • headers解析
  1. 优化寻找边界,先找到\n,查看前面是不是\r
  2. simd加速,sonic字节的Golang JSON
  3. 针对核心字段,快速解析
  4. 高频header,额外存储,方便取
  • 热点资源池化
  1. RequestContext池
  2. 减少内存分配,提高内存复用,降低GC压力
  3. 需要额外reset