golang-gob与rpc(代码片段)

cloudgeek cloudgeek     2022-12-16     553

关键词:

  今天和大家聊聊golang中怎么使用rpc,rpc数据传输会涉及到gob编码,所以先讲讲gob,别担心,就算你完全没有接触过gob与rpc,只要知道rpc的中文是远程过程调用,剩下的我都能给你讲明白(带你入门不包你精通)!

一、数据结构编码之gob

  gob全称为:Go binary

  Golang自带的一个数据结构序列化编码/解码工具,也就是说gob可以讲go中的一个数据结构序列化成某种东西,还能反序列化!序列化成啥我们后面来看,不管是变成一个字符串,变成二进制流,变成啥先不管,反正作用就是序列化。

  Gob使用时我们需要关注Encoder和Decoder对象,顾名思义,一个是编码的时候用的,一个是解码的时候用的,我们看一下怎么获取这两个对象先:

技术分享图片

 

技术分享图片

  所以很明确,需要调用这两个函数来获取Encoder和Decoder对象。注意这里的参数是io.Writer和io.Reader接口类型,我们在上一讲介绍过这两个接口,所以这里需要的参数分别是实现了io.Writer和io.Reader接口类型的对象即可。

  Encoder和Decoder分别有一个主要的方法是:

技术分享图片

 

技术分享图片

  看到这里我们已经可以得到如下结论:

  Gob 使用 io.Writer 接口,通过 NewEncoder() 函数创建 Encoder 对象通过调用 Encode()方法实现编码操作;使用 io.Reader 接口,通过 NewDecoder() 函数创建 Decoder 对象并调用 Decode()方法完成解码操作!

  接下来我们试着用一下这个Encoder和Decoder,就轻轻松松入门gob了,来看第一个例子

  例1:数据结构与bytes.Buffer之间的转换(编码成字节切片)

 1package main
2
3import (
4    "bytes"
5    "fmt"
6    "encoding/gob"
7    "io"
8)
9
10//准备编码的数据
11type P struct 
12    X, Y, Z int
13    Name    string
14
15
16//接收解码结果的结构
17type Q struct 
18    X, Y *int32
19    Name string
20
21
22func main() 
23    //初始化一个数据
24    data := P345"CloudGeek"
25    //编码后得到buf字节切片
26    buf := encode(data)
27    //用于接收解码数据
28    var q *Q
29    //解码操作
30    q = decode(buf)
31    //"CloudGeek": 3,4
32    fmt.Printf("%q: %d,%d ", q.Name, *q.X, *q.Y)
33
34
35
36func encode(data interface) *bytes.Buffer 
37    //Buffer类型实现了io.Writer接口
38    var buf bytes.Buffer
39    //得到编码器
40    enc := gob.NewEncoder(&buf)
41    //调用编码器的Encode方法来编码数据data
42    enc.Encode(data)
43    //编码后的结果放在buf中
44    return &buf
45
46
47func decode(data interface) *Q 
48    d := data.(io.Reader)
49    //获取一个解码器,参数需要实现io.Reader接口
50    dec := gob.NewDecoder(d)
51    var q Q
52    //调用解码器的Decode方法将数据解码,用Q类型的q来接收
53    dec.Decode(&q)
54    return &q
55

  例2:数据结构到文件的序列化和反序列化

 1package main
2
3import (
4    "encoding/gob"
5    "os"
6    "fmt"
7)
8
9//试验用的数据类型
10type Address struct 
11    City    string
12    Country string
13
14
15//序列化后数据存放的路径
16var filePath string
17
18func main() 
19    filePath = "./address.gob"
20    encode()
21    pa := decode()
22    fmt.Println(*pa) //Chengdu China
23
24
25//将数据序列号后写到文件中
26func encode() 
27    pa := &Address"Chengdu""China"
28    //打开文件,不存在的时候新建
29    file, _ := os.OpenFile(filePath, os.O_CREATE|os.O_WRONLY, 0666)
30    defer file.Close()
31
32    //encode后写到这个文件中
33    enc := gob.NewEncoder(file)
34    enc.Encode(pa)
35
36
37//从文件中读取数据并反序列化
38func decode() *Address 
39    file, _ := os.Open(filePath)
40    defer file.Close()
41
42    var pa Address
43    //decode操作
44    dec := gob.NewDecoder(file)
45    dec.Decode(&pa)
46    return &pa
47

  上面2个例子都不难,我去掉了错误处理之类的代码,尽量注释了每块代码,耐心看完这2个例子应该就能体会gob的encode和decode精髓了。

理解gob是什么的基础上,如果你需要使用gob开发,建议详细看一下官方文档,了解一下更多的细节:https://golang.org/pkg/encoding/gob/

 

