RPC 的基本概念
-
RPC的概念模型:User、User-Stub、RPC-Runtime、Server-Stub、Server
-
IDL(Interface Definition Language) 文件
- Thrift
- Protobuf
- 生成代码
- 编解码(序列化/反序列化)
-
通信协议
- 应用层协议
-
网络通信
-
IO 网络模型
- blocking IO
- unblocking IO
- IO multiplexing
- signal driven IO
- asynchronous IO
-
传输层协议
- TCP
- UDP
-
- 框架文档 Kitex
-
自研网络库 Netpoll,背景:
a. 原生库无法感知连接状态
b. 原生库存在 goroutine 暴涨的风险
- 扩展性:支持多协议,也支持灵活的自定义协议扩展
-
性能优化,参考 字节跳动 Go RPC 框架 KiteX 性能优化实践
a. 网络优化
- i. 调度优化
- ii. LinkBuffer 减少内存拷贝,从而减少 GC
- iii. 引入内存池和对象池
b. 编解码优化
- i. Codegen:预计算提前分配内存,inline,SIMD等
- ii. JIT:无生产代码,将编译过程移到了程序的加载(或首次解析)阶段,可以一次性编译生成对应的 codec 并高效执行
-
合并部署
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的核心概念和运作方式。
七、未来发展趋势
课程最后,我们还对RPC技术的未来发展趋势进行了展望。随着微服务架构的兴起和物联网、边缘计算等领域的发展,RPC技术也在不断演进。了解这些趋势,使我对自己的职业规划有了更明确的方向。