前言
远程过程调用(远程过程调用,简称RPC )是计算机通信协议。 通过该协议程序员,可以实现像调用本地函数那样调用远程服务的函数。 下面介绍高效的rpc库(rpcx )。
rpcx是一种分布式的Go语言RPC框架,支持Zookepper、etcd、consul多种服务发现方式、多种服务路由方式,是目前性能最高的RPC框架之一。
官方资料: https://books.study golang.com /谷歌/
项目: https://github.com /小型网络/rpcx
功能
支持原始的Go功能。 不需要定义原型文件。 插件可以扩展服务发现、跟踪等功能。 TCP、HTTP、QUIC和KCP支持编解码器,如JSON、Protobuf、消息包和原始字节。 服务发现。 支持peer2peer、预配置的peer、zookeeper、etcd、控制台和mDNS。 容错能力:故障转移、故障转移、故障转移。 负载平衡:支持随机、循环、一致的sldzc、加权、网络质量和地理位置。 支持裁军。 支持元数据的分发。 支持许可证。 支持心跳和单方面请求。 其他功能:指标、日志、超时、别名、断路器。 支持双向通信。 由于支持通过HTTP访问,因此可以用任何编程语言创建客户端。 支持API网关。 支持备份请求、分支和广播。 rpcx使用二进制协议,与平台无关。 也就是说,可以使用其他语言(如Java、Python和nodejs )开发服务,也可以调用Go开发的服务。
性能
测试结果表明,除标准rpc库外,rpcx的性能优于其他rpc框架。
快速开始
基本安装
千兆以太网.com /小型网/rpcx/.服务端
新服务器. go打包主
import (
上下文
'标志'
' fmt '。
示例' Github.com/RPC Xio/rpcx -示例'
' github.com /小型网/rpcx /服务器'
)
var (
addr=flag.string('addr ',' localhost:8972 ','服务器地址' ) )
)
类型体系结构
//thesecondparameterisnotapointer
func(t*Arith ) mul (CTX上下文.上下文,args example.Args,复制*实例.复制)错误) ) ) )
reply.c=阿瑟. a *阿瑟. b
FMT.println('c=',复制. c ) )。
返回尼尔
}
功能主()
flag.Parse (
s :=服务器.新服务器(
//s.register (新建(区域),'')
s .注册名称(' arith ',新建),' )
ERR:=s.serve('TCP ',*addr ) ) ) ) )。
红外!=聂耳
是帕尼克(ERR )
}
客户端
客户端. go打包主
import (
上下文
'标志'
' fmt '。
日志
' github.com /小型网/rpcx /协议'
示例' Github.com/RPC Xio/rpcx -示例'
' github.com /小型网/rpcx /客户端'
)
var (
addr=flag.string('addr ',' localhost:8972 ','服务器地址' ) )
)
功能主()
flag.Parse (
d :=客户端.新对等2对等发现(' TCP @ ' *添加,'')
opt :=客户端.默认选项
opt .序列类型=协议. JSON
x客户端:=客户端. newx客户端(' arith ',客户端.故障树,客户端.随机选择,d,op
t) 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= 200 2020/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 main import ( "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/rpcxrn" . // "X-RPCX-MessageID: 12345678rn" . // "X-RPCX-MesssageType: 0rn" . "X-RPCX-SerializeType: 1rn" . "X-RPCX-ServicePath: Arithrn" . "X-RPCX-ServiceMethod: Mulrn", '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/rpcx-gateway/blob/master/examples/README.md
rpcx 3.0已针对以下目标进行了重构:
简单:易于学习,易于开发,易于交互和易于部署性能:高性能(> = grpc-go)跨平台:支持字节,JSON,Protobuf和MessagePack的**原始切片。从理论上讲,它可以与java,php,python,c / c ++,node.js,c#和其他平台一起使用服务发现和服务治理:支持zookeeper,etcd和consul。相关资料
https://github.com/rpcxio/rpcx-gateway
https://github.com/smallnest/rpcx