RPC 原理与实践 | 青训营

91 阅读3分钟

RPC 的基本概念

  • IDL(Interface Definition Language) 文件

    • Thrift
    • Protobuf
  • 生成代码
  • 编解码(序列化/反序列化)
  • 通信协议

    • 应用层协议
  • 网络通信

    • IO 网络模型

      • blocking IO
      • unblocking IO
      • IO multiplexing
      • signal driven IO
      • asynchronous IO
    • 传输层协议

      • TCP
      • UDP

image.png

  1. 框架文档 Kitex
  1. 自研网络库 Netpoll,背景:

    a. 原生库无法感知连接状态
    b. 原生库存在 goroutine 暴涨的风险

  1. 扩展性:支持多协议,也支持灵活的自定义协议扩展
  1. 性能优化,参考 字节跳动 Go RPC 框架 KiteX 性能优化实践

    a. 网络优化

    • i. 调度优化
    • ii. LinkBuffer 减少内存拷贝,从而减少 GC
    • iii. 引入内存池和对象池

    b. 编解码优化

    • i. Codegen:预计算提前分配内存,inline,SIMD等
    • ii. JIT:无生产代码,将编译过程移到了程序的加载(或首次解析)阶段,可以一次性编译生成对应的 codec 并高效执行
  1. 合并部署

    a. 微服务过微,引入的额外的传输和序列化开销越来越大
    b. 将强依赖的服务统计部署,有效减少资源消耗

var msec = -1
for {
   n, err = syscall.EpollWait(epfd, events, msec)
   if n <= 0 {
      msec = -1
      continue
   }
   msec = 0
   ...
}

上述伪代码中,当无事件触发,调整 msec=-1 时,直接 continue 会立即再次执行 EpollWait,而由于无事件,msec=-1,当前 goroutine 会 block 并被 P 切换。但是被动切换效率较低,如果我们在 continue 前主动为 P 切换 goroutine,则可以节约时间。因此我们将上述伪代码改为如下:

var msec = -1
for {
   n, err = syscall.EpollWait(epfd, events, msec)
   if n <= 0 {
      msec = -1
      runtime.Gosched()
      continue
   }
   msec = 0
   ...
}

三、RPC框架与实现

课程中我们学习了多种RPC框架,如gRPC、Thrift等。通过实际动手,我们了解了如何在项目中引入并使用这些框架。同时,我们还深入探讨了框架背后的原理,比如gRPC的基于HTTP/2的多路复用,以及服务发现、负载均衡等关键概念。

四、服务治理与容错

在分布式系统中,服务的高可用性和容错机制至关重要。课程中,我们学习了服务注册与发现的原理,了解了ZooKeeper、Consul等工具的应用。此外,容错机制如超时处理、重试策略、熔断器等也在课程中得到了详细讲解。

五、安全与性能优化

随着分布式系统的复杂性增加,安全和性能问题愈发凸显。课程在这方面也给予了充分的关注。我们学习了如何保障通信的安全性,探讨了TLS/SSL的应用。同时,通过性能剖析工具,我们了解了如何找出性能瓶颈,并进行优化,以提供更高效的通信。

六、实战案例与项目

课程的高潮之一是实战案例和项目。我们在实际场景中应用所学知识,设计了一个分布式系统的通信模块。从架构设计、接口定义,到框架的选择和实现,每一步都让我更深刻地理解了RPC的核心概念和运作方式。

image-20230808114033876

七、未来发展趋势

课程最后,我们还对RPC技术的未来发展趋势进行了展望。随着微服务架构的兴起和物联网、边缘计算等领域的发展,RPC技术也在不断演进。了解这些趋势,使我对自己的职业规划有了更明确的方向。

参考资料:链接juejin.cn/post/719632… juejin.cn/post/726460…