初识RPC
介绍
RPC 是远程过程调用的简称,是分布式系统中不同节点间流行的通信方式。在互联网时代,RPC 已经和 IPC 一样成为一个不可或缺的基础构件。因此 Go 语言的标准库也提供了一个简单的 RPC 实现,我们将以此为入口学习 RPC 的各种用法。
hello RPC
server端代码
package main
import ( "log" "net" "net/rpc" )
type HelloService struct{}
func (p *HelloService) Hello(request string, reply *string) error { *reply = "hello:" + request return nil }
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) }
|
client代码
package main
import ( "fmt" "log" "net/rpc" )
func main() { client, err := rpc.Dial("tcp", "localhost:1234") if err != nil { panic(err) } var reply string err = client.Call("HelloService.Hello", "hello", &reply) if err != nil { log.Fatal(err) }
fmt.Println(reply) }
|
跨语言的RPC
go的RPC默认采用go独有的gob编码,其他语言无法直接调用
基于JSON的RPC
server端
package main
import ( "log" "net" "net/rpc" "net/rpc/jsonrpc" )
type HelloService struct{}
func (p *HelloService) Hello(request string, reply *string) error { *reply = "hello:" + request return nil }
func main() { rpc.RegisterName("HelloService", new(HelloService))
listener, err := net.Listen("tcp", ":1234") if err != nil { log.Fatal("ListenTCP error:", err) }
for { conn, err := listener.Accept() if err != nil { log.Fatal("Accept error:", err) }
go rpc.ServeCodec(jsonrpc.NewServerCodec(conn)) } }
|
client
package main
import ( "fmt" "log" "net/rpc" )
func main() { client, err := rpc.Dial("tcp", "localhost:1234") if err != nil { panic(err) } var reply string err = client.Call("HelloService.Hello", "hello", &reply) if err != nil { log.Fatal(err) }
fmt.Println(reply) }
|