rpcx-gateway是为rpcx提供网关服务的,官方是这样定义的:
Gateway 为 rpcx services 提供了 http 网关服务.
你可以使用你熟悉的编程语言, 比如Java、Python、C#、Node.js、Php、C\C++、Rust等等来调用 rpcx 服务。查看一些编程语言实现的例子 。
这意味着,你可以不用实现 rpcx的协议,而是使用熟悉的 http 访问方式调用 rpcx 服务, 设置用curl
、wget
等命令行工具。
测试工具:Jmeter
测试环境:macbook pro 自建zookeeper+rpcx
测试目的:两者的性能差异
一、不使用rpcx-gateway提供http访问rpcx
package main
import (
"context"
"flag"
"fmt"
"log"
"net/http"
"strconv"
_"time"
example "github.com/rpcxio/rpcx-examples"
"github.com/smallnest/rpcx/client"
)
var (
zkAddr = flag.String("zkAddr", "localhost:2181", "zookeeper address")
basePath = flag.String("base", "/youpin/services", "prefix path")
)
func main() {
flag.Parse()
d := client.NewZookeeperDiscovery(*basePath, "Arith", []string{*zkAddr}, nil)
xclient := client.NewXClient("Arith", client.Failtry, client.RandomSelect, d, client.DefaultOption)
defer xclient.Close()
args := &example.Args{
A: 10,
B: 20,
}
reply := &example.Reply{}
http.HandleFunc("/", func(writer http.ResponseWriter, request *http.Request) {
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)
fmt.Fprintf(writer, strconv.Itoa(reply.C))
})
// }()
uri := "127.0.0.1:8090"
er := http.ListenAndServe(uri, nil)
if er != nil {
log.Fatal("ListenAndServe: ", er)
}
}
func handleToken(w http.ResponseWriter, r *http.Request) {
//time.Sleep(1e9)
}
二、使用rpcx-gateway 访问 rpcx
package main
import (
"flag"
_ "time"
gateway "github.com/rpcxio/rpcx-gateway"
"github.com/rpcxio/rpcx-gateway/gin"
"github.com/smallnest/rpcx/client"
)
var (
zkAddr = flag.String("zkAddr", "localhost:2181", "zookeeper address")
basePath = flag.String("base", "/youpin", "prefix path")
failmode = flag.Int("failmode", int(client.Failover), "failMode, Failover in default")
selectMode = flag.Int("selectmode", int(client.RoundRobin), "selectMode, RoundRobin in default")
registry = flag.String("registry", "127.0.0.1:8972", "registry address")
)
func main() {
flag.Parse()
d := client.NewZookeeperDiscovery(*basePath, "services", []string{*zkAddr}, nil)
uri := "127.0.0.1:8089"
httpServer := gin.New(uri)
gw := gateway.NewGateway("/index.do", httpServer, d, client.FailMode(*failmode), client.SelectMode(*selectMode), client.DefaultOption)
gw.Serve()
}
service.go
// Package example defines datastructure and services.
package example
import (
"context"
"fmt"
)
type Args struct {
A int
B int
}
type Reply struct {
C int
}
type Arith int
type Arith1 int
type Arith2 int
func (t *Arith) Mul(ctx context.Context, args *Args, reply *Reply) error {
reply.C = args.A * args.B
fmt.Printf("call: %d * %d = %d\n", args.A, args.B, reply.C)
return nil
}
func (t *Arith) Add(ctx context.Context, args *Args, reply *Reply) error {
reply.C = args.A + args.B
fmt.Printf("call: %d + %d = %d\n", args.A, args.B, reply.C)
return nil
}
func (t *Arith) Say(ctx context.Context, args *string, reply *string) error {
*reply = "hello " + *args
return nil
}
func (t *Arith1) Mul(ctx context.Context, args *Args, reply *Reply) error {
reply.C = args.A * args.B * 10
fmt.Printf("call: %d * %d = %d\n", args.A, args.B, reply.C)
return nil
}
func (t *Arith2) Mul(ctx context.Context, args *Args, reply *Reply) error {
reply.C = args.A * args.B * 50
fmt.Printf("call: %d * %d = %d\n", args.A, args.B, reply.C)
return nil
}
type Greeter struct{}
func (s *Greeter) Say(ctx context.Context, name *string, reply *string) error {
*reply = fmt.Sprintf("hello %s!", *name)
return nil
}
server.go
package main
import (
"flag"
"log"
"time"
metrics "github.com/rcrowley/go-metrics"
example "github.com/rpcxio/rpcx-examples"
"github.com/smallnest/rpcx/server"
"github.com/smallnest/rpcx/serverplugin"
)
var (
addr = flag.String("addr", "localhost:8972", "server address")
zkAddr = flag.String("zkAddr", "localhost:2181", "zookeeper address")
basePath = flag.String("base", "/youpin/services", "prefix path")
)
func main() {
flag.Parse()
s := server.NewServer()
addRegistryPlugin(s)
s.RegisterName("Arith", new(example.Arith), "")
s.Serve("tcp", *addr)
}
func addRegistryPlugin(s *server.Server) {
r := &serverplugin.ZooKeeperRegisterPlugin{
ServiceAddress: "tcp@" + *addr,
ZooKeeperServers: []string{*zkAddr},
BasePath: *basePath,
Metrics: metrics.NewRegistry(),
UpdateInterval: time.Minute,
}
err := r.Start()
if err != nil {
log.Fatal(err)
}
s.Plugins.Add(r)
}
测试结果
直接使用http创建web服务访问后端的rpcx的TPS在7000+/sec,而使用rpcx-gateway创建的http服务访问后端的TPS只能达到1300+/sec。
另:把server.go的数量增加,有助于提升rpcx-geteway的性能,大约每增加一个server,就提升1倍的TPS.
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。