GO学习之 远程过程调用(RPC)

GO系列

1、GO学习之Hello World

2、GO学习之入门语法

3、GO学习之切片操作

4、GO学习之 Map 操作

5、GO学习之 结构体 操作

6、GO学习之 通道(Channel)

7、GO学习之 多线程(goroutine)

8、GO学习之 函数(Function)

9、GO学习之 接口(Interface)

10、GO学习之 网络通信(Net/Http)

11、GO学习之 微框架(Gin)

12、GO学习之 数据库(mysql)

13、GO学习之 数据库(Redis)

14、GO学习之 搜索引擎(ElasticSearch)

15、GO学习之 消息队列(Kafka)

16、GO学习之 远程过程调用(RPC)

文章目录

前言

按照公司目前的任务,go 学习是必经之路了,虽然行业卷,不过技多不压身,依旧努力!!!

RPC 在许多应用程序中有着广泛应用,尤其是分布式系统和微服务中,一些场景的应用场景包括:

  • 微服务通信: 在微服务框架中,实现各个服务之间的通信使用 RPC 进行通信,以实现服务间的协作和数据传递。
  • 分布式系统: 在分布式系统中,不同节点之间需要进行远程调用。
  • 高性能计算: 在高性能计算环境中,可以使用 RPC 在不同计算机节点上执行计算任务,以加速并行计算。
  • 数据同步: 在不同数据源之间进行数据同步,例如:将数据从一个数据库复制到另一个数据库。

一、什么是RPC?

  • RPC 是远程过程调用(Remote Procedure Call, RPC)是一个计算机通信协议。
  • RPC 协议允许一台计算机的程序调用另一台计算机的子程序,我程序员无需要额外地为这个交互编程。
  • RPC 允许应用程序调用另一个地址空间(通常是远程服务器)上的函数和方法,就像本地调用一样。
  • RPC 的核心思想就是使远程调用过程对开发者透明,就像本地调用一样。

二、调用示例

在Go 标准库中包含了net/rpc包,用于实现 RPC 远程调用,所以不用在引入第三方包了。

2.1 服务端

下面代码中,实现了一个 RPC 的服务端,用来提供 RPC 服务,通过 rpc.Register(productService)来注册一个服务,并且通过 net.Listen("tcp", ":8899")监听。

go 复制代码
package main

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

// 定义一个返回体结构
type Product struct {
	Id    int32
	Name  string
	Desc  string
	Price float32
}

// 定义了一个 RPC 服务,用于返回产品信息
type ProductService struct{}

// 定义服务的方法, 参数定义需要定义为传递对象的指针
func (ps *ProductService) FetchProduct(Id *int32, reply *Product) error {
	p := Product{
		Id:    *Id,
		Name:  "钻石王老五",
		Desc:  "一部手机,能打电话",
		Price: 5000.00,
	}
	// 将产品信息写入 reply 指针
	*reply = p
	return nil
}

func main() {
	// 实例化产品服务
	productService := new(ProductService)
	// 注册ProductService 为 RPC 服务
	rpc.Register(productService)

	// 启动监听 8899
	listener, err := net.Listen("tcp", ":8899")
	if err != nil {
		log.Fatal("RPC service start fial: ", err)
		return
	}
	defer listener.Close()

	fmt.Println("RPC service is listening on part 8899...")
	for {
		// 接受客户端连接
		conn, err := listener.Accept()
		if err != nil {
			fmt.Println("Error accepting connection: ", err)
			continue
		}
		// 启动一个新的 goroutine 处理连接
		go rpc.ServeConn(conn)
	}
}

运行结果:

bash 复制代码
PS D:\workspaceGo\src\rpc> go run .\rpcServer.go
RPC service is listening on part 8899...

2.2 客户端

以下是 RPC 客户端代码,实现调用服务端代码,并且获得返回信息。代码中通过 rpc.Dial("tcp", "127.0.0.1:8899")调用本地端口 8899,通过 client.Call("ProductService.FetchProduct", 1, &result)实现调用,第一个参数为 远程方法名,第二个是方法参数,第三个参数用于接收返回结果。

go 复制代码
package main

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

// 定义一个结构体用户接受数据
type Product struct {
	Id    int32
	Name  string
	Desc  string
	Price float32
}

func main() {
	// 连接到远程 RPC 服务
	client, err := rpc.Dial("tcp", "127.0.0.1:8899")
	if err != nil {
		log.Fatal("Connect to server fail: ", err)
	}
	defer client.Close()

	var result Product
	// 调用远程函数 fetchProduct,result 用来获取返回值
	err = client.Call("ProductService.FetchProduct", 1, &result)
	if err != nil {
		log.Fatal("Call remote function fail: ", err)
		return
	}
	fmt.Printf("Result: %v \n", result)
}

运行结果:

bash 复制代码
PS D:\workspaceGo\src\rpc> go run .\rpcClient.go
Result: {1 钻石王老五 一部手机,能打电话 5000} 
PS D:\workspaceGo\src\rpc> 

三、RPC 实际应用中的优缺点

优点(不限于):

  1. 简化分布式系统开发: RPC 隐藏了底层通信细节,使分布式系统开发更加容易。
  2. 强类型: RPC 使用强类型语言定义接口,可以提前发现类型错误。
  3. 跨语言: 许多 RPC 框架支持多种编程语言,可以使不同语言开发的应用系统之间通信。

缺点(不限于):

  1. 增加复杂性: 在分布式系统的开发中,RPC 可能会增加系统的复杂性,例如:调用失败、超时和并发问题等。
  2. 性能开销: RPC 引入了额外的开销,比如:序列化、反序列化、网络开销等。

现阶段还是对 Go 语言的学习阶段,想必有一些地方考虑的不全面,本文示例全部是亲自手敲代码并且执行通过。
如有问题,还请指教。

评论去告诉我哦!!!一起学习一起进步!!!

相关推荐
周杰伦_Jay2 小时前
【智能体(Agent)技术深度解析】从架构到实现细节,核心是实现“感知环境→处理信息→决策行动→影响环境”的闭环
人工智能·机器学习·微服务·架构·golang·数据挖掘
天使街23号5 小时前
go-dongle v1.2.0 发布,新增 SM2 非对称椭圆曲线加密算法支持
开发语言·后端·golang
雨中散步撒哈拉7 小时前
16、做中学 | 初三上期 Golang面向对象_进阶
爬虫·python·golang
友莘居士10 小时前
Ganache-CLI以太坊私网JSON-RPC接口执行环境搭建
网络协议·rpc·json·环境搭建·以太坊
Java小混子10 小时前
golang项目CRUD示例
开发语言·后端·golang
想搞艺术的程序员10 小时前
Go 优雅关闭实践指南:从原理到框架落地
开发语言·后端·golang
大G的笔记本15 小时前
gRPC vs RPC 高频面试题
网络·网络协议·rpc
百***416615 小时前
Go-Gin Web 框架完整教程
前端·golang·gin
猫头虎17 小时前
Rust评测案例:Rust、Java、Python、Go、C++ 实现五大排序算法的执行时间效率比较(基于 OnlineGDB 平台)
java·开发语言·c++·python·golang·rust·排序算法
像风一样自由20201 天前
Go语言入门指南-从零开始的奇妙之旅
开发语言·后端·golang