前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >rpcx-gateway与直接创建http.HandleFunc的性能差异

rpcx-gateway与直接创建http.HandleFunc的性能差异

原创
作者头像
用户2825890
修改2020-12-07 11:46:54
8770
修改2020-12-07 11:46:54
举报
文章被收录于专栏:点滴随笔

rpcx-gateway是为rpcx提供网关服务的,官方是这样定义的:

Gateway 为 rpcx services 提供了 http 网关服务.

你可以使用你熟悉的编程语言, 比如Java、Python、C#、Node.js、Php、C\C++、Rust等等来调用 rpcx 服务。查看一些编程语言实现的例子

这意味着,你可以不用实现 rpcx的协议,而是使用熟悉的 http 访问方式调用 rpcx 服务, 设置用curlwget等命令行工具。

测试工具:Jmeter

测试环境:macbook pro 自建zookeeper+rpcx

测试目的:两者的性能差异

一、不使用rpcx-gateway提供http访问rpcx

代码语言:javascript
复制
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

代码语言:javascript
复制
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

代码语言:javascript
复制
// 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

代码语言:javascript
复制
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 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
命令行工具
腾讯云命令行工具 TCCLI 是管理腾讯云资源的统一工具。使用腾讯云命令行工具,您可以快速调用腾讯云 API 来管理您的腾讯云资源。此外,您还可以基于腾讯云的命令行工具来做自动化和脚本处理,以更多样的方式进行组合和重用。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档