二、golang中的rpc入门

  如果你之前没有做过基于rpc通信的开发工作,直接去网上查rpc相关的知识点的时候很可能会一脸蒙圈,rest api咋就那么好理解,一个http请求过去就行了,rpc咋个回事,看不懂呀。。。

  所以我不会和多数教程一样为了追求详细或者展示自己技术多牛而去写很长的例子,扯一堆专业的概念,我们先最快的方式体验一下rpc调用的感觉!

  rpc服务端

 1package main
2
3import (
4    "net"
5    "net/rpc"
6    "net/http"
7)
8
9type Args struct 
10    A, B int
11
12
13//定义一个算术类型,其实就是int
14type Arith int
15
16//实现乘法的方法绑定到Arith类型,先不管为什么是这样的形式
17func (t *Arith) Multiply(args *Args, reply *int) error 
18    *reply = args.A * args.B
19    return nil
20
21
22func main() 
23    //得到一个Arith类型的指针实例
24    arith := new(Arith)
25    //注册到rpc服务
26    rpc.Register(arith)
27    //挂到http服务上
28    rpc.HandleHTTP()
29    //开始监听
30    l, _ := net.Listen("tcp"":1234")
31    http.Serve(l, nil)
32

  rpc客户端

 1package main
2
3import (
4    "net/rpc"
5    "fmt"
6)
7
8type Args struct 
9    A, B int
10
11
12func main() 
13    //连接服务器端,创建一个client
14    client, _ := rpc.DialHTTP("tcp""127.0.0.1:1234")
15    args := &Args78
16    var reply int
17    //通过Call方法调用Arith类型的Multiply方法,注意形参
18    client.Call("Arith.Multiply", args, &reply)
19    //得到调用结果,输出Arith: 7*8=56
20    fmt.Printf("Arith: %d*%d=%d ", args.A, args.B, reply)
21

  上面2段程序很简短,可能你现在还不能理解其中的细节,但也请耐心看完,这个时候你应该能够心里有个rpc调用的概念了,客户端直接调用了服务器端的一个函数传递过去参数列表和接收返回值的对象,获得调用结果。

 

三、rpc的一些细节

  下面我们再来看一些rpc相关的细节

  首先能够被rpc调用的方法应该看起来像这样:

func (t *T) MethodName(argType T1, replyType *T2) error

  大概解释一下:

  • 函数必须是可导出的(首字母大写)
  • 必须有两个导出类型的参数,第一个参数用来接收参数,第二个参数是返回给客户端的结果参数,第二个参数必须是指针类型的
  • 函数还要有一个返回值error
  • T1、T2能够被encoding/gob编码

  看到这里你应该对于rpc的作用有了一定的认识,go中rpc包的用法简单来看就是准备一个类型,绑定一堆符合规范的方法,然后注册给rpc服务,监听客户端连接,客户端通过rpc包提供的Call方法可以调用到server注册好的方法。更多细节可以看一下官方文档:https://golang.org/pkg/net/rpc/

技术分享图片

go微服务rpc的原理与gorpc(代码片段)

本文介绍了RPC的概念以及Go语言中标准库rpc的基本使用。什么是RPCRPC(RemoteProcedureCall),即远程过程调用。它允许像调用本地服务一样调用远程服务。RPC是一种服务器-客户端(Client/Server)模式,经典实现... 查看详情

go微服务rpc的原理与gorpc(代码片段)

本文介绍了RPC的概念以及Go语言中标准库rpc的基本使用。什么是RPCRPC(RemoteProcedureCall),即远程过程调用。它允许像调用本地服务一样调用远程服务。RPC是一种服务器-客户端(Client/Server)模式,经典实现... 查看详情

protobuf源码解析与netty+rpc实战(代码片段)

1.背景grpc由protobuf+netty实现,为了研究grpc框架的设计思想,本文从protobuf生成的java源码出发,脱离grpc框架研究protobuf的框架。在此基础上,基于protobuf+netty手写一个rpc框架,熟悉rpc的设计思路。2.逐步深入protobuf2.1protobuf工作流程p... 查看详情

基于zookeeper与netty实现的分布式rpc服务(代码片段)

...中,随着系统访问量提高,业务复杂度提高,代码复杂度提高,应用逐渐从单体式架构向面向服务的 查看详情

flink内核原理学习组件通信rpc(代码片段)

Flink内核原理学习之RPC文章目录Flink内核原理学习之RPC一、Akka与Actor模型二、RPC消息类型三、Flink通信组件3.1RpcGateway3.2RpcEndpoint3.3RpcService与RpcServer3.4AkkaRpcActor四、PRC交互过程Java、大数据开发学习要点(持续更新中…)一、... 查看详情

13.rpc的socket实现(阻塞式)与netty实现(非阻塞式)(代码片段)

