这是我参与[第三届青训营-后端场]笔记创作活动的第3篇笔记
实现RPC调用需要具备的三个功能
- 函数映射
- 数据和字节流的转换
- 网络传输
RPC过程
- IDL->生成代码->编解码->通信协议->网络传输 IDL:接口定义文件,如proto和thrift 生成代码:protobuf和thrift有对应的编译器,可以自动生成代码 编解码:可读性强的有json,xml等;还有语言专属的编解码,例如go的gob;二进制编解码有protobuf和thrift
RPC的优点
- 单一职责,一个模块对应一个服务
- 可扩展性强,资源利用率高
- 故障隔离,可靠性强
使用RPC要注意的问题
- 服务宕机
- 如何保证消息可达
- 请求量徒增
RPC分层设计
编解码层
- TLV编码。Tag:标签 Length:长度 Value:值(也可以是TLV)
- 编解码层的选型指标:兼容性,通用性,性能。
协议层
- 特殊符号结尾
- 不定长,例如|length|value|length|value格式
网络通信层
- 使用SocketAPI
RPC关键指标
- 稳定性:熔断,限流,超时控制,负载均衡,重试(例如错误重试,或者长尾请求设置超时时间重试),这些策略通过中间件注册到RPC服务中。
- 易用性:开箱即用,周边工具(代码生成、脚手架工具)
- 扩展性:middleware,option,编解码层,协议层,网络传输,代码生成扩展工具都不是写死的。
- 观测性:log,metric,tracing(链式跟踪)、内置观测服务(即时报警)
- 高性能:目标(高吞吐,低延迟),手段(连接池,多路复用,高性能编解码协议protobuf或thrift,高性能网络库(epoll))
高性能网络库
- epoll主动监听机制,感知连接状态
- goroutine池
- 内存池、对象池,减少GC开销
- 引入NoCopy Buffer,实现编解码层面零拷贝
服务注册,服务发现
负载均衡策略:轮询,加权轮询,一致性哈希
服务治理
- 服务发布:将一个服务升级运作新的代码的过程。
- 难点:服务不可用,服务抖动,服务回滚
- 解决:蓝绿部署(需要两倍资源);灰度发布(金丝雀发布,先部署一个测试是否可用)
- 流量治理:地区、集群、实例、请求等维度进行流量的分配
- 负载均衡:轮询,加权轮询,一致性哈希
- 稳定性治理:限流,过载保护,降级,熔断。(服务降级是将一个服务的非核心接口关闭,服务还能执行核心功能;熔断是将整个服务关闭,无法正常提供服务)