这是我参与「第五届青训营 」伴学笔记创作活动的第 14 天。
01. 基本概念
1.1 本地函数调用
1.2 远程函数调用(RPC - Remote Procedure Calls)
RPC需要解决的问题
- 函数映射
- 数据转换成字节流
- 网络传输
1.3 RPC概念模型
1.4 一次RPC的完整过程
IDL(Interface description language)文件
生成代码
编解码:也常叫做序列化和反序列化
通信协议
网络传输:通常基于成熟的网络库走TCP/UDP传输
1.5 RPC的好处
- 单一职责,有利于分工协作和运维开发
- 可扩展性强,资源使用率更优
- 故障隔离,服务的整体可靠性更高
1.6 RPC带来的问题
- 服务宕机
- 在调用过程中发生网络异常,如何表征消息的可达性
- 请求量突增导致服务无法及时处理
02. 分层设计
编解码层 | 协议层 | 网络通信层
2.1 分层设计-以Apache Thrift为例
2.2 编解码层
依赖同一份IDL文件,生成不同语言的CodeGen
· 语言特定的格式
· 文本格式,具有人类可读性
· 二进制编码
· TLV编码
编码层选型:兼容性、通用性、性能
2.7 协议层
· 特殊结束符
· 变长协议
2.12 网络通信层 - Sockets API
网络库:提供易用API、功能、性能
03. 关键指标
稳定性 | 易用性 | 扩展性 | 观测性 | 高性能
3.1 稳定性
· 熔断
· 限流
· 超时控制
负载均衡、重试
长尾请求:响应时间很久的请求
3.5 易用性
开箱即用、周边工具
3.7 观测性
· Log、Metric、Tracing
· 内置观测性服务
3.8 高性能
04. 企业实践
整体架构 | 自研网络库 | 扩展性设计 | 性能优化 | 合并部署
4.1 整体架构 - Kitex
4.2 自研网络库 - 背景
· 原生库无法感知连接状态
· 原生库存在goroutine暴涨的风险
4.3 自研网络库 - Netpoll
· 解决无法感知连接状态的问题
· 解决goroutine暴涨的风险
· 提升性能
4.4 扩展性设计
4.5 性能优化 - 网络库优化
· 调度优化
· LinkBuffer
· Pool
编解码优化
· Codegen
· JIT
4.7 合并部署
微服务过微,传输和序列化开销越来越大
将亲和性强的服务实例极可能调度到同一个物理机,远程RPC调用优化为本地IPC调用