Golang

关注公众号 jb51net

关闭
首页 > 脚本专栏 > Golang > Golang RPC

Golang RPC的原理与简单调用详解

作者:胡安民

RPC(Remote Procedure Call),主要是帮助我们屏蔽网络编程细节 ,使我们更专注于业务逻辑,所以本文主要来和大家聊聊RPC的原理与简单调用,希望对大家有所帮助

RPC(Remote Procedure Call),主要是帮助我们屏蔽网络编程细节 ,是我们更专注于业务逻辑,实现调用远程方法就像调用本地方法一样。

RPC通信过程

由服务提供者给出业务接口声明,在调用方的程序里面,RPC 框架根据调用的服务接口提前生成动态代理实现类,并通过依赖注入等技术注入到声明了该接口的相关业务逻辑里面。该代理实现类会拦截所有的方法调用,在提供的方法处理逻辑里面完成一整套的远程调用,并把远程调用结果返回给调用方,这样调用方在调用远程方法的时候就获得了像调用本地接口一样的体验。

RPC设计组成

以下是对RPC的四种角色的解释和说明:

客户端(Client): 服务调用发起方,也称为服务消费者。

客户端存根(Client Stub): 该程序运行在客户端所在的计算机机器上,主要用来存储要调用的服务器的地址,另外,该程序还负责将客户端请求远端服务器程序的数据信息打包成数据包,通过网络发送给服务端Stub程序;其次,还要接收服务端Stub程序发送的调用结果数据包,并解析返回给客户端。

服务端(Server): 远端的计算机机器上运行的程序,其中有客户端要调用的方法。

服务端存根(Server Stub): 接收客户Stub程序通过网络发送的请求消息数据包,并调用服务端中真正的程序功能方法,完成功能调用;其次,将服务端执行调用的结果进行数据处理打包发送给客户端Stub程序。

RPC原理和调用步骤

实际上,如果我们想要在网络中的任意两台计算机上实现远程调用过程,要解决很多问题,比如:

我们来看看RPC具体是如何解决这些问题的,RPC具体的调用步骤图如下:

在上述图中,通过1-10的步骤图解的形式,说明了RPC每一步的调用过程。具体描述为:

1、客户端想要发起一个远程过程调用,首先通过调用本地客户端Stub程序的方式调用想要使用的功能方法名;

2、客户端Stub程序接收到了客户端的功能调用请求,将客户端请求调用的方法名,携带的参数等信息做序列化操作,并打包成数据包。

3、客户端Stub查找到远程服务器程序的IP地址,调用Socket通信协议,通过网络发送给服务端。

4、服务端Stub程序接收到客户端发送的数据包信息,并通过约定好的协议将数据进行反序列化,得到请求的方法名和请求参数等信息。

5、服务端Stub程序准备相关数据,调用本地Server对应的功能方法进行,并传入相应的参数,进行业务处理。

6、服务端程序根据已有业务逻辑执行调用过程,待业务执行结束,将执行结果返回给服务端Stub程序。

7、服务端Stub程序将程序调用结果按照约定的协议进行序列化, 并通过网络发送回客户端Stub程序。

8、客户端Stub程序接收到服务端Stub发送的返回数据,对数据进行反序列化操作, 并将调用返回的数据传递给客户端请求发起者。

9、客户端请求发起者得到调用结果,整个RPC调用过程结束。

简单的使用

在对RPC进行简单介绍之后,我们先看一个简单的RPC服务注册和调用的demo

服务端代码如下:

package main
import (
	"fmt"
	"log"
	"net"
	"net/rpc"
)
type HelloService struct{}
func (p *HelloService) Hello(request string, reply *string) error {
	*reply = "hello:" + request
	log.Println("got req", request)
	return nil
}
func main() {
	// 创建TCP服务器
	listener, err := net.Listen("tcp", ":8888")
	if err != nil {
		fmt.Println("Listen error:", err)
		return
	}
	// 创建RPC服务
	rpcServer := rpc.NewServer()
	// 注册RPC服务(可以注册多个)
	rpcServer.RegisterName("HelloService", new(HelloService))
	// 开始接收RPC请求
	rpcServer.Accept(listener)
}

客户端代码如下:

package main
import (
   "fmt"
   "log"
   "net/rpc"
)
func main() {
    //访问rpc服务端
   client, err := rpc.Dial("tcp", "localhost:8888")
   if err != nil {
      log.Fatal("dialing:", err)
   }
   var reply string 
    //调用rpc服务的指定方法
   err = client.Call("HelloService.Hello", "RPC", &reply)
   if err != nil {
      log.Fatal(err)
   }
   fmt.Println(reply)
}

启动server.go 之后启动client.go ,RPC调用成功,控制台分别打印:

// server
got req RPC
// client
hello:RPC

以上就是Golang RPC的原理与简单调用详解的详细内容,更多关于Golang RPC的资料请关注脚本之家其它相关文章!

您可能感兴趣的文章:
阅读全文