gRPC是一个高性能、开源和通用的RPC框架,面向移动和HTTP/2设计。gRPC基于HTTP/2标准设计,带来诸如双向流、流控、头部压缩、单TCP连接上的多路复用请求等待。这些特性使得其在移动设备上表现更好,更省电和节省空间占用。

RPC

RPC(Remote Procedure Call Protocol) – 远程过程调用协议,他是一种通过网络从远程计算机上请求服务,而不需要了解底层网络技术的协议。

Golang本身有rpc包net/rpc,可以方便的使用,来构建自己的rpc服务。

RPC调用流程分析

RPC 远程过程调用流程图

  1. 调用客户端句柄;执行传送参数
  2. 调用本地系统内核发送网络消息
  3. 消息传送到远程主机
  4. 服务器句柄得到消息并取得参数
  5. 执行远程过程
  6. 执行的过程将结果返回服务器句柄
  7. 服务器句柄返回结果,调用远程系统内核
  8. 消息传回本地主机
  9. 客户端句柄由内核接收消息
  10. 客户接收句柄返回的数据

RPC调用示例

服务端

 1package main
 2
 3import (
 4	"io"
 5	"log"
 6	"net"
 7	"net/http"
 8	"net/rpc"
 9)
10
11type Hello string
12
13// 函数关键字 (对象) 函数名 (客户端发送过来的内容, 返回给对方的内容) 错误返回
14func (h *Hello) SayHello(recv string, reply *string) error {
15	log.Println("客户端发送过来的内容为:", recv)
16	*reply = "hello " + recv
17	return nil
18}
19
20func main() {
21	// 页面请求
22	http.HandleFunc("/hello", sayHello)
23
24	// 将类实例化为对象
25	hello := new(Hello)
26	// 服务端注册一个对象
27	rpc.Register(hello)
28	rpc.HandleHTTP()
29
30	ln, err := net.Listen("tcp", ":10000")
31	if err != nil {
32		log.Println(err)
33		return
34	}
35	http.Serve(ln, nil)
36}
37
38func sayHello(w http.ResponseWriter, r *http.Request) {
39	io.WriteString(w, "hello")
40}

客户端

 1package main
 2
 3import (
 4	"log"
 5	"net/rpc"
 6)
 7
 8func main() {
 9	// 建立网络连接
10	cli, err := rpc.DialHTTP("tcp", "127.0.0.1:10000")
11	if err != nil {
12		log.Printf("网络连接失败,err:%v\n", err)
13		return
14	}
15
16	var hello string
17	err = cli.Call("Hello.SayHello", "jerry", &hello)
18	if err != nil {
19		log.Printf("call failed, err:%v\n", err)
20		return
21	}
22	log.Println("Result:", hello)
23}

运行测试

服务端

1go run main.go
22020/03/14 17:26:03 客户端发送过来的内容为: jerry

客户端

1go run main.go
22020/03/14 17:26:03 Result: hello jerry

gRPC介绍

参见Go语言gRPC快速入门