更多个人笔记:(仅供参考,非盈利)
gitee: https://gitee.com/harryhack/it_note
github: https://github.com/ZHLOVEYY/IT_note
文章目录
rpc基础概念
电商系统迅速发展后,有很多服务需要拆分,比如用户服务,商品服务,支付服务,订单服务,售后服务等 这些服务之间的相互调用就需要使用rpc
rpc框架:
服务注册中心:负责本地服务发布为远程服务,管理提供给消费者
消费者:通过远程代理对象调用远程服务
服务提供者:提供接口和相关服务
rpc框架可以跨语言,协议私密,传输效率也很高
GO的rpc应用
官方的net/rpc包对于方法有定义要求符合:
GO
func (t *T) MethodName (argType T1, replyType *T2) error
其中T,T1,T2需要被encoding/gob包序列化(就是说不同编码器都需要适用)
第一个参数是调用者需要传递的参数
第二个是会以字符串方式返回的结果
简单编写
服务端: go run server.go运行就行
Go
package main
import (
"fmt"
"net/http"
"net/rpc"
)
type Args struct { //定义传入参数结构
X, Y int
}
type Algorithm int //就是一个辅助的定义
func (t *Algorithm) Sum(args *Args, reply *int) error { //定义方法
*reply = args.X + args.Y
fmt.Println("Exec Sum ", reply)
return nil
}
func main() {
algorithm := new(Algorithm) //分配内存空间指针同时分配内存初始化为0值
fmt.Println("algorithm start", algorithm)
//注册服务
rpc.Register(algorithm)
rpc.HandleHTTP() //将 RPC 服务挂载到 HTTP 服务器
err := http.ListenAndServe(":8081", nil)
if err != nil {
fmt.Println("err=====", err.Error())
}
}
- 定义传入的结构体参数
- 为了调用方法,定义相关结构体承载
- 实例化对应的承载结构体
- 注册服务,并注册到HTTP上
- 启动端口监听
客户端: 终端开启运行 go run xxx.go 1 2
(后面的1和2是制定的参数传入)
go
package main
import (
"fmt"
"log"
"net/rpc"
"os"
"strconv"
)
type Args struct { //定义传入参数结构
X, Y int
}
type Algorithm int //就是一个辅助的定义
func (t *Algorithm) Sum(args *Args, reply *int) error {
*reply = args.X + args.Y
fmt.Println("Exec Sum ", reply)
return nil
}
func main() {
//连接服务器
client, err := rpc.DialHTTP("tcp", "127.0.0.1:8081")
if err != nil {
log.Fatal("dailHTTP发生错误", err)
}
//获取第一个输入
i1, _ := strconv.Atoi(os.Args[1])
//获取第二个输入
i2, _ := strconv.Atoi(os.Args[2])
args := Args{i1, i2}
var reply int
//调用远程方法
err = client.Call("Algorithm.Sum", args, &reply) //调用对应的方法
if err!= nil {
log.Fatal("调用远程方法发生错误", err)
}
fmt.Printf("Arith: %d+%d=%d\n", args.X, args.Y, reply)
}
- 连接对应的服务
- 输入,组成结构体
- 通过Call 调用对应的方法并进行传递
json编写rpc
- 标准 RPC:主要用于 Go 程序之间通信,用Gob进行二进制编码
- JSON-RPC:适合跨语言通信(因为 JSON 是通用格式),用json进行编码
jsonrpc更加通用,,二者的实际使用其实就是启动方式时函数调用上的区别,先不重复展开