7天用Go动手写/从零实现RPC框架GeeRPC

geerpc.jpg

0 目录

1 谈谈 RPC 框架

RPC(Remote Procedure Call,远程过程调用)是一种计算机通讯协议,容许调用不一样进程空间的程序。RPC 的客户端和服务器能够在一台机器上,也能够在不一样的机器上。程序员使用时,就像调用本地程序同样,无需关注内部的实现细节。html

不一样的应用程序之间的通讯方式有不少,好比浏览器和服务器之间普遍使用的基于 HTTP 协议的 Restful API。与 RPC 相比,Restful API 有相对统一的标准,于是更通用,兼容性更好,支持不一样的语言。HTTP 协议是基于文本的,通常具有更好的可读性。可是缺点也很明显:程序员

  • Restful 接口须要额外的定义,不管是客户端仍是服务端,都须要额外的代码来处理,而 RPC 调用则更接近于直接调用。
  • 基于 HTTP 协议的 Restful 报文冗余,承载了过多的无效信息,而 RPC 一般使用自定义的协议格式,减小冗余报文。
  • RPC 能够采用更高效的序列化协议,将文本转为二进制传输,得到更高的性能。
  • 由于 RPC 的灵活性,因此更容易扩展和集成诸如注册中心、负载均衡等功能。

2 RPC 框架须要解决什么问题

RPC 框架须要解决什么问题?或者咱们换一个问题,为何须要 RPC 框架?golang

咱们能够想象下两台机器上,两个应用程序之间须要通讯,那么首先,须要肯定采用的传输协议是什么?若是这个两个应用程序位于不一样的机器,那么通常会选择 TCP 协议或者 HTTP 协议;那若是两个应用程序位于相同的机器,也能够选择 Unix Socket 协议。传输协议肯定以后,还须要肯定报文的编码格式,好比采用最经常使用的 JSON 或者 XML,那若是报文比较大,还可能会选择 protobuf 等其余的编码方式,甚至编码以后,再进行压缩。接收端获取报文则须要相反的过程,先解压再解码。面试

解决了传输协议和报文编码的问题,接下来还须要解决一系列的可用性问题,例如,链接超时了怎么办?是否支持异步请求和并发?浏览器

若是服务端的实例不少,客户端并不关心这些实例的地址和部署位置,只关心本身可否获取到期待的结果,那就引出了注册中心(registry)和负载均衡(load balance)的问题。简单地说,即客户端和服务端互相不感知对方的存在,服务端启动时将本身注册到注册中心,客户端调用时,从注册中心获取到全部可用的实例,选择一个来调用。这样服务端和客户端只须要感知注册中心的存在就够了。注册中心一般还须要实现服务动态添加、删除,使用心跳确保服务处于可用状态等功能。服务器

再进一步,假设服务端是不一样的团队提供的,若是没有统一的 RPC 框架,各个团队的服务提供方就须要各自实现一套消息编解码、链接池、收发线程、超时处理等“业务以外”的重复技术劳动,形成总体的低效。所以,“业务以外”的这部分公共的能力,便是 RPC 框架所须要具有的能力。并发

3 关于 GeeRPC

Go 语言普遍地应用于云计算和微服务,成熟的 RPC 框架和微服务框架汗牛充栋。grpcrpcxgo-micro 等都是很是成熟的框架。通常而言,RPC 是微服务框架的一个子集,微服务框架能够本身实现 RPC 部分,固然,也能够选择不一样的 RPC 框架做为通讯基座。负载均衡

考虑性能和功能,上述成熟的框架代码量都比较庞大,并且一般和第三方库,例如 protobufetcdzookeeper 等有比较深的耦合,难以直观地窥视框架的本质。GeeRPC 的目的是以最少的代码,实现 RPC 框架中最为重要的部分,帮助你们理解 RPC 框架在设计时须要考虑什么。代码简洁是第一位的,功能是第二位的。框架

所以,GeeRPC 选择从零实现 Go 语言官方的标准库 net/rpc,并在此基础上,新增了协议交换(protocol exchange)、注册中心(registry)、服务发现(service discovery)、负载均衡(load balance)、超时处理(timeout processing)等特性。分七天完成,最终代码约 1000 行。异步

附 推荐阅读

原文地址: 7天用Go从零实现RPC框架GeeRPC - 极客兔兔
关注知乎: 极客兔兔
关注微博: @极客兔兔