前言

近程过程调用(Remote Procedure Call,缩写为 RPC)是一个计算机通信协议。通过该协定程序员能够实现像调取本地函数一样,调取近程服务的函数。这里介绍一个高效的rpc库(rpcx)。

rpcx 是一个分布式的Go语言的 RPC 框架,反对Zookepper、etcd、consul多种服务发现形式,多种服务路由形式, 是目前性能最好的 RPC 框架之一。

官网材料:https://books.studygolang.com...

我的项目:https://github.com/smallnest/...

性能

  • 反对原始Go性能。无需定义原型文件。
  • 可插拔 能够扩大性能,例如服务发现,跟踪。
  • 反对TCP,HTTP,QUIC和KCP
  • 反对多种编解码器,例如JSON,Protobuf,MessagePack和原始字节。
  • 服务发现。反对peer2peer,已配置的peer,zookeeper,etcd,consul和mDNS。
  • 容错:故障转移,故障转移,故障转移。
  • 负载平衡:反对随机,轮循,统一哈希,加权,网络品质和地理位置。
  • 反对压缩。
  • 反对传递元数据。
  • 反对受权。
  • 反对心跳和单向申请。
  • 其余性能:指标,日志,超时,别名,断路器。
  • 反对双向通信。
  • 反对通过HTTP拜访,因而您能够应用任何编程语言编写客户端。
  • 反对API网关。
  • 反对备份申请,分叉和播送。

rpcx应用二进制协定且与平台无关,这意味着您能够应用其余语言(例如Java,Python,nodejs)开发服务,还能够应用其余编程语言来调用Go中开发的服务。

性能

测试结果表明,除了规范rpc库之外,rpcx的性能要优于其余rpc框架。

疾速开始

根本装置

go get -v github.com/smallnest/rpcx/...
服务端

新建server.go

package mainimport (    "context"    "flag"    "fmt"    example "github.com/rpcxio/rpcx-examples"    "github.com/smallnest/rpcx/server")var (    addr = flag.String("addr", "localhost:8972", "server address"))type Arith struct{}// the second parameter is not a pointerfunc (t *Arith) Mul(ctx context.Context, args example.Args, reply *example.Reply) error {    reply.C = args.A * args.B    fmt.Println("C=", reply.C)    return nil}func main() {    flag.Parse()    s := server.NewServer()    //s.Register(new(Arith), "")    s.RegisterName("Arith", new(Arith), "")    err := s.Serve("tcp", *addr)    if err != nil {        panic(err)    }}
客户端

client.go

package mainimport (    "context"    "flag"    "fmt"    "log"    "github.com/smallnest/rpcx/protocol"    example "github.com/rpcxio/rpcx-examples"    "github.com/smallnest/rpcx/client")var (    addr = flag.String("addr", "localhost:8972", "server address"))func main() {    flag.Parse()    d := client.NewPeer2PeerDiscovery("tcp@"+*addr, "")    opt := client.DefaultOption    opt.SerializeType = protocol.JSON    xclient := client.NewXClient("Arith", client.Failtry, client.RandomSelect, d, opt)    defer xclient.Close()    args := example.Args{        A: 10,        B: 20,    }    reply := &example.Reply{}    err := xclient.Call(context.Background(), "Mul", args, reply)    if err != nil {        log.Fatalf("failed to call: %v", err)    }    log.Printf("%d * %d = %d", args.A, args.B, reply.C)}
运行

服务端

go  run server.go

客户端

go run client.go

这时服务端输入:

C= 2002020/07/21 15:19:02 server.go:358: INFO : client has closed this connection: 127.0.0.1:50186

客户端输入:

2020/07/21 15:19:02 10 * 20 = 200

跨语言

rpcx还提供了rpcx-gateway,您能够应用任何编程语言编写客户端,以通过rpcx-gateway调用rpcx服务。

装置rpcx-gateway

go  get  github.com/rpcxio/rpcx-gateway
示例

新建gateway.go文件,代码如下:

package mainimport (    "errors"    "flag"    "fmt"    "log"    "strings"    "time"    gateway "github.com/rpcxio/rpcx-gateway"    "github.com/rpcxio/rpcx-gateway/gin"    "github.com/smallnest/rpcx/client")var (    addr       = flag.String("addr", ":9981", "http server address")    registry   = flag.String("registry", "peer2peer://127.0.0.1:8972", "registry address")    basePath   = flag.String("basepath", "/rpcx", "basepath for zookeeper, etcd and consul")    failmode   = flag.Int("failmode", int(client.Failover), "failMode, Failover in default")    selectMode = flag.Int("selectmode", int(client.RoundRobin), "selectMode, RoundRobin in default"))func main() {    flag.Parse()    d, err := createServiceDiscovery(*registry)    if err != nil {        log.Fatal(err)    }    httpServer := gin.New(*addr)    gw := gateway.NewGateway("/", httpServer, d, client.FailMode(*failmode), client.SelectMode(*selectMode), client.DefaultOption)    gw.Serve()}func createServiceDiscovery(regAddr string) (client.ServiceDiscovery, error) {    i := strings.Index(regAddr, "://")    if i < 0 {        return nil, errors.New("wrong format registry address. The right fotmat is [registry_type://address]")    }    regType := regAddr[:i]    regAddr = regAddr[i+3:]    switch regType {    case "peer2peer": //peer2peer://127.0.0.1:8972        return client.NewPeer2PeerDiscovery("tcp@"+regAddr, ""), nil    case "multiple":        var pairs []*client.KVPair        pp := strings.Split(regAddr, ",")        for _, v := range pp {            pairs = append(pairs, &client.KVPair{Key: v})        }        return client.NewMultipleServersDiscovery(pairs), nil    case "zookeeper":        return client.NewZookeeperDiscoveryTemplate(*basePath, []string{regAddr}, nil), nil    case "etcd":        return client.NewEtcdDiscoveryTemplate(*basePath, []string{regAddr}, nil), nil    case "etcdv3":        return client.NewEtcdV3DiscoveryTemplate(*basePath, []string{regAddr}, nil), nil    case "consul":        return client.NewConsulDiscoveryTemplate(*basePath, []string{regAddr}, nil), nil    case "redis":        return client.NewRedisDiscoveryTemplate(*basePath, []string{regAddr}, nil), nil    case "mdns":        return client.NewMDNSDiscoveryTemplate(10*time.Second, 10*time.Second, ""), nil    default:        return nil, fmt.Errorf("wrong registry type %s. only support peer2peer,multiple, zookeeper, etcd, consul and mdns", regType)    }}

运行 gateway.go

go run  gateway.go

留神:运行网关前,要保障rpcx服务端(server.go)启动,这里以php客户端为例

新建client.php

代码如下:

<?php$url = 'http://localhost:9981/';$data = '{"A":10, "B":20}';// use key 'http' even if you send the request to https://...$options = array(    'http' => array(        'header'  => "Content-type: application/rpcx\r\n" .            // "X-RPCX-MessageID: 12345678\r\n" .            // "X-RPCX-MesssageType: 0\r\n" .            "X-RPCX-SerializeType: 1\r\n" .            "X-RPCX-ServicePath: Arith\r\n" .            "X-RPCX-ServiceMethod: Mul\r\n",        'method'  => 'POST',        'content' => $data    ));$context  = stream_context_create($options);$result = file_get_contents($url, false, $context);if ($result === FALSE) { /* Handle error */ }var_dump($result);?>

拜访http://localhost/client.php

后果:

string(9) "{"C":200}"

server.go 输入

C= 200

这样就实现跨语言了。

其余语言示例

https://github.com/rpcxio/rpc...

rpcx 3.0已针对以下指标进行了重构:

  1. 简略:易于学习,易于开发,易于交互和易于部署
  2. 性能:高性能(> = grpc-go)
  3. 跨平台:反对字节JSONProtobufMessagePack的原始切片。从实践上讲,它能够与java,php,python,c / c ++,node.js,c#和其余平台一起应用
  4. 服务发现和服务治理:反对zookeeper,etcd和consul。

相干材料

https://github.com/rpcxio/rpc...

https://github.com/smallnest/...

links

  • 目录
  • 上一节:
  • 下一节: