0 目录
- 第一天 – 服务端与音讯编码 | Code
- 第二天 – 反对并发与异步的客户端 | Code
- 第三天 – 服务注册(service register) | Code
- 第四天 – 超时解决(timeout) | Code
- 第五天 – 反对 HTTP 协定 | Code
- 第六天 – 负载平衡(load balance) | Code
- 第七天 – 服务发现与注册核心(registry) | Code
1 谈谈 RPC 框架
RPC(Remote Procedure Call,近程过程调用)是一种计算机通信协议,容许调用不同过程空间的程序。RPC 的客户端和服务器能够在一台机器上,也能够在不同的机器上。程序员应用时,就像调用本地程序一样,无需关注外部的实现细节。
不同的应用程序之间的通信形式有很多,比方浏览器和服务器之间宽泛应用的基于 HTTP 协定的 Restful API。与 RPC 相比,Restful API 有绝对对立的规范,因此更通用,兼容性更好,反对不同的语言。HTTP 协定是基于文本的,个别具备更好的可读性。然而毛病也很显著:
- Restful 接口须要额定的定义,无论是客户端还是服务端,都须要额定的代码来解决,而 RPC 调用则更靠近于间接调用。
- 基于 HTTP 协定的 Restful 报文冗余,承载了过多的有效信息,而 RPC 通常应用自定义的协定格局,缩小冗余报文。
- RPC 能够采纳更高效的序列化协定,将文本转为二进制传输,取得更高的性能。
- 因为 RPC 的灵活性,所以更容易扩大和集成诸如注册核心、负载平衡等性能。
2 RPC 框架须要解决什么问题
RPC 框架须要解决什么问题?或者咱们换一个问题,为什么须要 RPC 框架?
咱们能够设想下两台机器上,两个应用程序之间须要通信,那么首先,须要确定采纳的传输协定是什么?如果这个两个应用程序位于不同的机器,那么个别会抉择 TCP 协定或者 HTTP 协定;那如果两个应用程序位于雷同的机器,也能够抉择 Unix Socket 协定。传输协定确定之后,还须要确定报文的编码格局,比方采纳最罕用的 JSON 或者 XML,那如果报文比拟大,还可能会抉择 protobuf 等其余的编码方式,甚至编码之后,再进行压缩。接收端获取报文则须要相同的过程,先解压再解码。
解决了传输协定和报文编码的问题,接下来还须要解决一系列的可用性问题,例如,连贯超时了怎么办?是否反对异步申请和并发?
如果服务端的实例很多,客户端并不关怀这些实例的地址和部署地位,只关怀本人是否获取到期待的后果,那就引出了注册核心 (registry) 和负载平衡 (load balance) 的问题。简略地说,即客户端和服务端相互不感知对方的存在,服务端启动时将本人注册到注册核心,客户端调用时,从注册核心获取到所有可用的实例,抉择一个来调用。这样服务端和客户端只须要感知注册核心的存在就够了。注册核心通常还须要实现服务动静增加、删除,应用心跳确保服务处于可用状态等性能。
再进一步,假如服务端是不同的团队提供的,如果没有对立的 RPC 框架,各个团队的服务提供方就须要各自实现一套音讯编解码、连接池、收发线程、超时解决等“业务之外”的反复技术劳动,造成整体的低效。因而,“业务之外”的这部分公共的能力,即是 RPC 框架所须要具备的能力。
3 对于 GeeRPC
Go 语言宽泛地利用于云计算和微服务,成熟的 RPC 框架和微服务框架车载斗量。grpc
、rpcx
、go-micro
等都是十分成熟的框架。一般而言,RPC 是微服务框架的一个子集,微服务框架能够本人实现 RPC 局部,当然,也能够抉择不同的 RPC 框架作为通信基座。
思考性能和性能,上述成熟的框架代码量都比拟宏大,而且通常和第三方库,例如 protobuf
、etcd
、zookeeper
等有比拟深的耦合,难以直观地窥视框架的实质。GeeRPC 的目标是以起码的代码,实现 RPC 框架中最为重要的局部,帮忙大家了解 RPC 框架在设计时须要思考什么。代码简洁是第一位的,性能是第二位的。
因而,GeeRPC 抉择从零实现 Go 语言官网的规范库 net/rpc
,并在此基础上,新增了协定替换 (protocol exchange)、注册核心(registry)、服务发现(service discovery)、负载平衡(load balance)、超时解决(timeout processing) 等个性。分七天实现,最终代码约 1000 行。
附 举荐浏览
- Go 语言扼要教程
- Go 语言口试面试题
原文地址: 7 天用 Go 从零实现 RPC 框架 GeeRPC – 极客兔兔
关注知乎: 极客兔兔
关注微博: @极客兔兔