golang - gob与rpc

  今天和大家聊聊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) 910//准备编码的数据11type P struct {12    X, Y, Z int13    Name    string14}1516//接收解码结果的结构17type Q struct {18    X, Y *int3219    Name string20}2122func main() {23    //初始化一个数据24    data := P{3, 4, 5, "CloudGeek"}25    //编码后得到buf字节切片26    buf := encode(data)27    //用于接收解码数据28    var q *Q29    //解码操作30    q = decode(buf)31    //"CloudGeek": {3,4}32    fmt.Printf("%q: {%d,%d}\n", q.Name, *q.X, *q.Y)3334}3536func encode(data interface{}) *bytes.Buffer {37    //Buffer类型实现了io.Writer接口38    var buf bytes.Buffer39    //得到编码器40    enc := gob.NewEncoder(&buf)41    //调用编码器的Encode方法来编码数据data42    enc.Encode(data)43    //编码后的结果放在buf中44    return &buf45}4647func decode(data interface{}) *Q {48    d := data.(io.Reader)49    //获取一个解码器,参数需要实现io.Reader接口50    dec := gob.NewDecoder(d)51    var q Q52    //调用解码器的Decode方法将数据解码,用Q类型的q来接收53    dec.Decode(&q)54    return &q55}

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

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

  上面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 int11}1213//定义一个算术类型,其实就是int14type Arith int1516//实现乘法的方法绑定到Arith类型,先不管为什么是这样的形式17func (t *Arith) Multiply(args *Args, reply *int) error {18    *reply = args.A * args.B19    return nil20}2122func 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 int10}1112func main() {13    //连接服务器端,创建一个client14    client, _ := rpc.DialHTTP("tcp", "127.0.0.1:1234")15    args := &Args{7, 8}16    var reply int17    //通过Call方法调用Arith类型的Multiply方法,注意形参18    client.Call("Arith.Multiply", args, &reply)19    //得到调用结果,输出Arith: 7*8=5620    fmt.Printf("Arith: %d*%d=%d\n", 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/

原文地址:https://www.cnblogs.com/cloudgeek/p/9348267.html

时间: 2024-10-29 08:20:22

golang - gob与rpc的相关文章

[转]Golang Gob编码

Golang Gob编码 2012-08-24 09:47 by 轩脉刃, 5119 阅读, 1 评论, 收藏, 编辑 gob是Golang包自带的一个数据结构序列化的编码/解码工具.编码使用Encoder,解码使用Decoder.一种典型的应用场景就是RPC(remote procedure calls). gob和json的pack之类的方法一样,由发送端使用Encoder对数据结构进行编码.在接收端收到消息之后,接收端使用Decoder将序列化的数据变化成本地变量. 有一点需要注意, 发送

golang中的rpc包用法

RPC,即 Remote Procedure Call(远程过程调用),说得通俗一点就是:调用远程计算机上的服务,就像调用本地服务一样. 我所在公司的项目是采用基于Restful的微服务架构,随着微服务之间的沟通越来越频繁,就希望可以做成用rpc来做内部的通讯,对外依然用Restful.于是就想到了golang标准库的rpc包和google的grpc. 这篇文章重点了解一下golang的rpc包. 介绍 golang的rpc支持三个级别的RPC:TCP.HTTP.JSONRPC.但Go的RPC包

用Golang手写一个RPC,理解RPC原理

代码结构 . ├── client.go ├── coder.go ├── coder_test.go ├── rpc_test.go ├── server.go ├── session.go └── session_test.go 代码 client.go package rpc import ( "net" "reflect" ) // rpc 客户端实现 // 抽象客户端方法 type Client struct { conn net.Conn } // cl

2.微服务--RPC

1.RPC简介 1.远程过程调用(Remote Procedure Call,RPC)是一个计算机通信协议. 2.该协议允许运行于一台计算机的程序调用另一台计算机的子程序,而程序员无需额外地为这个交互作用编程. 3.如果涉及的软件采用面向对象编程,那么远程过程调用也可称为远程调用或远程方法调用. 2.流行的RPC框架的对比 3.golang中如何实现RPC Golang中实现RPC比较简单,官方提供了封装好的库,还有第三方库. 官方库:net/rpc 1.net/rpc库使用encoding/g

Go语言_RPC_Go语言的RPC

一 标准库的RPC RPC(Remote Procedure Call,远程过程调用)是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络细节的应用程序通信协议.简单的说就是要像调用本地函数一样调用服务器的函数. RPC协议构建于TCP或UDP,或者是 HTTP之上,允许开发者直接调用另一台计算机上的程序,而开发者无需额外地为这个调用过程编写网络通信相关代码,使得开发包括网络分布式程序在内的应用程序更加容易. Go语言的标准库已经提供了RPC框架和不同的RPC实现. 下面是一个服务器的

国际网络环境对库的影响

国际网络环境可以理解为延迟很大.经常掉线.丢包的环境,和跨机房环境是一样的,不过,前者掉线严重,延迟更大,比如德国来回一般有300ms,美国有200ms,新加坡一般是90ms. golang标准库RPC 虽然是表面看是block调用,但是内部的实现不是一应一答,发送一次请求之后并不会等待结果再发送下一次请求,所以效率也是很高的.而且,如果发生网络出错,一定会通知到调用端,调用端只要做多次请求即可. 问题在于缺少timeout机制,容易在异常断开情况下,产生阻塞很久的错觉. 这个问题可以加个tim

golang rpc 简单范例

RPC(Remote Procedure Call Protocol)--远程过程调用协议,它是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的协议. 它的工作流程如下图:   golang 使用 RPC的例子如下: 服务器端代码: 这里暴露了一个RPC接口,一个HTTP接口 package main import (     "fmt"     "io"     "net"     "net/http"  

谈谈RPC——golang中jsonrpc和grpc的使用

前言 不知从什么时候rpc这个东西开始进入我们的视野,一开始做开发的时候经常使用的都是http,偶尔使用的是socket进行通信,使用的是restful的方式.但是,一次偶然的机会你会发现RPC这个东西进入了你的视野,而且由于微服务的兴起然他迅速被人们所知,那么它是什么,又如何使用呢? RPC定义 RPC,即 Remote Procedure Call(远程过程调用),说得通俗一点就是:调用远程计算机上的服务,就像调用本地服务一样. 说的再实际一点: 如果我们之前使用UserService.ge

golang——net/rpc包学习

1.rpc包 rpc包提供了通过网络或其他I/O连接对一个对象的导出方法的访问. 只有满足如下标准的方法才能用于远程访问,其余方法会被忽略: (1)方法是导出的(2)方法有两个参数,都是导出类型或内建类型(3)方法的第二个参数是指针(4)方法只有一个error接口类型的返回值 func (t *T) MethodName(argType T1, replyType *T2) error 其中T.T1和T2都能被encoding/gob包序列化. 方法的第一个参数代表调用者提供的参数:第二个参数代