服务注册(service register)
- 通过反射实现服务注册功能
- 在服务端实现服务调用
结构体映射为服务
RPC 框架的一个基础能力是:像调用本地程序一样调用远程服务。那如何将程序映射为服务呢?那么对 Go 来说,这个问题就变成了如何将结构体的方法映射为服务。
net/rpc- the method’s type is exported. – 方法所属类型是导出的。
- the method is exported. – 方式是导出的。
- the method has two arguments, both exported (or builtin) types. – 两个入参,均为导出或内置类型。
- the method’s second argument is a pointer. – 第二个入参必须是一个指针。
- the method has return type error. – 返回值为 error 类型。
通过反射实现 service
service.goservice.go
集成到服务端
service.callserver.goreadRequesthandleRequestRegister超时处理(timeout)
- 增加连接超时的处理机制
- 增加服务端处理超时的处理机制
超时处理是 RPC 框架一个比较基本的能力,如果缺少超时处理机制,无论是服务端还是客户端都容易因为网络或其他错误导致挂死,资源耗尽,这些问题的出现大大地降低了服务的可用性。因此,我们需要在 RPC 框架中加入超时处理的能力。
纵观整个远程调用的过程,需要客户端处理超时的地方有:
- 与服务端建立连接,导致的超时
- 发送请求到服务端,写报文导致的超时
- 等待服务端处理时,等待处理导致的超时(比如服务端已挂死,迟迟不响应)
- 从服务端接收响应时,读报文导致的超时
需要服务端处理超时的地方有:
- 读取客户端请求报文时,读报文导致的超时
- 发送响应报文时,写报文导致的超时
- 调用映射服务的方法时,处理报文导致的超时
GinRPC 在 3 个地方添加了超时处理机制。分别是:
Client.Call()Server.handleRequest创建连接超时
为了实现上的简单,将超时设定放在了 Option 中。ConnectTimeout 默认值为 10s,HandleTimeout 默认值为 0,即不设限。
客户端连接超时,只需要为 Dial 添加一层超时处理的外壳即可。
client.go
dialTimeoutnet.Dialnet.DialTimeouttime.After()Client.Call 超时
Client.Call服务端处理超时
time.After()select+chanserver.go
sendResponsecalledsenttime.After()case <-time.After(timeout)sendResponse