Skip to content

Commit

Permalink
server: Accept a latency distribution on the commandline (#45)
Browse files Browse the repository at this point in the history
* make `distribution` and `percentiles` top-level modules

* Support a per-instance latency distribution configured on the server.

* update README
  • Loading branch information
olix0r authored Jun 9, 2018
1 parent 8483c26 commit a115f89
Show file tree
Hide file tree
Showing 8 changed files with 57 additions and 41 deletions.
43 changes: 21 additions & 22 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,16 @@ Strest client and server implementations for gRPC.

To run the client and server locally, first start the server.

```bash
$ go run main.go server
```
$ strest-grpc server
starting gRPC server on :11111
```

Next run the client. By default, the client will send as many request as it can
on a single connection for 10 seconds, and exit with a performance report.

```bash
$ go run main.go client --address localhost:11111
```
$ strest-grpc client --address localhost:11111
2017-05-12T16:17:40-07:00 98.2KB 354/0 10s L: 0 [ 89 97 ] 102 J: 0 0
{
"good": 354,
Expand All @@ -40,12 +40,10 @@ $ go run main.go client --address localhost:11111

### Usage

Use the `--help` flag for usage information.

#### Commands

```bash
$ go run main.go --help
```
$ strest-grpc --help
A load tester for stress testing grpc intermediaries.
Find more information at https://github.com/buoyantio/strest-grpc.
Expand All @@ -68,8 +66,8 @@ Use "strest-grpc [command] --help" for more information about a command.

#### Client

```bash
$ go run main.go client --help
```
$ strest-grpc client --help
run the strest-grpc client
Usage:
Expand Down Expand Up @@ -102,29 +100,30 @@ Global Flags:

#### Server

```bash
$ go run main.go server --help
```
$ strest-grpc server --help
run the strest-grpc server
Usage:
strest-grpc server [flags]
Flags:
--address string address to serve on (default ":11111")
-h, --help help for server
--metricAddr string address to serve metrics on
--tlsCertFile string the path to the trust certificate
--tlsPrivKeyFile string the path to the server's private key
-u, --unix use Unix Domain Sockets instead of TCP
--address string address to serve on (default ":11111")
-h, --help help for server
--latencyPercentiles string response latency percentile distribution added to client latencies. (e.g. 50=10,100=100) (default "100=0")
--metricAddr string address to serve metrics on
--tlsCertFile string the path to the trust certificate
--tlsPrivKeyFile string the path to the server's private key
-u, --unix use Unix Domain Sockets instead of TCP
Global Flags:
-l, --logLevel string log level, must be one of: panic, fatal, error, warn, info, debug (default "info")
```

#### Max-RPS

```bash
$ go run main.go max-rps --help
```
$ strest-grpc max-rps --help
compute max RPS
Usage:
Expand All @@ -144,15 +143,15 @@ Global Flags:

To build the strest-grpc binaries and archives, run:

```bash
```
./bin/release.sh [VERSION TAG]
```

That will create `strest-grpc` binaries and archives in `./release`.

To build a docker image, run:

```bash
```
$ docker build -t buoyantio/strest-grpc:latest .
```

Expand Down
4 changes: 2 additions & 2 deletions client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ import (
"syscall"
"time"

"github.com/buoyantio/strest-grpc/client/distribution"
"github.com/buoyantio/strest-grpc/client/percentiles"
"github.com/buoyantio/strest-grpc/distribution"
"github.com/buoyantio/strest-grpc/percentiles"
pb "github.com/buoyantio/strest-grpc/protos"
"github.com/codahale/hdrhistogram"
"github.com/prometheus/client_golang/prometheus"
Expand Down
1 change: 1 addition & 0 deletions cmd/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ func init() {
flags := serverCmd.Flags()
flags.StringVar(&serverCfg.Address, "address", ":11111", "address to serve on")
flags.StringVar(&serverCfg.MetricAddr, "metricAddr", "", "address to serve metrics on")
flags.StringVar(&serverCfg.LatencyPercentiles, "latencyPercentiles", "100=0", "response latency percentile distribution added to client latencies. (e.g. 50=10,100=100)")
flags.BoolVarP(&serverCfg.UseUnixAddr, "unix", "u", false, "use Unix Domain Sockets instead of TCP")
flags.StringVar(&serverCfg.TLSCertFile, "tlsCertFile", "", "the path to the trust certificate")
flags.StringVar(&serverCfg.TLSPrivKeyFile, "tlsPrivKeyFile", "", "the path to the server's private key")
Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package distribution_test
import (
"testing"

"github.com/buoyantio/strest-grpc/client/distribution"
"github.com/buoyantio/strest-grpc/distribution"
. "gopkg.in/check.v1"
)

Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
package percentiles_test

import (
"github.com/buoyantio/strest-grpc/client/percentiles"
. "gopkg.in/check.v1"
"testing"

"github.com/buoyantio/strest-grpc/percentiles"
. "gopkg.in/check.v1"
)

// Hook up gocheck into the "go test" runner.
Expand Down
43 changes: 29 additions & 14 deletions server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ import (
"net/http"
"time"

"github.com/buoyantio/strest-grpc/client/distribution"
"github.com/buoyantio/strest-grpc/distribution"
"github.com/buoyantio/strest-grpc/percentiles"
pb "github.com/buoyantio/strest-grpc/protos"
"github.com/buoyantio/strest-grpc/server/random_string"
"github.com/prometheus/client_golang/prometheus"
Expand All @@ -22,7 +23,9 @@ import (
"google.golang.org/grpc/status"
)

type server struct{}
type server struct {
latencyDistribution distribution.Distribution
}

var (
promRequests = prometheus.NewCounter(prometheus.CounterOpts{
Expand Down Expand Up @@ -57,8 +60,10 @@ func registerMetrics() {
func (s *server) Get(ctx context.Context, in *pb.ResponseSpec) (*pb.ResponseReply, error) {
var src = rand.NewSource(time.Now().UnixNano())
r := rand.New(src)
if in.Latency > 0 {
time.Sleep(time.Duration(in.Latency) * time.Millisecond)
latency := s.latencyDistribution.Get(r.Int31() % 1000)
latency = latency + in.Latency
if latency > 0 {
time.Sleep(time.Duration(latency) * time.Millisecond)
}
promRequests.Inc()
promResponses.Inc()
Expand Down Expand Up @@ -146,13 +151,14 @@ func (s *server) StreamingGet(stream pb.Responder_StreamingGetServer) error {
}
}

// Configuration for a server
// Config holds the commandline configuration for the server.
type Config struct {
Address string
UseUnixAddr bool
MetricAddr string
TLSCertFile string
TLSPrivKeyFile string
Address string
UseUnixAddr bool
MetricAddr string
LatencyPercentiles string
TLSCertFile string
TLSPrivKeyFile string
}

func (cfg *Config) serveMetrics() {
Expand All @@ -168,9 +174,9 @@ func (cfg *Config) serveMetrics() {
func (cfg *Config) af() string {
if cfg.UseUnixAddr {
return "unix"
} else {
return "tcp"
}

return "tcp"
}

func (cfg *Config) tlsCreds() (credentials.TransportCredentials, error) {
Expand All @@ -180,10 +186,19 @@ func (cfg *Config) tlsCreds() (credentials.TransportCredentials, error) {
return nil, nil
}

// run the server
// Run processes commandline configuration and runs the server.
func (cfg Config) Run() {
rand.Seed(time.Now().UnixNano())

latencyPercentiles, err := percentiles.ParsePercentiles(cfg.LatencyPercentiles)
if err != nil {
log.Fatalf("latencyPercentiles was not valid: %v", err)
}
latencyDistribution, err := distribution.FromMap(latencyPercentiles)
if err != nil {
log.Fatalf("unable to create latency distribution: %v", err)
}

cfg.serveMetrics()

fmt.Println("starting gRPC server on", cfg.Address)
Expand All @@ -205,6 +220,6 @@ func (cfg Config) Run() {

s := grpc.NewServer(opts...)

pb.RegisterResponderServer(s, new(server))
pb.RegisterResponderServer(s, &server{latencyDistribution})
s.Serve(lis)
}

0 comments on commit a115f89

Please sign in to comment.