《Go语言高级编程》RPC 入门

《Go语言高级编程》RPC 入门

一、什么是 RPC?

RPC(Remote Procedure Call,远程过程调用)是分布式系统中不同节点间的通信方式,允许程序像调用本地函数一样调用远程服务的方法。
Go 语言的标准库 net/rpc 提供了基础的 RPC 实现,基于网络(如 TCP)通信,支持服务注册、方法调用和数据编码。

二、RPC 版 “Hello, World” 示例
1. 服务端实现
// 定义服务类型及方法(需满足 RPC 规则:公开方法、两参数、第二参数为指针、返回 error)
type HelloService struct {}func (p *HelloService) Hello(request string, reply *string) error {*reply = "hello:" + requestreturn nil
}func main() {// 注册服务,方法会被放在 "HelloService" 命名空间下rpc.RegisterName("HelloService", new(HelloService))// 监听 TCP 连接listener, err := net.Listen("tcp", ":1234")if err != nil {log.Fatal("ListenTCP error:", err)}// 接受单个连接并提供服务conn, err := listener.Accept()if err != nil {log.Fatal("Accept error:", err)}rpc.ServeConn(conn)
}
2. 客户端实现
func main() {// 拨号连接服务端client, err := rpc.Dial("tcp", "localhost:1234")if err != nil {log.Fatal("dialing:", err)}// 调用服务方法(参数:服务名.方法名、请求参数、响应指针)var reply stringerr = client.Call("HelloService.Hello", "hello", &reply)if err != nil {log.Fatal(err)}fmt.Println(reply) // 输出:hello:hello
}
关键点说明:
  • RPC 方法规则:必须为公开方法(首字母大写),有两个可序列化参数,第二参数为指针,返回 error
  • 服务注册rpc.RegisterName 将方法注册到指定命名空间,便于客户端调用。
  • 通信流程:服务端监听连接,客户端拨号后通过 Call 方法远程调用。
三、更安全的 RPC 接口设计
1. 接口规范定义
// 定义服务名、接口和注册函数,解耦服务实现与调用
const HelloServiceName = "path/to/pkg.HelloService"type HelloServiceInterface interface {Hello(request string, reply *string) error
}func RegisterHelloService(svc HelloServiceInterface) error {return rpc.RegisterName(HelloServiceName, svc)
}
2. 客户端封装
// 封装客户端接口,简化调用并提供类型安全保障
type HelloServiceClient struct {*rpc.Client
}// 确保 HelloServiceClient 实现接口
var _ HelloServiceInterface = (*HelloServiceClient)(nil)func DialHelloService(network, address string) (*HelloServiceClient, error) {c, err := rpc.Dial(network, address)if err != nil {return nil, err}return &HelloServiceClient{Client: c}, nil
}func (p *HelloServiceClient) Hello(request string, reply *string) error {return p.Client.Call(HelloServiceName+".Hello", request, reply)
}
3. 客户端调用(简化版)
func main() {client, err := DialHelloService("tcp", "localhost:1234")if err != nil {log.Fatal("dialing:", err)}var reply stringerr = client.Hello("hello", &reply)if err != nil {log.Fatal(err)}fmt.Println(reply)
}
优势:
  • 接口隔离:服务端和客户端通过接口规范解耦,便于团队分工。
  • 类型安全:编译器确保服务实现和客户端调用符合接口定义,减少错误。
  • 可维护性:服务名和方法名通过常量管理,避免硬编码。
四、跨语言 RPC(基于 JSON 编码)

Go 标准库默认使用 gob 编码(Go 特有),若需跨语言调用,可改用 JSON 编码:

1. 服务端(JSON 版本)
func main() {rpc.RegisterName("HelloService", new(HelloService))listener, err := net.Listen("tcp", ":1234")if err != nil {log.Fatal("ListenTCP error:", err)}// 支持多个连接,每个连接使用 JSON 编解码器for {conn, err := listener.Accept()if err != nil {log.Fatal("Accept error:", err)}go rpc.ServeCodec(jsonrpc.NewServerCodec(conn))}
}
2. 客户端(JSON 版本)
func main() {// 手动建立 TCP 连接conn, err := net.Dial("tcp", "localhost:1234")if err != nil {log.Fatal("net.Dial:", err)}// 使用 JSON 编解码器创建客户端client := rpc.NewClientWithCodec(jsonrpc.NewClientCodec(conn))var reply stringerr = client.Call("HelloService.Hello", "hello", &reply)if err != nil {log.Fatal(err)}fmt.Println(reply)
}
3. 数据格式(JSON)
  • 请求格式{"method":"服务名.方法名","params":["参数"],"id":调用编号}
    示例:{"method":"HelloService.Hello","params":["hello"],"id":0}
  • 响应格式{"id":编号,"result":"结果","error":错误信息}
    示例:{"id":0,"result":"hello:hello","error":null}
跨语言原理:

