字节内部课程学习

一.走进RPC框架

1.基本概念

本地函数调用 压栈弹出

RPC调用 网上购物 {(付款操作)

远程调用 中间隔着网路 不能用函数指针了 是两个进程 机器id找到函数运行

解决问题 1. 函数映射

  1. 数据转换成字节流 (客户端转换成字节流 传送给 服务端)
  2. 网络传输(高效稳定传输数据)

}

示例图片

过程:User本地调用 打包参数 -》 RPC -》 对端-》解压-》调用真正业务逻辑 然后在返回 整个流程

IDL文件(接口描述文件)

image-20241107104049573

Caller(调用段)和 生成代码 -》 encoder编码 -》字节流 -》打包传送给对端

好处

image-20241107104333574

image-20241107111602308

image-20241107111758336

2.编解码层:

image-20241107111909320

编解码层:

image-20241107111950413

二进制编码

image-20241107112146078

左侧是IDL中写的统一的 -》字节流 有额外的内存开销

image-20241107112827203

image-20241107112953295

多路复用:同一个链接内 可以有多个请求流通过

协议解析:

image-20241107113245207

4.网络通信层:

image-20241107113347859

SCOEKT API (ip+端口)

一端关闭套接字 如果另一端如果尝试去读 可能就会返回(End Of File)也就是 EOF 在项目中我好像遇到过这个问题 用postman测试的时候返回了EOF错误和nil

网络库

image-20241107113810046

二.RPC关键指标分析与企业实践

稳定性 易用性 扩展性 观测性 高性能

稳定性:

image-20241107114134948

过程:a调用b b调用c c如果响应慢 b就会一直等待 a也就超时了 a就会频繁调用b b堆积大量请求就会宕机

熔断起保护作用

稳定性:请求成功了率

image-20241107114404973

1.均匀调用服务的每个节点

  1. 重试几次

image-20241107114611581

备份请求: 左侧正常 1失败 2是重试请求 总时间 t1+t2

​ 右侧 t3 tct99(这个值 在这个时间内应该可以返回值)如果在时间内没返回 就发送2请求 总时间就是 t4

1.注册中间件

image-20241107114931005

2.易用性:

image-20241107115019715

自动生成代码工具 : 减少重复性工作

3.扩展性

image-20241107115236618

用户请求 经过中间件处理-》和远端交互 -》 也通过中间件处理-》服务器

4.观测性:

image-20241107115409542

日志观察 监控面板qbs 链路跟踪(服务通过请求为什么超时了 耗费的时间是多少)

linux的top工具类似原理

5.高性能:

image-20241107115628087

高吞吐:在单位时间内尽可能多的处理更多请求

低延迟: 一次请求发出去延迟尽可能地低(重要)

6. 本章总结:

image-20241107115938337

字节实践:

image-20241107120230033

组件 结构 远端交互层 网络库 代码生成工具 (最左侧)

为什么自研网络库?

gonet

image-20241107120515080

Netpoll

image-20241107120603540

image-20241107120656906

交互方式pingpang(一发一回) 编解码 应用层协议

优化:

image-20241107120826363

image-20241107120948515

你应该想这些是怎么实现的?

image-20241107121448901

image-20241107121741751

三.走进HTTP协议

1.再谈http协议

HTTP 超文本传输协议

image-20241108133154991

http协议将人话以计算机语言传输过去

image-20241108133257828

1
2
3
4
5
6
7
8
9
请求行
:分隔 原数据

包的字节数
大空行

我们想说的话

下面是回复

image-20241108133725032

image-20241108133847415

上述功能代码:

image-20241108134149368

处理流程:

image-20241108134229285

H1的不足 H2也没完全解决 UDP解决对头阻塞

image-20241108134628306

四.HTTP框架实现

1.分层设计的好处

image-20241109154338484

高内聚 低耦合 易复用 高扩展性

image-20241109154510026

应用层

中间件层 预处理

路由层

协议层

中间件设计:

洋葱模型

image-20241121185257019

image-20241121185641849

路由设计: map[string]handlers 静态路由有效 动态不太行

前缀匹配树构建路由:

啊啊啊啊:前两天刚看 7_days_golang 构建动态路由的方法

这里就讲解了 啊啊啊

image-20241121190300522

参数路由:

协议层设计

网络层设计

image-20241121202157512

性能修炼之道

针对网络库的优化

netpoll (中大包性能高 时延低)

go net(流式友好,小包性能高)

存下全部Header

拷贝身体

针对协议的优化

Headers 解析

找到Header Line边界 /r/n

SIMD

Sonic

五.微服务架构:

单体架构 -》 垂直应用架构 -》 分布式架构 -》 SOA架构 -》 微服务架构

单体架构:

优势: 性能最高 冗余小

劣势: 1.debug困难 2.模块相互影响 3.模块

垂直应用架构:

优点: 业务独立开发维护

缺点 : 存在冗余

分布式架构:

image-20241122175120662

SOA架构:

image-20241122175312029

服务注册中心: 服务注册

劣势: 整个系统设计是中心化的

​ 需要从上至下设计

​ 重构困难

微服务架构:

image-20241122175442902

开发效率高

但是运维难度大

安全性

image-20241122175636816

image-20241122175816476

服务: 相同逻辑 的 运行实体

实例 : 每一个运行实体为一个实例

image-20241122180306396

逻辑划分称一个(集群) 集群包含实例

有状态 无状态服务: 是否存储了可持续化数据

服务间通信:

image-20241122180825079

HTTP RPC

目标服务地址:

hardcode

服务A调用服务B(指定一个目标服务地址会有什么问题?)

ip地址不会固定

image-20241122181602662

只有一个实例可以接受请求 别的接收不到

ip也是会变化的

如果用DNS域名来访问

DNS缓存机制: 导致延时

负载均衡问题:无法指定请求某个ip回应

不支持探活检查

域名无法配置端口

image-20241122182118324

负载均衡算法

若要 下线某个实例:

image-20241122182354705

流量会不会走到第三个实例上面

服务1 和 服务2 压力变大 可以在开启一个实例

image-20241122182554893

统一网关入口

四层负载均衡

租用了一台公网ip

现状 找一个物理机 ifconfig将网卡配上这个ip 起server监听即可

应用多 起多个server监听不同的端口

基于ip+端口 基于某种算法 将报文转发给后端服务器

image-20241123181002063

常见调度算法

RR轮询:

加权RR轮询:

最小连接

五元组hash

一致性hash

image-20241123181248969

FULLNAT

纯用户态协议栈

无缓存 零拷贝 大页内存 (减少 cache miss)

image-20241123181625438

7层负载均衡

image-20241123181812859

NGINX:

最灵活的高性能Web 7层反向代理

image-20241123182129083

网络接入实践与课程总结

image-20241123190541804

image-20241123190953261

七层负载均衡

image-20241123191212670

配置https访问

image-20241123191142306