GO语言RPC包使用

本文介绍了RPC的基本概念,然后通过一个使用Go标准库net/rpc实现的简易计算器例子,详细讲解了服务端和客户端的创建过程,包括服务端的注册、客户端的连接与调用。此外,还提及了GO标准库RPC的局限性以及更复杂的RPC框架如grpc、dubbo等的功能优势。
摘要由CSDN通过智能技术生成

下面首先会进行一个简单的RPC介绍,然后通过一个简易计算器的例子来了解如何运用GO标准库RPC。

1 RPC简介

RPC即远程过程调用(Remote Procedure Call),是一种通信协议,该协议允许运行于一台计算机的程序调用另一台计算机的程序,而程序员无需额外地为这个交互编程。 一个典型的RPC模型如下图所示,左边为消费者(客户端),右边为提供者(服务端),客户端通过RPC框架可直接调用服务端函数。
在这里插入图片描述

在本文中,主要运用GO语言标准库中自带的net/rpc库。其rpc实现使用encoding/gob进行编解码,支持tcp和http数据传输方式,但由于大部分语言不支持gob编码,所以此RPC实现方法仅支持使用Golang语言编写的客户机与服务器。GO语言标准库还实现了net/rpc/jsonrpc库,采用JSON进行编解码,因此支持跨语言调用。接下来将会通过一个经典的计算器例子来说明GO标准库net/rpc使用方法。

2 RPC实现简易计算机

RPC的实现主要分为服务端实现以及客户端实现。

服务端实现主要分为三步:

  • 定义输入输出参数
  • 实现拟调用的方法
  • 注册服务

代码及说明如下:

package main

import (
	"errors"
	"log"
	"net/http"
	"net/rpc"
)

// CalRequest 定义请求体,计算函数接受A、B值,并根据C来进行计算操作
// 注意:此处所有首字母都要大写,因为要供其他包进行调用。
type CalRequest struct {
	A int
	B int
	C string
}

// CalReply 定义响应体,返回结果。
// 注意:此处所有首字母都要大写,因为要供其他包进行调用。
type CalReply struct {
	Result int
}

// CalService 定义服务端
type CalService struct {
}

// Cal 定义相加函数供客户端调用。
//注意:1.此方法名首字母也要大写。
//2.此函数需为服务端结构体CalService的方法。
//3.函数参数有且仅有两个,第一个参数为输入参数,第二个参数为返回参数。
//4.函数返回值有且仅有一个,为error类型
func (s *CalService) Cal(request *CalRequest,reply *CalReply)error{
	switch request.C {
	case "+":
		reply.Result=request.A+request.B
	case "-":
		reply.Result=request.A-request.B
	case "/":
		reply.Result=request.A/request.B
	case "*":
		reply.Result=request.A*request.B
	default:
		return errors.New("C is not the correct value. ")
	}
	return nil
}

//注册服务
func main(){
	//注册一个rpc服务
	service:=&CalService{}
	rpc.Register(service)
	//绑定http协议。此时RPC使用HTTP协议进行服务端和客户端的通信。
	//实际上,当客户端发起一个 RPC 调用时,本质上是将要调用的方法和参数包装成一个 HTTP 请求。
	//服务端收到 HTTP 请求后,解码出要调用的本地方法名称和入参,然后调用本地方法。
	//在本地方法调用完成后再将结果写入到 HTTP 响应中,客户端收到响应后,再解析出远程调用的结果。
	rpc.HandleHTTP()
	//进行监听。
	err:=http.ListenAndServe(":8000",nil)
	if err != nil {
		log.Panicln(err)
	}
}

客户端实现主要分为两步:

  • 连接服务
  • 调用

代码及说明如下:

package main

import (
	"fmt"
	"log"
	"net/rpc"
)

// CalRequest 定义请求体,计算函数接受A、B值,并根据C来进行计算操作
// 注意:此处结构体名可与服务端名不同,但其内的元素名字应该与服务端完全一致,不然会出现调用错误。
type CalRequest struct {
	A int
	B int
	C string
}

// CalReply 定义响应体,返回结果。
// 注意:此处结构体名可与服务端名不同,但其内的元素名字应该与服务端完全一致,不然会出现调用错误。
type CalReply struct {
	Result int
}

func main() {
	//连接远程RPC服务器
	conn,err:=rpc.DialHTTP("tcp",":8000")
	if err != nil {
		log.Fatal(err)
	}
	defer conn.Close()
	//调用方法
	reply:=&CalReply{}
	err=conn.Call("CalService.Cal",&CalRequest{1,2,"+"},reply)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(reply.Result)
}

3 总结

至此,基于RPC的简易计算机实现完毕。客户端可以通过调用RPC来使用服务端提供的简单计算接口。

GO标准库提供的RPC功能还比较单薄,现有很多其他很经典的RPC框架,如grpc、dubbo、motan等。其提供的功能更加的多样化,比如协议交换(protocol exchange)、注册中心(registry)、服务发现(service discovery)、负载均衡(load balance)、超时处理(timeout processing)等等,面对不同的应用场景应该合理的选用不同的RPC框架。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

雨雨不怕雨

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值