通过标准 JSON 格式交换数据,任何支持 JSON 解析的语言(如 Python、Java)都可按此格式调用 Go 的 RPC 服务。

五、基于 HTTP 的 RPC

将 RPC 服务架设在 HTTP 协议上,便于与 Web 系统集成:

服务端实现
func main() {rpc.RegisterName("HelloService", new(HelloService))// 在 HTTP 路径 /jsonrpc 处理 RPC 请求http.HandleFunc("/jsonrpc", func(w http.ResponseWriter, r *http.Request) {// 构造 IO 读写器,适配 HTTP 请求和响应var conn io.ReadWriteCloser = struct {io.Writerio.ReadCloser}{ReadCloser: r.Body,Writer:     w,}rpc.ServeRequest(jsonrpc.NewServerCodec(conn))})http.ListenAndServe(":1234", nil)
}
客户端调用(通过 curl)
curl localhost:1234/jsonrpc -X POST \--data '{"method":"HelloService.Hello","params":["hello"],"id":0}'
优势:
  • 兼容性强:HTTP 是互联网标准协议,支持浏览器、API 网关等多种客户端。
  • 易于调试:可直接通过浏览器或 curl 工具测试 RPC 接口。
六、核心概念总结
  1. RPC 本质:封装网络通信,使远程调用像本地函数调用一样简单。
  2. Go RPC 关键组件
    • 服务注册rpc.RegisterName 绑定服务名与方法。
    • 编解码器:默认 gob,跨语言可用 jsonrpc
    • 连接处理ServeConn(单连接)、ServeCodec(多连接)。
  3. 设计原则
    • 接口与实现分离,通过规范解耦服务端与客户端。
    • 跨语言场景优先使用标准格式(如 JSON)编码数据。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/pingmian/86836.shtml
繁体地址,请注明出处:http://hk.pswp.cn/pingmian/86836.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

第N5周:Pytorch文本分类入门

🍨 本文为🔗365天深度学习训练营中的学习记录博客 🍖 原作者:K同学啊 一、前期准备 1.加载数据 import torch import torch.nn as nn import torchvision from torchvision import transforms,datasets import os,PIL,p…

uniappx 安卓app项目本地打包运行,腾讯地图报错:‘鉴权失败,请检查你的key‘

根目录下添加 AndroidManifest.xml 文件&#xff0c; <application><meta-data android:name"TencentMapSDK" android:value"腾讯地图申请的key" /> </application> manifest.json 文件中添加&#xff1a; "app": {"…

【向上教育】结构化面试开口秘籍.pdf

向 上 教 育 XI A N G S H A N G E D U C A T I O N 结构化 面试 开口秘笈 目 录 第一章 自我认知类 ........................................................................................................................... 2 第二章 工作关系处理类 .......…

Webpack 热更新(HMR)原理详解

&#x1f525; Webpack 热更新&#xff08;HMR&#xff09;原理详解 &#x1f4cc; 本文适用于 Vue、React 等使用 Webpack 的项目开发者&#xff0c;适配 Vue CLI / 自定义 Webpack 项目。 &#x1f3af; 一、什么是 HMR&#xff1f; Hot Module Replacement 是 Webpack 提供的…

MySQL索引完全指南

一、索引是什么&#xff1f;为什么这么重要&#xff1f; 索引就像字典的目录 想象一下&#xff0c;你要在一本1000页的字典里找"程序员"这个词&#xff0c;你会怎么做&#xff1f; 没有目录&#xff1a;从第1页开始一页一页翻&#xff0c;可能要翻500页才能找到有…

学习使用dotnet-dump工具分析.net内存转储文件(2)

运行ShenNiusModularity项目&#xff0c;使用createdump工具dump完整的进程内存映射文件&#xff0c;然后运行dotnet-dump analyze命令加载dump文件。   可以先使用dumpheap命令显示有关垃圾回收堆的信息和有关对象的收集统计信息。dumpheap支持多类参数&#xff08;如下所示…

Oracle BIEE 交互示例(一)同一分析内

Oracle BIEE 交互示例(一)同一分析内 1 示例背景2 实践目标3 实操步骤3.1 创建数据集3.1.1 TEST_TABLE3.1.2 保存名字为【01 TEST_TABLE】3.2 创建分析3.2.1 创建列3.2.2 创建视图3.2.2.1 数据透视表3.2.2.2 图形3.2.2.3 表3.3 设置交互4 结果示例1 示例背景 版本:OBIEE 12…

使用API有效率地管理Dynadot域名,出售账户中的域名

关于Dynadot Dynadot是通过ICANN认证的域名注册商&#xff0c;自2002年成立以来&#xff0c;服务于全球108个国家和地区的客户&#xff0c;为数以万计的客户提供简洁&#xff0c;优惠&#xff0c;安全的域名注册以及管理服务。 Dynadot平台操作教程索引&#xff08;包括域名邮…

Vite 打包原理详解 + Webpack 对比

