golang学习笔记27——golang 实现 RPC 模块

devtools/2024/9/24 16:29:03/

文章目录

    • 引言
    • Go 中 RPC 的基础知识
      • 1.RPC 服务端
      • 2.RPC 客户端
    • 代码示例
      • 1.定义 RPC 服务
      • 2.实现 RPC 客户端
    • 使用 JSON-RPC
    • 总结

引言

RPC(Remote Procedure Call)远程过程调用,它允许不同的进程在网络上进行通信,就像调用本地函数一样。在 Go 语言中,实现 RPC 模块相对简洁且高效。本文将详细介绍在 Go 语言中如何实现 RPC 模块。

Go 中 RPC 的基础知识

Go 标准库中的net/rpc包提供了对 RPC 的基本支持。

1.RPC 服务端

在服务端,我们需要定义一个对象,该对象的方法可以被远程调用。这些方法必须满足特定的规则:它们必须是公开的方法(首字母大写),并且必须有两个参数,第一个参数是接收请求的结构体指针,第二个参数是用于返回结果的结构体指针。

2.RPC 客户端

客户端可以像调用本地方法一样调用远程服务端的方法,只需要通过rpc.Dial建立连接后调用Call方法即可。

代码示例

1.定义 RPC 服务

首先,我们定义一个简单的服务,用于执行数学运算。

golang">package mainimport ("errors""net/http""net/rpc"
)// Args 用于传递请求参数
type Args struct {A, B int
}// MathService 数学运算服务
type MathService struct{}// Add 加法运算
func (m *MathService) Add(args *Args, reply *int) error {if args == nil {return errors.New("invalid arguments")}*reply = args.A + args.Breturn nil
}func main() {// 注册服务mathService := new(MathService)rpc.Register(mathService)// 开启 HTTP 服务rpc.HandleHTTP()err := http.ListenAndServe(":1234", nil)if err!= nil {panic(err)}
}

在上述代码中,我们定义了一个MathService结构体,其中Add方法用于执行加法运算。这个方法接收一个Args结构体指针作为参数,将运算结果通过reply指针返回。在main函数中,我们注册了这个服务,并开启了一个 HTTP 服务来处理 RPC 请求。

2.实现 RPC 客户端

golang">package mainimport ("fmt""log""net/rpc"
)func main() {// 连接到 RPC 服务端client, err := rpc.DialHTTP("tcp", "localhost:1234")if err!= nil {log.Fatal("dialing:", err)}// 准备请求参数args := Args{A: 3, B: 4}var reply int// 调用远程方法err = client.Call("MathService.Add", &args, &reply)if err!= nil {log.Fatal("arith error:", err)}// 输出结果fmt.Printf("The result of addition is: %d\n", reply)
}

在客户端代码中,我们首先通过rpc.DialHTTP连接到服务端。然后创建了一个Args结构体并设置了参数值。接着,我们调用client.Call方法来执行远程的Add方法,并将结果存储在reply变量中。

使用 JSON-RPC

除了使用 Go 标准的 RPC 编码,我们还可以使用 JSON-RPC。只需要将rpc.Register替换为rpc.RegisterName并指定编码为jsonrpc

golang">package mainimport ("errors""log""net/http""net/rpc""net/rpc/jsonrpc"
)// Args 用于传递请求参数
type Args struct {A, B int
}// MathService 数学运算服务
type MathService struct{}// Add 加法运算
func (m *MathService) Add(args *Args, reply *int) error {if args == nil {return errors.New("invalid arguments")}*reply = args.A + args.Breturn nil
}func main() {// 注册服务mathService := new(MathService)rpc.RegisterName("MathService", mathService)// 开启 HTTP 服务http.HandleFunc("/rpc", func(w http.ResponseWriter, r *http.Request) {jsonrpc.ServeRequest(rpc.DefaultServer, w, r)})// 启动服务log.Fatal(http.ListenAndServe(":1234", nil))
}

