从零实现GeeRPC框架:第一天构建服务端与消息编码
前言
在分布式系统中,远程过程调用(RPC)是一种常见的通信方式。本文将带领大家从零开始实现一个名为GeeRPC的RPC框架,第一天我们将聚焦于服务端基础架构和消息编码机制的实现。
RPC基础概念
RPC(Remote Procedure Call)允许程序像调用本地方法一样调用远程服务的方法。一个典型的RPC调用包含三个关键部分:
- 服务名和方法名
- 参数
- 返回值
在GeeRPC中,我们将这些信息抽象为Header和Body两部分,Header包含元数据,Body包含实际数据。
消息编码设计
Header结构设计
首先我们定义Header结构体:
type Header struct {
ServiceMethod string // 格式为"Service.Method"
Seq uint64 // 客户端选择的序列号
Error string // 错误信息
}
ServiceMethod
:标识要调用的服务和方法Seq
:请求的唯一标识符Error
:服务端返回的错误信息
编解码接口
为了实现灵活的编码方式,我们定义了Codec接口:
type Codec interface {
io.Closer
ReadHeader(*Header) error
ReadBody(interface{}) error
Write(*Header, interface{}) error
}
这个接口支持:
- 读取Header
- 读取Body
- 写入Header和Body
- 关闭连接
编解码工厂模式
我们采用工厂模式支持多种编码方式:
type NewCodecFunc func(io.ReadWriteCloser) Codec
type Type string
const (
GobType Type = "application/gob"
JsonType Type = "application/json"
)
var NewCodecFuncMap map[Type]NewCodecFunc
目前实现了Gob编码,未来可以轻松扩展JSON等其他编码方式。
Gob编码实现
Gob是Go语言自带的二进制序列化格式,我们基于它实现GobCodec:
type GobCodec struct {
conn io.ReadWriteCloser
buf *bufio.Writer
dec *gob.Decoder
enc *gob.Encoder
}
实现要点:
- 使用bufio.Writer缓冲提高性能
- 分离Decoder和Encoder分别处理读写
- 实现了完整的Codec接口方法
服务端实现
协议设计
客户端和服务端通信需要协商编码方式,我们定义Option结构:
type Option struct {
MagicNumber int // 标识GeeRPC请求
CodecType codec.Type // 编码类型
}
通信报文格式如下:
| Option | Header1 | Body1 | Header2 | Body2 | ...
服务端核心结构
服务端核心结构非常简单:
type Server struct{}
主要方法包括:
Accept
:接受连接并处理ServeConn
:处理单个连接serveCodec
:使用指定编解码器处理请求
请求处理流程
- 首先解析Option确定编码方式
- 循环读取请求(readRequest)
- 并发处理请求(handleRequest)
- 顺序回复请求(sendResponse)
关键点:
- 使用协程并发处理请求提高性能
- 使用互斥锁保证回复顺序
- 使用WaitGroup等待所有请求处理完成
请求数据结构
type request struct {
h *codec.Header
argv, replyv reflect.Value
}
目前argv和replyv都简单处理为字符串,后续会改进。
示例演示
我们实现了一个简单的客户端和服务端交互示例:
服务端:
func startServer(addr chan string) {
l, _ := net.Listen("tcp", ":0")
addr <- l.Addr().String()
geerpc.Accept(l)
}
客户端:
conn, _ := net.Dial("tcp", <-addr)
cc := codec.NewGobCodec(conn)
// 发送请求并接收响应
总结
第一天我们实现了:
- 基于Gob的消息编解码器
- 服务端基础架构
- 简单的协议协商机制
- 请求处理流程
虽然目前功能还比较简单,但已经建立了RPC框架的核心骨架。在后续开发中,我们将逐步完善客户端实现、服务注册、超时处理等高级特性。
完整代码约200行,涵盖了RPC框架最基础的功能。通过这个实现,我们可以深入理解RPC框架的工作原理,为后续扩展打下坚实基础。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考