&#x1f680; Vite 打包原理详解 Webpack 对比 &#x1f44b; 本文适合&#xff1a;Vite 使用者、Vue/React 工程师、希望搞清楚打包流程及与 Webpack 区别的开发者 &#x1f310; 技术背景&#xff1a;Vite 采用 ES Modules 原生浏览器能力驱动开发体验&#xff0c;Webpack…

区块链RWA(Real World Assets)系统开发全栈技术架构与落地实践指南

一、技术架构设计&#xff1a;分层架构与模块协同 1. 核心区块链层 区块链选型策略&#xff1a; 公链&#xff1a;以太坊主网&#xff08;安全性高&#xff0c;DeFi生态完备&#xff09; Polygon CDK&#xff08;Layer2定制化合规链&#xff0c;Gas费低至$0.003&#xff09;…

GBDT:梯度提升决策树——集成学习中的预测利器

核心定位&#xff1a;一种通过串行集成弱学习器&#xff08;决策树&#xff09;、以梯度下降方式逐步逼近目标函数的机器学习算法&#xff0c;在结构化数据预测任务中表现出色。 本文由「大千AI助手」原创发布&#xff0c;专注用真话讲AI&#xff0c;回归技术本质。拒绝神话或妖…

Redis持久化机制深度解析:RDB与AOF全面指南

摘要 本文深入剖析Redis的持久化机制&#xff0c;全面讲解RDB和AOF两种持久化方式的原理、配置与应用场景。通过详细的操作步骤和原理分析&#xff0c;您将掌握如何配置Redis持久化策略&#xff0c;确保数据安全性与性能平衡。文章包含思维导图概览、命令实操演示、核心原理图…

CentOS7升级openssh10.0p2和openssl3.5.0详细操作步骤

背景 近期漏洞扫描时&#xff0c;发现有很多关于openssh的相关高危漏洞&#xff0c;因此需要升级openssh的版本 升级步骤 由于openssh和openssl的版本是需要相匹配的&#xff0c;这次计划将openssh升级至10.0p2版本&#xff0c;将openssl升级至3.5.0版本&#xff0c;都是目前…

fishbot随身系统安装nvidia显卡驱动

小鱼的fishbot是已经配置好的ubuntu22.04,我听说在预先配置系统时需要勾选安装第三方图形化软件&#xff0c;不然直接安装会有进不去图形化界面的风险&#xff0c;若没有勾选&#xff0c;建议使用其他安装方法&#xff0c;比如禁用系统自带的驱动那套安装流程 1.打开设置->关…

学习昇腾开发的第十天--ffmpeg推拉流

1、FFmpeg推流 注意&#xff1a;在推流之前先运行rtsp-simple-server&#xff08;mediamtx&#xff09; ./mediamtx 1.1 UDP推流 ffmpeg -re -i input.mp4 -c copy -f rtsp rtsp://127.0.0.1:8554/stream 1.2 TCP推流 ffmpeg -re -i input.mp4 -c copy -rtsp_transport t…

成为一名月薪 2 万的 web 安全工程师需要掌握哪些技能??

现在 web 安全工程师比较火&#xff0c;岗位比较稀缺&#xff0c;现在除了一些大公司对学历要求严格&#xff0c;其余公司看中的大部分是能力。 有个亲戚的儿子已经工作 2 年了……当初也是因为其他的行业要求比较高&#xff0c;所以才选择的 web 安全方向。 资料免费分享给你…

Pytorch8实现CNN卷积神经网络

CNN卷积神经网络 本章提供一个对CNN卷积网络的快速实现 全连接网络 VS 卷积网络 全连接神经网络之所以不太适合图像识别任务&#xff0c;主要有以下几个方面的问题&#xff1a; 参数数量太多 考虑一个输入10001000像素的图片(一百万像素&#xff0c;现在已经不能算大图了)&…

平地起高楼: 环境搭建

技术选型 本小册是采用纯前端的技术栈模拟实现小程序架构的系列文章&#xff0c;所以主要以前端技术栈为主&#xff0c;但是为了模拟一个App应用的效果&#xff0c;以及小程序包下载管理流程的实现&#xff0c;我们还是需要搭建一个基础的App应用。这里我们将选择 Tauri2.0 来…

langgraph学习2 - MCP编程

3中通信方式&#xff1a; 目前sse用的很少 3.开发mcp框架 主流框架2个&#xff1a; MCP skd 官方 Fast Mcp V2 &#xff0c;&#xff08;V1捐给MCP 官方&#xff09; 大模型如何识别用哪个tools&#xff0c; 以及如何使用tools&#xff1a;

CSS 与 JavaScript 加载优化

&#x1f4c4; CSS 与 JavaScript 加载优化指南&#xff1a;位置、阻塞与性能 让你的网页飞起来&#xff01;&#x1f680; 本文详细解析 CSS 和 JavaScript 标签的放置位置如何影响页面性能&#xff0c;涵盖阻塞原理、浏览器机制和最佳实践。掌握这些知识可显著提升用户体验…