当前位置: 首页 > article >正文

【Go语言】RPC 使用指南(初学者版)

RPC(Remote Procedure Call,远程过程调用)是一种计算机通信协议,允许程序调用另一台计算机上的子程序,就像调用本地程序一样。Go 语言内置了 RPC 支持,下面我会详细介绍如何使用。

1

一、基本概念

在 Go 中,RPC 主要通过 net/rpc 包实现,它使用 Gob 编码进行数据传输。Go 还提供了 net/rpc/jsonrpc 包,支持 JSON 编码的 RPC。

二、最简单的 RPC 示例

1. 定义服务

首先需要定义一个服务类型及其方法:

package mainimport ("errors""log""net""net/rpc"
)// 定义服务结构体
type Arith struct{}// 定义服务方法
// 注意:方法必须满足以下条件:
// 1. 方法是导出的(首字母大写)
// 2. 有两个参数,都是导出类型或内建类型
// 3. 第二个参数是指针
// 4. 返回 error 类型
func (t *Arith) Multiply(args *Args, reply *int) error {*reply = args.A * args.Breturn nil
}func (t *Arith) Divide(args *Args, quo *Quotient) error {if args.B == 0 {return errors.New("divide by zero")}quo.Quo = args.A / args.Bquo.Rem = args.A % args.Breturn nil
}// 定义参数结构体
type Args struct {A, B int
}// 定义返回结构体
type Quotient struct {Quo, Rem int
}

2. 启动 RPC 服务器

func main() {// 创建服务实例arith := new(Arith)// 注册服务rpc.Register(arith)// 注册服务到HTTP处理器(可选)// rpc.HandleHTTP()// 监听TCP连接l, err := net.Listen("tcp", ":1234")if err != nil {log.Fatal("listen error:", err)}// 开始接受连接for {conn, err := l.Accept()if err != nil {log.Fatal("accept error:", err)}// 为每个连接创建goroutine处理go rpc.ServeConn(conn)}// 如果使用HTTP,可以这样启动:// http.ListenAndServe(":1234", nil)
}

3. 创建 RPC 客户端

package mainimport ("log""net/rpc"
)// 定义参数结构体
type Args struct {A, B int
}// 定义返回结构体
type Quotient struct {Quo, Rem int
}func main() {// 连接RPC服务器client, err := rpc.Dial("tcp", "localhost:1234")if err != nil {log.Fatal("dialing:", err)}// 同步调用args := &Args{7, 8}var reply interr = client.Call("Arith.Multiply", args, &reply)if err != nil {log.Fatal("arith error:", err)}log.Printf("Arith: %d*%d=%d", args.A, args.B, reply)// 异步调用quotient := new(Quotient)divCall := client.Go("Arith.Divide", args, quotient, nil)replyCall := <-divCall.Done // 等待完成if replyCall.Error != nil {log.Fatal("arith error:", replyCall.Error)}log.Printf("Arith: %d/%d=%d...%d", args.A, args.B, quotient.Quo, quotient.Rem)
}

三、JSON-RPC 示例

如果你想使用 JSON 编码而不是 Gob 编码:

服务器端

