1.RPC(远程过程调用)是一种通信机制,允许一个计算机程序通过网调用另一个计算机程序的函数或过程,就像本地调用一样它使得不同计算机或进程之间的通信和数据交换变得更加简单,程序可以透明地调用远程计算机上的函数,并获取返回结果, 工作原理: 客户端调用本地的RPC代理,传递参数和调用请求0 ·RPC代理将调用请求编码为适当的格式 (如JSON、Protobuf) 。 。编码后的请求通过网终发送给远程RPC服务器. 远程RPC服务器接收请求,解码请求并执行相应的函数或过程 。服务器执行完函数或过程后,将结果编码为适当的格式并返回给客户端。 客户端接收到响应后,解码响应并获取结果。
2.在Go语言中,通过使用 net/rpc 库实现RPC方法的步骤如下 i.定义RPC服务接口: 定义一个包含要远程调用的方法的接口。 ii.注册RPC服务对象: 将RPC服务对象注册到RPC服务中。 ii.实现RPC服务对象:实现RPC服务接口中定义的方法 iv.启动RPC服务: 启动RPC服务,等待客户端的调用请求
下面自己写了一个简单的Golang RPC示例,包含服务端和客户端两部分服务端代码:
package main
import (
"errors"
"log"
"net"
"net/rpc"
)
type Args struct {
A, B int
}
type Arith struct{}
func (t *Arith) Multiply(args *Args, reply *int) error {
*reply = args.A * args.B
return nil
}
func (t *Arith) Divide(args *Args, reply *float64) error {
if args.B == 0 {
return errors.New("divide by zero")
}
*reply = float64(args.A) / float64(args.B)
return nil
}
func main() {
arith := new(Arith)
rpc.Register(arith)
l, err := net.Listen("tcp", ":1234")
if err != nil {
log.Fatal("listen error: ", err)
}
log.Println("rpc server listening on :1234 ...")
rpc.Accept(l)
}
该服务端定义了一个Arith结构体,其中包含Multiply和Divide两个方法。Multiplv方法实现了两个整数相乘的功能而Divide方法实现了两个整数相除的功能。当除数为0时,Divide方法将返回一个错误。
服务端在启动时,首先使用 rpc.Register 函数注册了Arith类型,并监听端口号为1234的TCP连接。当有客户端连接时,服务端会接收到请求并进行处理
客户端代码:
epackage main
import (
"fmt"
"log"
"net/rpc"
)
type Args struct {
A, B int
}
func main() {
client, err := rpc.Dial("tcp", "localhost:1234")
if err != nil {
log.Fatal("dialing error: ", err)
}
args := Args{4, 5}
var reply int
// 调用Multiply方法
err = client.Call("Arith.Multiply", &args, &reply)
if err != nil {
log.Fatal("arith error: ", err)
}
fmt.Printf("Multiply: %d * %d = %d\n", args.A, args.B, reply)
args = Args{10, 0}
var fReply float64
// 调用Divide方法
err = client.Call("Arith.Divide", &args, &fReply)
if err != nil {
log.Fatal("arith error: ", err)
}
fmt.Printf("Divide: %d / %d = %f\n", args.A, args.B, fReply)
}
该客户端通过 rpc.Dial 函数连接到服务端,并通过 client.cal1 函数调用服务端的方法。客户端首先调用Multiply方法,传入参数4和5,并接收服务端返回的结果。然后客户端调用Divide方法,传入参数10和0,由于除数为0,服务端将返回一个错误
在Golang的RPC编程中,客户端和服务端的方法名、参数和返回值类型必须一致,否则会出现调用失败