这是我参与「第三届青训营 -后端场」笔记创作活动的的第8篇笔记
GO-学习笔记
网络是怎么交互的
- 结构
路由
- 同网段,ip在子码掩码以内
- 同一个ip的设备,通过交换机互通
- SDN,Software Defined Network,软件定义网络,网络虚拟化,集中管理范围内的网络资源(交换组),并进行转发
- 修改目标IP的MAC地址即可发送
- 跨网段
- A通过路由,先到
能到达目的地的路由- 配置默认网关,与路由表进行匹配,如果没有优先选择的路由,选择默认网关
- 路由不是对称的,去路,不一定是回路
- 路由总体上工作在IP层,但是也涉及数据链路层和传输层
- 目标IP地址一直不变,通过修改MAC地址,找到下一个的物理网关
通过ARP协议,通过IP获取MAC地址
- 传输过程中,四元组中,源/目标IP不变,源/目标MAC改变
- 发包时,指定网卡,以网卡为单位,才能发送
- 动态路由 BGP/OSPF
- 动态路由,路由器能够根据路由器之间的信息交换,进行路由表的维护
- BGP,Border Getway Protocol,边界网关协议,传递路由信息
- OSPF,Open Shortest Path First,开发最短路径优先,定期与建立邻接关系的路由进行交互,根据链路状态数据库表(全网的网络拓扑),经过SPF算法,计算出到达每个相连网络的最佳路径
怎么找下一跳MAC
- ARP协议
- 逻辑同网段才能发送ARP
- 不断通过发送ARP请求广播,收到ARP应答单播,获得对应的MAC,进行下一跳
广播不能跨网段
- 免费ARP,Gratuitous RAP
- 新增IP,告诉同频段的设备,新增设备的IP和MAC
- 防止IP冲突
- 更新其他主机的ARP缓存表
- ARP代理
- 中介作用,扩充边界
- ARP请求劫持,修改真正要访问的MAC
- 路由器拦截客户端的ARP请求,返回自己的MAC地址,代理访问真实的主机
- 针对没有路由的主机,代理其与网络通信
IP协议
- 为什么不能用MAC地址代替IP地址
- MAC协议在第2层,数据链路层,有些设备不支持MAC协议,通过IP协议来封装一层,进行兼容
- 地址统一
- IPv4不够用
- IPv6扩充
- NAT,内部IP可以重复,用统一的IP连接互联网
- NAT,多个内网客户端访问同一个目标地址+端口,该端口与内网某个客户端重复怎么办
- NAT,同时修改IP和端口
- 维护一张表,冲突了,就修改对外网的端口
数据包
- 结构,层层包装
- 发送
DNS协议
- 将域名映射为IP
- 递归迭代,解析域名
- 根域服务器,写死的
- 顶级域服务器.
.comdouyin.comwww.douyin.com- 找到目标ip
UDP协议
- 源/目标端口+长度/校验+数据
- QUIC,基于UDP的可靠协议
- 无队头阻塞,每个数据包都有唯一的标签,当数据包丢失后,只阻塞该数据包的流
- 更快的建立连接,基于ECDHE算法,TLS1.3,一个RTT就能开始数据传输,第二次连接时,只需携带QUIC信息和数据包,达到0RTT建立连接
- 网络迁移无需重新连接,连接时会生成连接ID,只需验证连接ID
TCP协议
- 本质上就是一个TCP连接的状态
- 拔了网线,不一定会断
- 如果有保活机制,那么会发送探测报文,检查是否有回应
- 如果没有,长时间不互通消息,不一定会断
三次握手
- 三次握手时,确认MSS,通过TCP中
option字段,协商出最小值,作为MSS - 时间戳交互
- 计算往返时延,a向b发,记录t1;b向a回复,记录t2,RTT = t2 - t1
- 防止序列号回绕,如果出现序列号相同的包,利用时间戳进行区分,忽略过期的包
sequence number,这部分数据第一位,应该在数据流的位置索引acknowledge number,期望对方下一次的sequence number是多少- SYN/FIN,没有传输数据,但是会让下一次的
seq增加1,ACK,则不会
传输
- 有限状态机
- TIME_WAIT
- 出现在四次挥手的过程中
- 2MSL,确保双方的包,都能够消失,防止复用连接时数据混乱
- 滑动窗口
- 接收方窗口,根据内核为TCP划分的缓存空间,进行动态变化
- 发送方窗口,根据接收方窗口和网络阻塞情况,取最小值
- 流量控制/拥塞机制
- 流量控制,发送数据时,在tcp头部,表明窗口大小,发送方根据窗口大小进行发送,防止接收方处理不过来
- 拥塞控制,发送发需要探知网络拥塞程度,对发送窗口进行控制,慢启动/拥塞避免/拥塞发生/快速恢复
HTTP/HTTP1.1
- 分层,在TCP上多加了一层规范
- TCP负责的内容本身就够过了
- 关注业务本身
- HTTP1.1
- 长连接
- 部分传输,返回码206
- HOST,区分同一个服务器,不同的服务
- 缓存,访问过的资源,可以在本地进行缓存,优先在缓存中查找,如果过期,再访问服务器
HTTPS
- 解密出来依然是HTTP
- 非对称加密 SSL/TLS
- 客户端发送,TLS版本/支持的密码套件列表/随机数
- 服务端,确认TLS版本/选择的密码套件(RSA/AES)/数字证书/随机数
- 客户端,校验数字证书,获取RSA公钥,并对新的随机数进行加密;根据AES算法和随机数,生成会话密钥,将内容摘要加密
- 服务端,校验摘要,RSA私钥解密随机数,生成会话密钥
- 开始通信
网络优化
HTTP2.0
- 多路复用,一个连接中并发多个请求和响应,不用按照顺序响应
- A请求耗时,可以先回应A处理好的部分,处理好B后,再处理A
- 头部压缩,客户端和服务端同时维护一张表,用赫夫曼编码
- 数据均为二进制格式
- 并发传输,一个TCP连接中有多个流,一个流中包含着请求和响应
- 客户端,流编号奇数;服务端,流编号偶数
- 一个TCP连接上,进行多个HTTP连接
- sack方法,标记接收到的数据包
- 缺点
- 其中一个stream中丢包了,需要全部重发,导致队头阻塞,会阻塞在TCP层
- 网络迁移需要重新连接
QUIC/HTTP3.0
- 基于UDP,在用户态实现
- 弱网传输
- 无队头阻塞,每个数据包都有唯一的标签,当数据包丢失后,只阻塞该数据包的流
- 更快的建立连接,基于ECDHE算法,TLS1.3,一个RTT就能开始数据传输,第二次连接时,只需携带QUIC信息和数据包,达到0RTT建立连接
- 网络迁移无需重新连接,连接时会生成连接ID,只需验证连接ID
数据中心的分布
- 服务器集合的地方
- 核心机房,存储核心数据
- POP接入,跟运营商和互联网交互
- 边缘机房,更靠近用户,绑定运营商
同运营商访问
- 电信访问电信的服务器,移动访问移动的服务器
- 国内跨网访问比较慢
- 通过域名解析,解析到目标的运营商
CDN路径优化
- 针对静态资源
- 在边缘机房中进行缓存,是否有其他用户访问过的内容
- 层层上去找
DSA路径优化
- 针对动态资源,使用一个小文件放置在源服务器上进行探测
- 路径访问的距离和时间最快
- 对周围的机房做网络探测,结合延时通过算法,找到最优路径
容灾概念
- 故障发生
- 鼓掌感知,通过监控,感知故障
- 自动切换,及时下线故障节点
- 服务恢复
案例
- 外网容灾,专线不可用,通过外网
- 调度容灾,同一个域名对应多个具体机房,如果一个节点发生故障,分配给另一个节点
- GTM,Global Traffic Manager,全局流量管理,DNS解析给用户返回最佳的IP,会对所有资源进行健康检查,发现故障就从其中删除
- 在分配前,进行探测,要确保另一个节点能承载故障节点的流量
- TNC云控系统,云到端,通过内嵌的AppSKD控制,主动降级/容灾
- 用户禁止执行某些节点切换命令
- 通过web访问节点,SDK不能控制
- 代码有bug,APP崩了,在最前端,做逻辑兜底,进行降级
故障排查
- 故障明确
- 故障体现在哪里
- 访问其他目标是否正常
- 是否是修改导致的异常
- 故障止损
- 用户体验第一
- 降级/组件系统容灾
- 分段排查
- 客户端排查,客户端访问其他服务是否有问题;其他客户端访问本服务
- 服务端排查,监控/指标,手动访问,分组件排查
- 中间链路排查,中间网络设备/旁路DNS
案例
- 健康检查服务异常,错误下线健康的服务器节点
- 客户端个例异常,防火墙配置问题
- 硬件传输电缆被挖断
- 服务正常,网络设备异常,抓包查看
快速发包,默认路由对称,导致不能解析MAC地址
HTTP框架
- 字节内部
Hertz - HTTP,Hypertext Transfer Protocol,超文本传输协议,属于第七层应用层
- 超文本,视频/声音/图片/超链接也可以作为文本内容
- 协议,双方均能解析出对应的内容,明确的边界
- 结构
- 请求行,方法名/URL/协议版本;状态行,协议版本/状态码/状态码描述
- 请求头;响应头,请求/响应参数
- 请求体;响应体
- 版本迭代
- HTTP1,队头阻塞,传输效率低,明文传输不安全
- HTTP2,多路复用,头部压缩,二进制协议
- HTTP3/QUCI,基于UDP,解决对头压缩,加密次数减少
分层
- 应用层
- 合理的API,可理解性、简单性、去冗余性、兼容性、可测性、可见性
- 中间件层,将核心逻辑和通用逻辑解耦
- 完整的请求处理完整周期
- 拥有预处理逻辑和后处理逻辑
- 可以注册多中间件
- 对上层模块用户模块易用
- 路由,为URL,匹配对应的处理函数
map<mehod, 路由前缀树>的形式,构建方法与url的关系
- 协议层
- 抽象出合适的接口
- 传输层
- BIO,阻塞式IO
- NIO,非阻塞IO,
netpoll
性能
网络库的优化
- 为每个连接绑定一块缓冲区
- 存下全部的header,拷贝出完整的body
根据历来的请求,估算buffer大小,用足够大的buffer,减少拷贝
针对协议的优化
- headers解析
- 优化寻找边界,先找到\n,查看前面是不是\r
- simd加速,
sonic字节的Golang JSON库- 针对核心字段,快速解析
- 高频header,额外存储,方便取
- 热点资源池化
- RequestContext池
- 减少内存分配,提高内存复用,降低GC压力
- 需要额外reset