1
18
19 package main
20
21 import (
22 "flag"
23 "fmt"
24 "net"
25 "runtime"
26 "strconv"
27 "strings"
28 "sync"
29 "time"
30
31 "google.golang.org/grpc"
32 "google.golang.org/grpc/benchmark"
33 "google.golang.org/grpc/codes"
34 "google.golang.org/grpc/credentials"
35 "google.golang.org/grpc/internal/syscall"
36 testpb "google.golang.org/grpc/interop/grpc_testing"
37 "google.golang.org/grpc/status"
38 "google.golang.org/grpc/testdata"
39 )
40
41 var (
42 certFile = flag.String("tls_cert_file", "", "The TLS cert file")
43 keyFile = flag.String("tls_key_file", "", "The TLS key file")
44 )
45
46 type benchmarkServer struct {
47 port int
48 cores int
49 closeFunc func()
50 mu sync.RWMutex
51 lastResetTime time.Time
52 rusageLastReset *syscall.Rusage
53 }
54
55 func printServerConfig(config *testpb.ServerConfig) {
56
57
58
59
60
61 logger.Infof(" * server type: %v (ignored, always starts sync server)", config.ServerType)
62 logger.Infof(" * async server threads: %v (ignored)", config.AsyncServerThreads)
63
64 logger.Infof(" * core list: %v (ignored)", config.CoreList)
65
66 logger.Infof(" - security params: %v", config.SecurityParams)
67 logger.Infof(" - core limit: %v", config.CoreLimit)
68 logger.Infof(" - port: %v", config.Port)
69 logger.Infof(" - payload config: %v", config.PayloadConfig)
70 }
71
72 func startBenchmarkServer(config *testpb.ServerConfig, serverPort int) (*benchmarkServer, error) {
73 printServerConfig(config)
74
75
76
77 numOfCores := runtime.NumCPU()
78 if config.CoreLimit > 0 {
79 numOfCores = int(config.CoreLimit)
80 }
81 runtime.GOMAXPROCS(numOfCores)
82
83 opts := []grpc.ServerOption{
84 grpc.WriteBufferSize(128 * 1024),
85 grpc.ReadBufferSize(128 * 1024),
86 }
87
88
89 switch config.ServerType {
90 case testpb.ServerType_SYNC_SERVER:
91 case testpb.ServerType_ASYNC_SERVER:
92 case testpb.ServerType_ASYNC_GENERIC_SERVER:
93 default:
94 return nil, status.Errorf(codes.InvalidArgument, "unknown server type: %v", config.ServerType)
95 }
96
97
98 if config.SecurityParams != nil {
99 if *certFile == "" {
100 *certFile = testdata.Path("server1.pem")
101 }
102 if *keyFile == "" {
103 *keyFile = testdata.Path("server1.key")
104 }
105 creds, err := credentials.NewServerTLSFromFile(*certFile, *keyFile)
106 if err != nil {
107 logger.Fatalf("failed to generate credentials: %v", err)
108 }
109 opts = append(opts, grpc.Creds(creds))
110 }
111
112
113 port := int(config.Port)
114 if port == 0 {
115 port = serverPort
116 }
117 lis, err := net.Listen("tcp", fmt.Sprintf(":%d", port))
118 if err != nil {
119 logger.Fatalf("Failed to listen: %v", err)
120 }
121 addr := lis.Addr().String()
122
123
124 var closeFunc func()
125 if config.PayloadConfig != nil {
126 switch payload := config.PayloadConfig.Payload.(type) {
127 case *testpb.PayloadConfig_BytebufParams:
128 opts = append(opts, grpc.CustomCodec(byteBufCodec{}))
129 closeFunc = benchmark.StartServer(benchmark.ServerInfo{
130 Type: "bytebuf",
131 Metadata: payload.BytebufParams.RespSize,
132 Listener: lis,
133 }, opts...)
134 case *testpb.PayloadConfig_SimpleParams:
135 closeFunc = benchmark.StartServer(benchmark.ServerInfo{
136 Type: "protobuf",
137 Listener: lis,
138 }, opts...)
139 case *testpb.PayloadConfig_ComplexParams:
140 return nil, status.Errorf(codes.Unimplemented, "unsupported payload config: %v", config.PayloadConfig)
141 default:
142 return nil, status.Errorf(codes.InvalidArgument, "unknown payload config: %v", config.PayloadConfig)
143 }
144 } else {
145
146 closeFunc = benchmark.StartServer(benchmark.ServerInfo{
147 Type: "protobuf",
148 Listener: lis,
149 }, opts...)
150 }
151
152 logger.Infof("benchmark server listening at %v", addr)
153 addrSplitted := strings.Split(addr, ":")
154 p, err := strconv.Atoi(addrSplitted[len(addrSplitted)-1])
155 if err != nil {
156 logger.Fatalf("failed to get port number from server address: %v", err)
157 }
158
159 return &benchmarkServer{
160 port: p,
161 cores: numOfCores,
162 closeFunc: closeFunc,
163 lastResetTime: time.Now(),
164 rusageLastReset: syscall.GetRusage(),
165 }, nil
166 }
167
168
169
170 func (bs *benchmarkServer) getStats(reset bool) *testpb.ServerStats {
171 bs.mu.RLock()
172 defer bs.mu.RUnlock()
173 wallTimeElapsed := time.Since(bs.lastResetTime).Seconds()
174 rusageLatest := syscall.GetRusage()
175 uTimeElapsed, sTimeElapsed := syscall.CPUTimeDiff(bs.rusageLastReset, rusageLatest)
176
177 if reset {
178 bs.lastResetTime = time.Now()
179 bs.rusageLastReset = rusageLatest
180 }
181 return &testpb.ServerStats{
182 TimeElapsed: wallTimeElapsed,
183 TimeUser: uTimeElapsed,
184 TimeSystem: sTimeElapsed,
185 }
186 }
187
View as plain text