【README】1.本文总结了RPC的概念,包括定义,RPC实现,及其优缺点;2.本文po出了RPC的简单代码实现,总结自B站《netty-尚硅谷》;3.本文部分内容总结自:WhatIsRemoteProcedureCall(RPC)?DefinitionfromSearchAppArchitectu 查看详情

分布式与微服务系列分布式rpc框架apachedubbo服务(代码片段)

分布式RPC框架ApacheDubbo服务一、ApacheDubbo概述1.1、Dubbo简介1.2、什么是RPC?1.3、什么是服务发现?1.3、Dubbo架构二、服务注册中心Zookeeper2.1、Zookeeper介绍2.2、安装Zookeeper2.3、启动、停止Zookeeper三、Dubbo快速入门3.1、服务提供... 查看详情

手写rpc框架第七天服务发现与注册(代码片段)

手写RPC框架第七天服务发现与注册1.注册中心的位置注册中心的位置如上图所示。注册中心的好处在于,客户端和服务端都只需要感知注册中心的存在,而无需感知对方的存在。更具体一些:服务端启动后,向注... 查看详情

http与rpc区别比较分析(代码片段)

HTTP与RPC区别比较分析一、TCP的特点与问题二、HTTP与RPC1、HTTP协议2、RPC协议3、有了HTTP,why要出现RPC协议4、有了RPC,why要出现HTTP协议三、HTTP与RPC的区别1、服务发现2、底层连接形式3、传输的内容一、TCP的特点与问题我们... 查看详情

13.rpc的socket实现(阻塞式)与netty实现(非阻塞式)(代码片段)

...#xff0c;RPC实现,及其优缺点;2.本文po出了RPC的简单代码实现,总结自B站《netty-尚硅谷》;3.本文部分内容总结自:WhatIsRemoteProcedureCall(RPC)?DefinitionfromSearchAppArchitecture4.本文还po出了RPC与RMI的区别;5.基于socket... 查看详情

java实现简单的rpc框架(代码片段)

0引言  RPC,全称为RemoteProcedureCall,即远程过程调用,它是一个计算机通信协议。它允许像调用本地服务一样调用远程服务。它可以有不同的实现方式。如RMI(远程方法调用)、Hessian、Httpinvoker等。另外,RPC是与语言无关的。 ... 查看详情

大鹏rpc流程分析(代码片段)

大鹏RPC1.概述采用Zookeeper作为注册中心,记录服务提供者IP端口信息.客户端读取Zookeeper上已注册的服务提供方信息.服务器与客户端采用Netty通讯.序列化方式为TProtocol2.通讯协议项层协议为:TProtocol2.1.数据包4bytes1byte1byte1byte4bytesheaderb... 查看详情

go微服务rpc的原理与gorpc(代码片段)

...RPC调用本地过程调用发生在同一进程中——定义add函数的代码和调用add函数的代码共享同一个内 查看详情

fiscobcos区块链修改增加rpc接口(代码片段)

一、RPCRPC(RemoteProcedureCall,远程过程调用)是客户端与区块链系统交互的一套协议和接口。用户通过RPC接口可查询区块链相关信息(如块高、区块、节点连接等)和发送交易。介绍文档远程过程调用(RPC)—FISCO... 查看详情

fiscobcos区块链修改增加rpc接口(代码片段)

一、RPCRPC(RemoteProcedureCall,远程过程调用)是客户端与区块链系统交互的一套协议和接口。用户通过RPC接口可查询区块链相关信息(如块高、区块、节点连接等)和发送交易。介绍文档远程过程调用(RPC)—FISCO... 查看详情

设计一个分布式rpc框架(代码片段)

0前言提前先祝大家春节快乐!好了,先简单聊聊。我从事的是大数据开发相关的工作,主要负责的是大数据计算这块的内容。最近Hive集群跑任务总是会出现Thrift连接HS2相关问题,研究了解了下内部原理,突然来了兴趣,就想着... 查看详情

组件篇值rpc(上)(代码片段)

组件篇值RPC(上)基础架构暂时无法在文档外展示此内容基础架构之组件篇组件篇RPC注册中心Zookeeper配置中心Nacos消息队列事务消息延时消息Spring组件篇之RPC(上)01.RPC原理分析理解RPCRemoteProcedureCall远程过程调用基于网络表... 查看详情

nfs服务搭建与配置(代码片段)

NFS服务搭建与配置NFS介绍NFS服务端安装配置NFS配置选项exportfs命令NFS客户端问题NFS介绍NFS是NetworkFileSystem的缩写NFS最早由Sun公司开发,分2,3,4三个版本,2和3由Sun起草开发,4.0开始Netapp公司参与并主导开发,最新为4.1版本NFS数据... 查看详情