RPC框架和笔记服务项目| 青训营笔记

147 阅读3分钟

这是我参与「第三届青训营 -后端场」笔记创作活动的的第7篇笔记

GO-学习笔记

RPC框架

  • RPC Remote Procedure Calls,远程函数调用
  1. 函数映射
  2. 数据转换成字节流
  3. 网络传输
  • 优点
  1. 单一职责,利于分工协作
  2. 可扩展性强,资源使用率高
  3. 故障隔离,服务整体可靠性高
  • 弊端
  1. 服务宕机
  2. 跨网络,保证消息可达性
  3. 流量突增导致服务器不能及时处理

结构

  • IDL调用方和被调用方都要依赖这个文件
  • TLV编码层
  1. Tag,标签/类型
  2. Length,长度
  3. Value,值
  • 协议层
  1. 特殊结束符,每个协议单元的结束
  2. 变长协议,定长部分描述不定长部分的长度
  • 网络通信层
  1. sockets API,在应用层和传输层之间

关键指标

  • 稳定性
  1. 熔断,保护调用方,防止被调用的服务出现问题,影响链路
  2. 限流,保护被调用方,防止大流量把服务压垮
  3. 超时控制,避免浪费资源在不可用的节点
  4. 请求成功率,负载均衡/重试
  5. 长尾请求,高于平均请求时间的请求,利用backup request,在请求超时时,在发送一个
  • 易用性
  1. 开箱即用
  2. 周边工具
  • 扩展性
  1. 中间件
  2. 参数
  3. 编解码层
  4. 协议层
  5. 网络传输层
  6. 代码生成工具插件扩展
  • 观测性
  1. log(日志)/metric(计算、耗时)/tracing(追踪)
  2. 内置观测性服务
  • 高性能
  1. 高吞吐、低延迟
  2. 连接池、多路复用、高性能编解码、高性能网络库
  3. 多请求类型

Kitex

整体架构

  • Kitex Core核心组件
  • Kitex Byted公司内部集成设施
  • Kitex Tool代码生成工具

自研网络库

  • 原生库的问题
  1. 无法感知连接状态
  2. 存在goroutine暴涨的风险,连接利用率低
  • Netpoll
  1. epoll主动监听机制,事件推送
  2. goroutine池,复用goroutine
  3. 引入Nocopy Buffer,编解码层实现零拷贝

扩展性

  • 灵活的自定义协议扩展
  • 请求 ping-pong/streaming/Oneway
  • 编解码 Codec Thrift/protobuf,Thrift更紧凑
  • 应用层 Application TTHeader/HTTP2
  • 传输层 Transport TCP/UDP/RDMA

优化

  • 网络库
  1. 调度优化,epoll/gopoll(重用goroutine),降低同时运行协程数
  2. LinkBuffer 读写并行无锁,支持nocopy/高效扩缩容
  3. Pool,引入内存池和对象池,减少GC开销
  • 编解码优化
  1. Codegen,预计算并预分配内存,减少内存操作次数;inline内联减少函数调用次数和避免不必要的反射;自研Thriftgo代码生成器,支持完善的Thrifit IDL语法和语义检查
  2. JIT,即时编译,代码运行时再去进行编解码;自研Thrift编解码器Frugal

合并部署

  • 将亲和性强的服务实例调度到同一个无理解,远程调用RPC优化为本地IPC调用
  • 中心化部署调度和流量控制
  • 基于共享内存的通信协议
  • 定制化的服务发现和连接池实现
  • 定制化的服务启动和监听逻辑

笔记项目

Kitex

  • RPC框架,接口式编程
  • IDL Interface Definition Language 接口定义语言
  • Kitex使用

Etcd

  • 注册中心,类似zookeeper的角色,服务注册和调用

Opentracing

  • Jaeger
  • 分布式追踪链路
  • 每个服务的执行情况

项目

  • 路径bizdemo/easy_note
  • 结构

dubbo注册到zookeeper,业务层直接调用 image.png

  • 技术栈 image.png

项目目录

  • idl统一接口,有kitex自动生成
  • pkg
  1. errno 错误码
  2. contants 常量
  3. middleware 中间件扩展
  4. tracer 初始化Jaeger
  5. bound TLS限流
  • note/user
  1. dal数据库
  2. pack 类型转换
  3. rpc相关,初始化user的服务
  4. service基础服务
  5. handler.go实现rpc接口