“这是我参与「第五届青训营 」伴学笔记创作活动的第 13 天”
1.3 RPC关键五大指标分析
1.3.1 稳定性
1、稳定性-保障策略
- 1)熔断:
- A调用B,B调用从c,熔断是为了防止C的超时响应链路影响到A以及更多服务器;
- 2)限流:
- 当调用端发送请求,服务端会先检查限流逻辑,如果发现访问量过大并且超过了限流条件,就让服务端直接降级处理或者返回给调用方一个限流异常;
- 3)超时:
- 当下游服务因为某种原因响应过慢,下游服务主动停掉一些不太重要业务,释放服务器资源,避免浪费资源;
从某种程度上讲,超时、限流、熔断是一种服务降级的手段;
2、稳定性-请求成功率
3、稳定性-长尾请求
- 长尾请求
- 长尾请求一般是指明显高于均值的那部分占比较小的请求。业界关于延迟有一个常用的P99标准, P99单个请求响应耗时从小到大排列,顺序处于99%位置的值即为P99值,那后面这1%就可以认为是长尾请求。在较复杂的系统中,长尾延时总是会存在。造成这个的原因非常多,常见的有网络抖动,GC,系统调度。
- 处理:
- 我们预先设定一个阈值t3(比超时时间小,通常建议是RPC-请求延时的pct99 ),当Req1发出去后超过t3时间都没有返回,那我们直接发起重试请求Req2,这样相当于同时有两个请求运行。然后等待请求返回,只要Resp1或者Resp2任意一个返回成功的结果,就可以立即结束这次请求,这样整体的耗时就是t4,它表示从第一个请求发出到第一个成功结果返回之间的时间,相比于等待超时后再发出请求,这种机制能大大减少整体延时。
4、稳定性-注册中间件
- 通过中间件,注入稳定性策略
1.3.2 易用性
1.3.3 扩展性
- 中间middleware执行;
- 例如服务发现、路由、负载均衡、超时控制等;
1.3.4 观测性
- 除了传统的Log.Metric、Tracing 三件套之外,对于框架来说可能还不够,还有些框架自身状态需要暴露出来,例如当前的环境变量、配置、Client/Server初始化参数.缓存信息等
1.3.5 高性能
- 高性能意味着高吞吐和低延迟,两者都很重要,甚至大部分场景下低延迟更重要。
1、多路复用
- 调用端向服务端的一个节点发送请求,并发场景下,
- 如果是非连接多路复用,每个请求都会持有一个连接,直到请求结束连接才会被关闭或者放入连接池复用,并发量与连接数是对等的关系。
- 而使用连接多路复用,所有请求都可以在一个连接上完成。
1.3.6 小结
1.4 RPC企业实践
1.4.1 整体架构-Kitex
- modules就是中间件服务,服务发现、熔断等;
- remote是与对端交互的模块,包括编解码和网络通信;
- 蓝色最下面是网络库;
1.4.2 自研网络库
1、自研网络库-背景
- 1.Go Net使用Epoll ET , Netpoll使用LT。
- 2.Netpoll在大包场景下会占用更多的内存
- 3.Go Net只有一个Epoll事件循环(因为ET模式被唤醒的少,且事件循环内无需负责读写,所以干的活少),而Netpoll允许有多个事件循环(循环内需要负责读写,干的活多,读写越重,越需要开更多 Loops)。
- 4.Go Net一个连接一个Goroutine,Netpoll连接数和Goroutine数量没有关系,和请求数有一定关系,但是有Gopool重用
- 5.Go Net不支持Zero Copy,甚至于如果用户想要实现BufferdConnection这类缓存读取,还会产生二次拷贝。Netpoll支持管理一个Buffer池直接交给用户,且上层用户可以不使用Read(p [byte)接口而使用特定零拷贝读取接口对 Buffer进行管理,实现零拷贝能力的传递。
2、自研网络库-Netpoll
- netpoll基于epoll,同时采用Reactor模型,对于服务端则是主从Reactor模型,如右图所示:服务端的主reactor用于接受调用端的连接,然后将建立好的连接注册到某个从Reactor上,从Reactor负责监听连接上的读写事件,然后将读写事件分发到协程池里进行处理。