客户端的调用方式需要稍作修改:

golang">package mainimport ("fmt""log""net/rpc/jsonrpc"
)func main() {// 连接到 RPC 服务端client, err := jsonrpc.Dial("tcp", "localhost:1234")if err!= nil {log.Fatal("dialing:", err)}// 准备请求参数args := Args{A: 3, B: 4}var reply int// 调用远程方法err = client.Call("MathService.Add", &args, &reply)if err!= nil {log.Fatal("arith error:", err)}// 输出结果fmt.Printf("The result of addition is: %d\n", reply)
}

总结

在 Go 语言中实现 RPC 模块非常方便,无论是使用标准的 RPC 编码还是 JSON-RPC。通过简单的几步:定义服务、注册服务、开启服务端以及在客户端进行调用,我们可以轻松地实现跨进程的远程过程调用。在实际应用中,可以根据具体的业务需求选择合适的 RPC 实现方式。

关注我看更多有意思的文章哦!👉👉


http://www.ppmy.cn/devtools/116585.html

相关文章

2024年【N2观光车和观光列车司机】复审考试及N2观光车和观光列车司机实操考试视频

题库来源:安全生产模拟考试一点通公众号小程序 N2观光车和观光列车司机复审考试是安全生产模拟考试一点通总题库中生成的一套N2观光车和观光列车司机实操考试视频,安全生产模拟考试一点通上N2观光车和观光列车司机作业手机同步练习。2024年【N2观光车和…

JZ2440开发板——S3C2440的UART

以下内容源于韦东山课程的学习与整理,如有侵权请告知删除。 一、UART硬件简介 UART,全称是“Universal Asynchronous Receiver Transmitter”,即“通用异步收发器”,也就是我们日常说的“串口”。 它在嵌入式中用途非常广泛&…

介绍GPT-o1:一系列解决困难问题( science, coding, and math )的推理模型

openai o1介绍 一、官方技术报告要点剖析实验1 benchmark分析实验2:和phd比赛技术细节:Chain of Thought的使用人类偏好评估Human preference evaluationsatety技术细节:隐藏思维链为监控模型提供了机会:)openai的几点conclusion 二、官方介绍剖析 Intro…

AI学习指南深度学习篇-Adadelta超参数调优与性能优化

AI学习指南深度学习篇-Adadelta超参数调优与性能优化 在深度学习领域,Adadelta是一种常用的优化算法,它具有自适应学习率和动量的特点,能够在训练过程中自动调整学习率,并且对参数的更新步长做出了合理的调整,使得训练…

Java面试篇基础部分- Java中的阻塞队列

首先队列是一种前进后出的操作结构,也就是说它只允许从队列前端进入,从队列后端退出。这个前端和后端看个人如何理解,也就是通常所说的入队和出队,队头和队尾。 阻塞队列和一般队列的不同就在于阻塞队列是可以阻塞的,这里所说的并不是说队列中间或者队头队尾被拦截了,而是…

ORA-28032 Your password has expired and the database is set to read only

做个记录。 non-cdb 处于只读状态,CDB创建到noncdb的dblink后产生的报错,dblink可以成功创建,但无法连接到non-cdb。 解决:一开始以为是cdb的密码不正确,mos上找到问题,non-cdb的密码过期了,并且…

【Webpack】Tree Shaking

概念 Webpack 的 Tree Shaking 机制的原理是通过静态分析代码的模块依赖图,把没有用到的代码“剪掉”,从而减少打包后的代码体积。 主要依赖于 ES6 的模块系统(即 import 和 export 语法),因为 ES6 模块是静态的&…

【截稿更新 | 11月杭州 | EI稳定 】

【截稿更新 | 11月杭州 | EI稳定 】2024年人机交互与虚拟现实国际会议(HCIVR 2024) ✅会议时间:2024年11月15-17日 ✅会议地点:中国杭州 🔥二轮截稿日期:2024年10月15日 🌈投稿通道已开启&#…