func main() {arith := new(Arith)rpc.Register(arith)l, err := net.Listen("tcp", ":1234")if err != nil {log.Fatal("listen error:", err)}for {conn, err := l.Accept()if err != nil {log.Fatal("accept error:", err)}// 使用JSON编码go rpc.ServeCodec(jsonrpc.NewServerCodec(conn))}
}

客户端

func main() {conn, err := net.Dial("tcp", "localhost:1234")if err != nil {log.Fatal("dial error:", err)}client := rpc.NewClientWithCodec(jsonrpc.NewClientCodec(conn))args := &Args{7, 8}var reply interr = client.Call("Arith.Multiply", args, &reply)if err != nil {log.Fatal("arith error:", err)}log.Printf("Arith: %d*%d=%d", args.A, args.B, reply)
}

四、HTTP 上的 RPC

服务器端

func main() {arith := new(Arith)rpc.Register(arith)rpc.HandleHTTP()err := http.ListenAndServe(":1234", nil)if err != nil {log.Fatal("listen error:", err)}
}

客户端

func main() {client, err := rpc.DialHTTP("tcp", "localhost:1234")if err != nil {log.Fatal("dialing:", err)}args := &Args{7, 8}var reply interr = client.Call("Arith.Multiply", args, &reply)if err != nil {log.Fatal("arith error:", err)}log.Printf("Arith: %d*%d=%d", args.A, args.B, reply)
}

五、更现代的 gRPC

Go 的标准 RPC 包功能有限,Google 开发的 gRPC 是更现代的 RPC 框架:

1. 安装 gRPC

go get -u google.golang.org/grpc
go get -u github.com/golang/protobuf/protoc-gen-go

2. 定义 proto 文件

创建 hello.proto:

syntax = "proto3";package hello;service Greeter {rpc SayHello (HelloRequest) returns (HelloReply) {}
}message HelloRequest {string name = 1;
}message HelloReply {string message = 1;
}

3. 生成代码

protoc --go_out=plugins=grpc:. hello.proto

4. 实现服务端

package mainimport ("context""log""net""google.golang.org/grpc"pb "path/to/your/package" // 替换为你的包路径
)type server struct{}func (s *server) SayHello(ctx context.Context, in *pb.HelloRequest) (*pb.HelloReply, error) {return &pb.HelloReply{Message: "Hello " + in.Name}, nil
}func main() {lis, err := net.Listen("tcp", ":50051")if err != nil {log.Fatalf("failed to listen: %v", err)}s := grpc.NewServer()pb.RegisterGreeterServer(s, &server{})if err := s.Serve(lis); err != nil {log.Fatalf("failed to serve: %v", err)}
}

5. 实现客户端

package mainimport ("context""log""os""time""google.golang.org/grpc"pb "path/to/your/package" // 替换为你的包路径
)func main() {conn, err := grpc.Dial("localhost:50051", grpc.WithInsecure())if err != nil {log.Fatalf("did not connect: %v", err)}defer conn.Close()c := pb.NewGreeterClient(conn)name := "world"if len(os.Args) > 1 {name = os.Args[1]}ctx, cancel := context.WithTimeout(context.Background(), time.Second)defer cancel()r, err := c.SayHello(ctx, &pb.HelloRequest{Name: name})if err != nil {log.Fatalf("could not greet: %v", err)}log.Printf("Greeting: %s", r.Message)
}

六、选择建议

  1. 标准库 RPC:简单、轻量,适合内部服务通信
  2. JSON-RPC:需要跨语言通信时使用
  3. gRPC:现代、高性能、支持多种语言,适合生产环境

七、常见问题

  1. 方法不满足要求:确保方法签名符合要求(两个参数,第二个是指针,返回 error)
  2. 连接问题:检查服务器是否启动,端口是否正确

相关文章:

【Go语言】RPC 使用指南(初学者版)

RPC&#xff08;Remote Procedure Call&#xff0c;远程过程调用&#xff09;是一种计算机通信协议&#xff0c;允许程序调用另一台计算机上的子程序&#xff0c;就像调用本地程序一样。Go 语言内置了 RPC 支持&#xff0c;下面我会详细介绍如何使用。 一、基本概念 在 Go 中&…...

Python----深度学习(基于深度学习Pytroch簇分类,圆环分类,月牙分类)

一、引言 深度学习的重要性 深度学习是一种通过模拟人脑神经元结构来进行数据学习和模式识别的技术&#xff0c;在分类任务中展现出强大的能力。 分类任务的多样性 分类任务涵盖了各种场景&#xff0c;例如簇分类、圆环分类和月牙分类&#xff0c;每种任务都有不同的…...

入侵检测系统(IDS)与入侵防御系统(IPS):功能对比与部署实践

入侵检测系统&#xff08;IDS&#xff09;与入侵防御系统&#xff08;IPS&#xff09;&#xff1a;功能对比与部署实践 在网络安全防御体系中&#xff0c;入侵检测系统&#xff08;Intrusion Detection System, IDS&#xff09;与入侵防御系统&#xff08;Intrusion Preventio…...

uniapp-商城-38-shop 购物车 选好了 进行订单确认4 配送方式1

配送方式在订单确认页面最上方&#xff0c;可以进行选中配送还是自提&#xff0c;这里先看看配送。 代码样式&#xff1a; 可以看出来是通过组件来实现的。组件名字是&#xff1a;delivery-layout 1、建立组件文件夹和页面&#xff0c;delivery-layout这里就只有配送 2、具体…...

uniappx 打包配置32位64位x86安装包

{"app": {"distribute": {"android": {"abiFilters": ["armeabi-v7a","arm64-v8a","x86","x86_64"]}}} }...

【深度强化学习 DRL 快速实践】逆向强化学习算法 (IRL)

Inverse Reinforcement Learning (IRL) 详解 什么是 Inverse Reinforcement Learning&#xff1f; 在传统的强化学习 (Reinforcement Learning, RL) 中&#xff0c;奖励函数是已知的&#xff0c;智能体的任务是学习一个策略来最大化奖励 而在逆向强化学习 (Inverse Reinforc…...

《普通逻辑》学习记录——性质命题及其推理

目录 一、性质命题概述 二、性质命题的种类 2.1、性质命题按质的分类 2.2、性质命题按量的分类 2.3、性质命题按质和量结合的分类 2.4、性质命题的基本形式归纳 三、四种命题的真假关系 3.1、性质命题与对象关系 3.2、四种命题的真假判定 3.3、四种命题的对当关系 四、四种命题…...

人工智能(AI)对网络管理的影响

近年来&#xff0c;人工智能(AI)尤其是大语言模型(LLMs)的快速发展&#xff0c;正在深刻改变网络管理领域。AI的核心价值在于其能够通过自动化、模式分析和智能决策&#xff0c;显著提升网络运维效率并应对复杂挑战。具体表现为&#xff1a; 快速数据查询与分析​​&#xff1…...

第1讲|R语言绘图体系总览(Base、ggplot2、ComplexHeatmap等)

目录 第1讲|R语言绘图体系总览 ✨ 引言:为什么R绘图如此重要? 🧩 1. Base绘图系统 🧩 2. ggplot2生态系统 🧩 3. ComplexHeatmap超级热图系统 🧩 4. 其他特色绘图库(快速了解) ✏️ 小结一句话 📅 预告下一讲 第1讲|R语言绘图体系总览 (Base、ggplot…...

embedding_model模型通没有自带有归一化层该怎么处理?

embedding_model 是什么&#xff1a; 嵌入式模型&#xff08;Embedding&#xff09;是一种广泛应用于自然语言处理&#xff08;NLP&#xff09;和计算机视觉&#xff08;CV&#xff09;等领域的机器学习模型&#xff0c;它可以将高维度的数据转化为低维度的嵌入空间&#xff0…...

基于STM32、HAL库的MCP3421A0T模数转换器ADC驱动程序设计

一、简介&#xff1a; MCP3421A0T是Microchip公司生产的一款18位Δ-Σ模数转换器(ADC)&#xff0c;具有以下特点&#xff1a; 18位分辨率 单通道差分输入 可编程增益放大器(PGA)&#xff1a;1, 2, 4, 8 可选的转换速率(3.75/15/60/240SPS) 内部基准电压(2.048V 0.05%) IC…...

八大排序——冒泡排序/归并排序

八大排序——冒泡排序/归并排序 一、冒泡排序 1.1 冒泡排序 1.2 冒泡排序优化 二、归并排序 1.1 归并排序&#xff08;递归&#xff09; 1.2 递归排序&#xff08;非递归&#xff09; 一、冒泡排序 1.1 冒泡排序 比较相邻的元素。如果第一个比第二个大&#xff0c;就交换…...

银发科技:AI健康小屋如何破解老龄化困局

随着全球人口老龄化程度的不断加深&#xff0c;如何保障老年人的健康、提升他们的生活质量&#xff0c;成为了社会各界关注的焦点。 在这场应对老龄化挑战的战役中&#xff0c;智绅科技顺势而生&#xff0c;七彩喜智慧养老系统构筑居家养老安全网。 而AI健康小屋作为一项创新…...

Python实例题:使用Pvthon3编写系列实用脚本

目录 Python实例题 题目 1. 文件重命名脚本 csv_data_statistics.py file_rename.py web_crawler.py 2. CSV 文件数据统计脚本 3. 简单的网页爬虫脚本 运行思路 文件重命名脚本 CSV 文件数据统计脚本 简单的网页爬虫脚本 注意事项 Python实例题 题目 使用Pvthon…...

命令行指引的尝试

效果 步骤 首先初始化一个空的项目&#xff0c;然后安装一些依赖 npm init -y npm install inquirer execa chalk ora至于这些依赖是干嘛的&#xff0c;如下图所示&#xff1a; 然后再 package.json 中补充一个 bin 然后再根目录下新建一个 index.js , 其中的内容如下 #!/…...

Sharding-JDBC 系列专题 - 第九篇:高可用性与集群管理

Sharding-JDBC 系列专题 - 第九篇:高可用性与集群管理 本系列专题旨在帮助开发者全面掌握 Sharding-JDBC,一个轻量级的分布式数据库中间件。本篇作为系列的第九篇文章,将重点探讨 高可用性(High Availability, HA) 和 集群管理,包括数据库高可用方案、Sharding-JDBC 的故…...

【Dify系列教程重置精品版】第1课 相关概念介绍

文章目录 一、Dify是什么二、Dify有什么用三、如何玩转Dify?从螺丝刀到机甲战士的进阶指南官方网站:https://dify.ai github地址:https://github.com/langgenius/dify 一、Dify是什么 Dify(D​​efine + ​​I​​mplement + ​​F​​or ​​Y​​ou)。这是一款开源的大…...

leetcode0106. 从中序与后序遍历序列构造二叉树-medium

1 题目&#xff1a;从中序与后序遍历序列构造二叉树 官方标定难度&#xff1a;中 给定两个整数数组 inorder 和 postorder &#xff0c;其中 inorder 是二叉树的中序遍历&#xff0c; postorder 是同一棵树的后序遍历&#xff0c;请你构造并返回这颗 二叉树 。 示例 1: 输入…...

第5.5章:ModelScope-Agent:支持多种API无缝集成的开源框架

5.5.1 ModelScope-Agent概述 ModelScope-Agent&#xff0c;由阿里巴巴旗下ModelScope社区开发&#xff0c;是一个开源的、模块化的框架&#xff0c;旨在帮助开发者基于大型语言模型快速构建功能强大、灵活性高的智能代理。它的核心优势在于支持与多种API和外部系统的无缝集成&…...

Spring Boot默认缓存管理

Spring框架支持透明地向应用程序添加缓存&#xff0c;以及对缓存进行管理&#xff0c;其管理缓存的核心是将缓存应用于操作数据的方法&#xff0c;从而减少操作数据的执行次数&#xff0c;同时不会对程序本身造成任何干扰。Spring Boot继承了Spring框架的缓存管理功能&#xff…...

XYNU2024信安杯-REVERSE(复现)

前言 记录记录 1.Can_you_find_me? 签到题&#xff0c;秒了 2.ea_re 快速定位 int __cdecl main_0(int argc, const char **argv, const char **envp) {int v4; // [esp0h] [ebp-1A0h]const char **v5; // [esp4h] [ebp-19Ch]const char **v6; // [esp8h] [ebp-198h]char v7;…...

MySQL的MVCC【学习笔记】

MVCC 事务的隔离级别分为四种&#xff0c;其中Read Committed和Repeatable Read隔离级别&#xff0c;部分实现就是通过MVCC&#xff08;Multi-Version Concurrency Control&#xff0c;多版本并发控制&#xff09; 版本链 版本链是通过undo日志实现的&#xff0c; 事务每次修改…...

罗德FSP13 FSP40频谱分析仪频率13.6GHz

罗德FSP13 FSP40频谱分析仪频率13.6GHz 附加的功能&#xff1a; 分辨率带宽&#xff1a;1 Hz 至 10 MHz 显示的平均噪音水平&#xff1a;-155 dBm (1 Hz) 相位噪声&#xff1a;10 kHz 时 -113 dB (1 Hz) 附加滤波器&#xff1a;100 Hz 至 5 MHz 的通道滤波器和 RRC 滤波器、…...

腾讯PC客户端面经

1.有关虚函数调用问题 空指针可以在特定的情况下去调用非虚函数&#xff0c;因为非虚函数在编译阶段就可以确定地址&#xff0c;调用的时候this指针传的是nullptr没有问题&#xff0c;不需要依赖对象的创建。 空指针不可以去调用虚函数&#xff0c;因为虚函数的调用需要虚表&…...

达梦数据库压力测试报错超出全局hash join空间,适当增加HJ_BUF_GLOBAL_SIZE解决

1.名词解释&#xff1a;达梦数据库中的HJ_BUF_GLOBAL_SIZE是所有哈希连接操作可用的最大哈希缓冲区大小&#xff0c;单位为兆字节&#xff08;MB&#xff09; 2.达梦压测报错&#xff1a; 3.找到达梦数据库安装文件 4.压力测试脚本 import http.client import multiprocessi…...

Oracle--SQL性能优化与提升策略

前言&#xff1a;本博客仅作记录学习使用&#xff0c;部分图片出自网络&#xff0c;如有侵犯您的权益&#xff0c;请联系删除 一、导致性能问题的内在原因 系统性能问题的底层原因主要有三个方面&#xff1a; CPU占用率过高导致资源争用和等待内存使用率过高导致内存不足并需…...

如何在Spring Boot中配置自定义端口运行应用程序

Spring Boot 应用程序默认在端口 8080 上运行嵌入式 Web 服务器&#xff08;如 Tomcat、Jetty 或 Undertow&#xff09;。然而&#xff0c;在开发、测试或生产环境中&#xff0c;开发者可能需要将应用程序配置为在自定义端口上运行&#xff0c;例如避免端口冲突、适配微服务架构…...

六个能够白嫖学习资料的网站

一、咖喱君的资源库 地址&#xff1a;https://flowus.cn/galijun/share/de0f6d2f-df17-4075-86ed-ebead0394a77 这是一个学习资料/学习网站分享平台&#xff0c;包含了英语、法语、德语、韩语、日语、泰语等几十种外国语言的学习资料及平台&#xff0c;这个网站的优势就是外语…...

破界出海:HR SaaS平台的全球化实践与组织效能跃升

全球化浪潮下的HR SaaS破局实践 在全球化与数字化双重浪潮的推动下&#xff0c;中国企业出海已从战略选择演变为生存刚需。然而&#xff0c;跨文化管理冲突、多国法律合规风险、复杂薪酬体系与人才发展需求&#xff0c;构成了企业国际化的四大核心挑战。据艾瑞咨询数据&#x…...

IntelliJ IDEA 中配置 Spring MVC 环境的详细步骤

以下是在 IntelliJ IDEA 中配置 Spring MVC 环境的详细步骤&#xff1a; 步骤 1&#xff1a;创建 Maven Web 项目 新建项目 File -> New -> Project → 选择 Maven → 勾选 Create from archetype → 选择 maven-archetype-webapp。输入 GroupId&#xff08;如 com.examp…...