There are 4 components in this load test, i.e.
-
client app (load generator)
-
client sidecar proxy
-
server sidecar proxy
-
server app
Traffic flows from 1 to 2 to 3 to 4.
Currently, the intention is to load test the client sidecar proxy (2) in various setups, e.g. an EC2 c5 instance versus an EC2 c6g instance.
For simplicity, the client app (1), the server sidecar proxy (3), and the server app (4) can all be installed in the same machine (loadgen/server), with the client sidecar proxy (2) running on a dedicated machine (client).
The load test requires the following ports to be open:
-
from the loadgen machine to the client machine's TCP port 60000 (i.e. the path from 1 to 2)
-
from the client machine to the server machine's TCP port 20000 (i.e. the path from 2 to 3)
The communication path from 2 to 3 has mTLS enabled.
This is a dummy golang service that returns the current time.
To build (requires go):
(local) $ cd app
(local) app $ go build cmd/time/main.go
Copy the binary to the server. To run:
(server) $ ./main -l 127.0.0.1:3000 -t Asia/Kuala_Lumpur
The dummy service will listen on 127.0.0.1:3000, and return the current time in the specific time zone.
To test the service via curl:
(server) $ curl -iv 127.0.0.1:3000/local
To test the service via grpcurl (need to copy pb/ to the server):
(server) $ grpcurl -import-path pb/ -proto time.proto -plaintext -vv 127.0.0.1:3000 Time/LocalTime
Retrieve the official envoy binary via docker, e.g.
(local) $ docker create --platform linux/amd64 --name envoy-copy envoyproxy/envoy:v1.25.2
(local) $ docker cp envoy-copy:/usr/local/bin/envoy /tmp/envoy-amd64-1.25.2
(local) $ docker rm envoy-copy
Copy the envoy binary, the server.json config file, and the certs/ directory to the server. Start the server sidecar proxy:
(server) $ ./envoy-amd64-1.25.2 -c server.json
This will start envoy with N number of worker threads based on the number of CPUs. To limit the number of worker threads, set the --concurrency
runtime flag, e.g.
(server) $ ./envoy-amd64-1.25.2 -c server.json --concurrency 1
Retrieve the official envoy binary via docker, e.g.
$ docker create --platform linux/arm64 --name envoy-copy envoyproxy/envoy:v1.25.2
$ docker cp envoy-copy:/usr/local/bin/envoy /tmp/envoy-arm64-1.25.2
$ docker rm envoy-copy
Copy the envoy binary, and the client.json config file, and the certs/ directory to the client. Modify client.json to replace all the 1.2.3.4 with the server IP address, then start the client sidecar proxy:
(client) $ ./envoy-arm64-1.25.2 -c client.json
This will start envoy with N number of worker threads based on the number of CPUs. To limit the number of worker threads, set the --concurrency
runtime flag, e.g.
(client) $ ./envoy-arm64-1.25.2 -c client.json --concurrency 1
Note that we put multiple endpoints with the same server IP address in client.json, so that the client sidecar proxy will open multiple connections to the server, and subsequently the connections can be spread across the worker threads on the server sidecar proxy, such that it doesn't become the bottleneck.
This is a load generator written in java, serving as the client app.
To build (requires a jdk):
(local) $ cd net-stress
(local) net-stress $ ./mvnw clean package -P http-get,grpc-get
Copy the resulting jar files from target/ and the log4j2.xml config file to the server. To run (requires a jre):
# http, 4000 rps, 1024 threads, warm up for 10 seconds, stress test for 30 seconds
(server) $ java -Dlog4j.configurationFile=log4j2.xml -jar http-get-jar-with-dependencies.jar -r 4000 -t 1024 -u http://5.6.7.8:60000/local -t 1024 -w 10 -s 30
# grpc, 4000 rps, 1024 threads, 4 connections, warm up for 10 seconds, stress test for 30 seconds
(server) $ java -Dlog4j.configurationFile=log4j2.xml -jar grpc-get-jar-with-dependencies.jar -r 4000 -t 1024 -e 5.6.7.8:60000 -c 4 -w 10 -s 30
Replace 5.6.7.8 with the client IP address.