【GO开发工程师】RPC 详解#golang
推荐个人主页: 席万里的个人空间
文章目录
一、什么是rpc?rpc开发的挑战是什么?
1、什么是rpc?
RPC原理图
- rpc(Remote Procedure Call)远程过程调用,简单的理解是一个节点请求另一个节点提供的服务。
- 对应rpc的是本地过程调用,函数调用是最常见的本地过程调用。
- 将本地过程调用变成远程过程调用会面临各种问题。
2、远程过程面临的问题?
- 原本的本地函数放到另一个服务器运行。
- Call的id映射。
- 序列化和反序列化。
- 网络传输。
二、通过http实现add服务端/客户端
1、服务端
package main
import (
"encoding/json"
"fmt"
"net/http"
"strconv"
)
func main() {
// http://127.0.0.1:8080/add?a=1&b=2
http.HandleFunc("/add", func(w http.ResponseWriter, r *http.Request) {
_ = r.ParseForm() //解析参数
fmt.Println("path:", r.URL.Path)
a, _ := strconv.Atoi(r.Form["a"][0])
b, _ := strconv.Atoi(r.Form["b"][0])
w.Header().Set("Content-Type", "application/json")
jData, _ := json.Marshal(map[string]int{
"data": a + b,
})
_, _ = w.Write(jData)
})
http.ListenAndServe(":8080", nil)
}
运行结果:
2、客户端
type ResponseData struct {
Data int `json:"data"`
}
func Add(a, b int) int {
req := HttpRequest.NewRequest()
res, _ := req.Get(fmt.Sprintf("http://127.0.0.1:8080/%s?a=%d&b=%d", "add", a, b))
body, _ := res.Body()
rspData := ResponseData{body, &rspData}
return rspData.Data
}
func main() {
fmt.Println(Add(2, 2))
}
三、rpc架构技术要点
-
通信协议: RPC系统需要定义通信协议,用于客户端和服务器之间的通信。常见的通信协议包括HTTP、TCP/IP等。
-
序列化和反序列化: 在RPC中,客户端调用远程服务时,需要将调用的参数序列化为网络可传输的格式,而服务器端接收到请求后需要将数据反序列化为程序可理解的格式。
-
服务接口定义: RPC系统需要明确定义服务接口,包括接口的方法、参数以及返回值。这有助于客户端和服务器之间的约定,使得双方可以进行有效的通信。
-
远程过程调用机制: RPC系统需要提供远程过程调用的机制,使得客户端能够像调用本地函数一样调用远程服务。这通常包括客户端存根和服务器存根的生成与调用过程。
-
服务注册与发现: 在分布式系统中,需要有一种机制来注册和发现可用的服务。这可以是基于中心化的服务注册中心,也可以是采用去中心化的服务发现机制。
-
负载均衡和容错机制: 由于RPC系统可能涉及多个服务实例,因此需要考虑负载均衡和容错机制,以确保请求能够被合理地分发,并且在某些服务不可用时能够进行故障转移或重试。
-
安全机制: RPC系统需要考虑数据在传输过程中的安全性,通常包括数据加密、身份验证、授权等机制,以保护通信过程中的数据安全。
-
性能优化: 对于RPC系统而言,性能是一个重要考量因素,因此需要对通信协议、序列化方式、远程调用机制等进行优化,以提高系统的性能表现。