Go语言 RPC 极速入门指南

简介: RPC是远程过程调用(Remote Procedure Call)的缩写形式,是分布式系统中不同节点间流行的通信方式。

RPC是远程过程调用(Remote Procedure Call)的缩写形式,是分布式系统中不同节点间流行的通信方式。

一个完整的RPC架构里面包含了四个核心的组件,分别是Client ,Server,Client Stub以及Server Stub,这个Stub大家可以理解为存根。分别说说这几个组件:

  • 客户端(Client),服务的调用方。
  • 服务端(Server),真正的服务提供者。
  • 客户端存根,存放服务端的地址消息,再将客户端的请求参数打包成网络消息,然后通过网络远程发送给服务方。
  • 服务端存根,接收客户端发送过来的消息,将消息解包,并调用本地的方法。


image.png


Hello, World

Go 语言的 RPC 包的路径为 net/rpc,可以猜测该RPC包是建立在 net 包基础之上的。下面我们尝试基于 rpc 实现一个打印的例子。

服务端 server

先构造一个 HelloService 类型,其中的 Hello 方法用于实现打印功能:

server

package main
import (
  "log"
  "net"
  "net/rpc"
)
// HelloService is rpc server obj
type HelloService struct {}
func (p *HelloService) Hello(request string, reply *string) error {
  *reply = "hello:" + request
  return nil
}
//将HelloService类型的对象注册为一个RPC服务
func main(){
  rpc.RegisterName("HelloService", new(HelloService))
  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)
}
复制代码

其中Hello方法必须满足Go语言的RPC规则:

  • 方法只能有两个可序列化的参数,其中第二个参数是指针 类型
  • 并且返回一个error类型,同时必须是公开的方法。

rpc.Register 函数调用会将对象类型中所有满足 RPC 规则的对象方法注册为 RPC 函数,所有注册 的方法会放在 “HelloService” 服务空间之下。

建立一个唯一的TCP链接,并且通过 rpc.ServeConn 函数在该 TCP 链接上为对方提供 RPC 服务。

客户端 clinet

客户端请求HelloService服务的代码:

package main
import (
  "fmt"
  "log"
  "net/rpc"
)
func main() {
  client, err := rpc.Dial("tcp", "localhost:1234")
  if err != nil {
    log.Fatal("dialing err:", err)
  }
  var reply string
  err = client.Call("HelloService.Hello", "test_rpc", &reply)
  if err != nil {
    log.Fatal(err)
  }
  fmt.Println(reply)
}
复制代码

通过rpc.Dial拨号RPC服务,然后通过client.Call调用具体的RPC方法。在调用 client.Call时,第一个参数是用点号链接的RPC服务名字和方法名字,第二和第三个参数分别我们定 义RPC方法的两个参数。

开启服务器端,开启客户端。客户端的执行结果如下:

$ go run client.go
hello:test_rpc


相关文章
|
1月前
|
Cloud Native 安全 Java
Go语言深度解析:从入门到精通的完整指南
🌟蒋星熠Jaxonic,Go语言探索者。深耕云计算、微服务与并发编程,以代码为笔,在二进制星河中书写极客诗篇。分享Go核心原理、性能优化与实战架构,助力开发者掌握云原生时代利器。#Go语言 #并发编程 #性能优化
366 43
Go语言深度解析:从入门到精通的完整指南
|
1月前
|
存储 安全 Java
【Golang】(4)Go里面的指针如何?函数与方法怎么不一样?带你了解Go不同于其他高级语言的语法
结构体可以存储一组不同类型的数据,是一种符合类型。Go抛弃了类与继承,同时也抛弃了构造方法,刻意弱化了面向对象的功能,Go并非是一个传统OOP的语言,但是Go依旧有着OOP的影子,通过结构体和方法也可以模拟出一个类。
144 1
|
2月前
|
Cloud Native 安全 Java
Go语言深度解析:从入门到精通的完整指南
🌟 蒋星熠Jaxonic,执着的星际旅人,用Go语言编写代码诗篇。🚀 Go语言以简洁、高效、并发为核心,助力云计算与微服务革新。📚 本文详解Go语法、并发模型、性能优化与实战案例,助你掌握现代编程精髓。🌌 从goroutine到channel,从内存优化到高并发架构,全面解析Go的强大力量。🔧 实战构建高性能Web服务,展现Go在云原生时代的无限可能。✨ 附技术对比、最佳实践与生态全景,带你踏上Go语言的星辰征途。#Go语言 #并发编程 #云原生 #性能优化
|
3月前
|
Cloud Native 安全 Java
Go:为云原生而生的高效语言
Go:为云原生而生的高效语言
280 1
|
3月前
|
Cloud Native Go API
Go:为云原生而生的高效语言
Go:为云原生而生的高效语言
355 0
|
3月前
|
Cloud Native Java Go
Go:为云原生而生的高效语言
Go:为云原生而生的高效语言
229 0
|
3月前
|
Cloud Native Java 中间件
Go:为云原生而生的高效语言
Go:为云原生而生的高效语言
209 0
|
3月前
|
Cloud Native Java Go
Go:为云原生而生的高效语言
Go:为云原生而生的高效语言
300 0
|
9月前
|
存储 缓存 安全
Go 语言中的 Sync.Map 详解:并发安全的 Map 实现
`sync.Map` 是 Go 语言中用于并发安全操作的 Map 实现,适用于读多写少的场景。它通过两个底层 Map(`read` 和 `dirty`)实现读写分离,提供高效的读性能。主要方法包括 `Store`、`Load`、`Delete` 等。在大量写入时性能可能下降,需谨慎选择使用场景。
|
存储 负载均衡 监控
如何利用Go语言的高效性、并发支持、简洁性和跨平台性等优势,通过合理设计架构、实现负载均衡、构建容错机制、建立监控体系、优化数据存储及实施服务治理等步骤,打造稳定可靠的服务架构。
在数字化时代,构建高可靠性服务架构至关重要。本文探讨了如何利用Go语言的高效性、并发支持、简洁性和跨平台性等优势,通过合理设计架构、实现负载均衡、构建容错机制、建立监控体系、优化数据存储及实施服务治理等步骤,打造稳定可靠的服务架构。
282 1