远程函数调用 RPC
- 需要解决问题
- 函数映射
- 数据转换成字节流
- 网络传递
- RPC 概念模型
- RPC 完整过程
- IDL文件
- 生成代码
- 编解码
- 通信协议:规范数据在网络中的传输内容与格式
- 网络传输:基于成熟的网络库走TCP/UDP
- 好处
- 单一职责,利于分工协作运维开发
- 可扩展性强,资源使用率更有
- 故障隔离,服务的整体可靠性更强
- 问题
- 服务待机
- 调用过程中发生网络异常,如何保证消息的可达性
- 请求量突增导致服务无法及时处理,有哪些应对措施
分层设计
以Apache Thrift为例
- 编解码层
- 生成代码
- 数据格式
- TLV编码
- tag:标签
- lenght:长度
- value:值
- 选型
- 兼容性,通用性,性能
- 协议层
- 概念
- 特殊结束符
- 变长协议
- 协议构造
- length
- header magic
- sequence number
- header side
- protocol id
- transform id
- info id
- payload:消息体
- 协议解析
- magicnumber -> payloadcode -> payload
- 概念
- 网络通信层
- sockets api
- 网络库
构建RPC关键指标
- 稳定性
- 保障策略
- 熔断
- 限流
- 超时控制
- 请求成功率
- 负载均衡
- 重试
- 长尾请求
- 注册中间件
- 保障策略
- 易用性
- 默认参数,生成代码工具,脚手架工具
- 拓展性
- middleware
- option
- 编解码层
- 协议层
- 网络传输层
- 代码生成工具插件扩展
- 观测性
- log,metric,tracing
- 内置观测性服务
- 高性能
- 场景,目标,手段
企业实践
- Kitex
- Kitex core:核心组件
- Kitex Byted:与公司内部基础设施集成
- Kitex Tool:代码生成工具
- 自研网络库
- Netpoll
- 解决无法感知连接状态问题,epoll
- 解决goroutine暴涨的风险
- 提高性能
- Netpoll
- 扩展性设计
- 性能优化
- 网络库优化
- 调度优化
- LinkBuffer
- Pool
- 编解码优化
- Codegen
- JIT
- 网络库优化
- 合并部署
- 远程RPC调用优化为本地IPC调用
HTTP协议
超文本传输协议
协议要素
- 请求行/状态行
- 方法名/状态码
- get,head,post
- URL/状态码描述
- 协议版本
- 方法名/状态码
- 请求头/响应头
- 请求体/响应体
请求流程
- 业务层
- 服务治理层,中间件层
- 路由层(serve)
- 协议编(解)码层
- 传输层
HTTP框架设计与实现
分层设计
OSI七层网络模型,TCP/IP四层概念模型
- 应用层
- 提供合理API
- 可理解性 简单性 冗余性 兼容 可测性 可见性
- 提供合理API
- 中间件层
- 中间层需求
- 配合Handler实现一个完整请求处理生命周期
- 拥有预处理逻辑与后处理逻辑
- 很像调用了一个函数
- index保证递增
- index设置最大值(调用链,问题:不在一个调用栈上
- 可注册多中间件
- 对上层模块用户逻辑模块易用
- 中间件设计
- 洋葱模型;核心逻辑和通用逻辑分离
- 中间层需求
- 路由层( 实际是为URL匹配对应的处理函数
- 路由设计
- 静态路由:
map[string]handlers - 动态路由:前缀匹配树
- 参数路由:匹配树
- 静态路由:
- 匹配HTTP方法(路由映射表:MAP|Method|前缀树|头节点
- 外层MAP:根据method进行初步筛选
- 多处理
- 每个节点使用一个list存储handler
- 路由设计
- 协议层
- 抽象出合适的接口
- 需要在连接上读写数据
- 抽象出合适的接口
- 网络层
- BIO(阻塞IO)
- go net
- NIO唤醒
- netpoll
- BIO(阻塞IO)
- common公共逻辑