mirror of
https://github.com/yusing/godoxy.git
synced 2026-04-24 09:18:31 +02:00
feat(benchmark): enhance dev.compose.yml with benchmark services and scripts
- Added benchmark services (whoami, godoxy, traefik, caddy, nginx) to dev.compose.yml. - Introduced a new benchmark.sh script for load testing using wrk and h2load. - Updated Makefile to include a benchmark target for easy execution of the new script.
This commit is contained in:
7
Makefile
7
Makefile
@@ -123,6 +123,11 @@ dev:
|
|||||||
dev-build: build
|
dev-build: build
|
||||||
docker compose -f dev.compose.yml up -t 0 -d app --force-recreate
|
docker compose -f dev.compose.yml up -t 0 -d app --force-recreate
|
||||||
|
|
||||||
|
benchmark:
|
||||||
|
@docker compose -f dev.compose.yml up -d --force-recreate whoami godoxy traefik caddy nginx
|
||||||
|
sleep 1
|
||||||
|
@./scripts/benchmark.sh
|
||||||
|
|
||||||
dev-run: build
|
dev-run: build
|
||||||
cd dev-data && ${BIN_PATH}
|
cd dev-data && ${BIN_PATH}
|
||||||
|
|
||||||
@@ -142,7 +147,7 @@ ci-test:
|
|||||||
act -n --artifact-server-path /tmp/artifacts -s GITHUB_TOKEN="$$(gh auth token)"
|
act -n --artifact-server-path /tmp/artifacts -s GITHUB_TOKEN="$$(gh auth token)"
|
||||||
|
|
||||||
cloc:
|
cloc:
|
||||||
scc -w -i go --not-match '_test.go$'
|
scc -w -i go --not-match '_test.go$$'
|
||||||
|
|
||||||
push-github:
|
push-github:
|
||||||
git push origin $(shell git rev-parse --abbrev-ref HEAD)
|
git push origin $(shell git rev-parse --abbrev-ref HEAD)
|
||||||
|
|||||||
146
dev.compose.yml
146
dev.compose.yml
@@ -1,3 +1,8 @@
|
|||||||
|
x-benchmark: &benchmark
|
||||||
|
restart: no
|
||||||
|
labels:
|
||||||
|
proxy.exclude: true
|
||||||
|
proxy.#1.healthcheck.disable: true
|
||||||
services:
|
services:
|
||||||
app:
|
app:
|
||||||
image: godoxy-dev
|
image: godoxy-dev
|
||||||
@@ -90,7 +95,148 @@ services:
|
|||||||
labels:
|
labels:
|
||||||
proxy.#1.scheme: h2c
|
proxy.#1.scheme: h2c
|
||||||
proxy.#1.port: 80
|
proxy.#1.port: 80
|
||||||
|
whoami:
|
||||||
|
<<: *benchmark
|
||||||
|
image: traefik/whoami:latest
|
||||||
|
container_name: whoami
|
||||||
|
godoxy:
|
||||||
|
<<: *benchmark
|
||||||
|
build: .
|
||||||
|
container_name: godoxy-benchmark
|
||||||
|
environment:
|
||||||
|
DOCKER_HOST: unix:///var/run/docker.sock
|
||||||
|
ports:
|
||||||
|
- 8080:80
|
||||||
|
volumes:
|
||||||
|
- /var/run/docker.sock:/var/run/docker.sock:ro
|
||||||
|
configs:
|
||||||
|
- source: godoxy_config
|
||||||
|
target: /app/config/config.yml
|
||||||
|
- source: godoxy_provider
|
||||||
|
target: /app/config/providers.yml
|
||||||
|
traefik:
|
||||||
|
<<: *benchmark
|
||||||
|
image: traefik:latest
|
||||||
|
container_name: traefik
|
||||||
|
command:
|
||||||
|
- --api.insecure=true
|
||||||
|
- --entrypoints.web.address=:8081
|
||||||
|
- --providers.file.directory=/etc/traefik/dynamic
|
||||||
|
- --providers.file.watch=true
|
||||||
|
- --log.level=ERROR
|
||||||
|
ports:
|
||||||
|
- 8081:8081
|
||||||
|
configs:
|
||||||
|
- source: traefik_config
|
||||||
|
target: /etc/traefik/dynamic/routes.yml
|
||||||
|
caddy:
|
||||||
|
<<: *benchmark
|
||||||
|
image: caddy:latest
|
||||||
|
container_name: caddy
|
||||||
|
ports:
|
||||||
|
- 8082:80
|
||||||
|
configs:
|
||||||
|
- source: caddy_config
|
||||||
|
target: /etc/caddy/Caddyfile
|
||||||
|
tmpfs:
|
||||||
|
- /data
|
||||||
|
- /config
|
||||||
|
nginx:
|
||||||
|
<<: *benchmark
|
||||||
|
image: nginx:latest
|
||||||
|
container_name: nginx
|
||||||
|
command: nginx -g 'daemon off;' -c /etc/nginx/nginx.conf
|
||||||
|
ports:
|
||||||
|
- 8083:80
|
||||||
|
configs:
|
||||||
|
- source: nginx_config
|
||||||
|
target: /etc/nginx/nginx.conf
|
||||||
|
|
||||||
configs:
|
configs:
|
||||||
|
godoxy_config:
|
||||||
|
content: |
|
||||||
|
providers:
|
||||||
|
include:
|
||||||
|
- providers.yml
|
||||||
|
godoxy_provider:
|
||||||
|
content: |
|
||||||
|
whoami:
|
||||||
|
host: whoami
|
||||||
|
traefik_config:
|
||||||
|
content: |
|
||||||
|
http:
|
||||||
|
routers:
|
||||||
|
whoami:
|
||||||
|
rule: "Host(`whoami.domain.com`)"
|
||||||
|
entryPoints:
|
||||||
|
- web
|
||||||
|
service: whoami
|
||||||
|
services:
|
||||||
|
whoami:
|
||||||
|
loadBalancer:
|
||||||
|
servers:
|
||||||
|
- url: "http://whoami:80"
|
||||||
|
caddy_config:
|
||||||
|
content: |
|
||||||
|
{
|
||||||
|
admin off
|
||||||
|
auto_https off
|
||||||
|
default_bind 0.0.0.0
|
||||||
|
|
||||||
|
servers {
|
||||||
|
protocols h2c h1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
http://whoami.domain.com:80 {
|
||||||
|
reverse_proxy whoami:80
|
||||||
|
}
|
||||||
|
nginx_config:
|
||||||
|
content: |
|
||||||
|
worker_processes auto;
|
||||||
|
worker_rlimit_nofile 65535;
|
||||||
|
error_log /dev/null;
|
||||||
|
pid /var/run/nginx.pid;
|
||||||
|
|
||||||
|
events {
|
||||||
|
worker_connections 10240;
|
||||||
|
multi_accept on;
|
||||||
|
use epoll;
|
||||||
|
}
|
||||||
|
|
||||||
|
http {
|
||||||
|
include /etc/nginx/mime.types;
|
||||||
|
default_type application/octet-stream;
|
||||||
|
|
||||||
|
access_log off;
|
||||||
|
|
||||||
|
sendfile on;
|
||||||
|
tcp_nopush on;
|
||||||
|
tcp_nodelay on;
|
||||||
|
keepalive_timeout 65;
|
||||||
|
keepalive_requests 10000;
|
||||||
|
|
||||||
|
upstream backend {
|
||||||
|
server whoami:80;
|
||||||
|
keepalive 128;
|
||||||
|
}
|
||||||
|
|
||||||
|
server {
|
||||||
|
listen 80;
|
||||||
|
server_name whoami.domain.com;
|
||||||
|
http2 on;
|
||||||
|
|
||||||
|
location / {
|
||||||
|
proxy_pass http://backend;
|
||||||
|
proxy_http_version 1.1;
|
||||||
|
proxy_set_header Connection "";
|
||||||
|
proxy_set_header Host $$host;
|
||||||
|
proxy_set_header X-Real-IP $$remote_addr;
|
||||||
|
proxy_set_header X-Forwarded-For $$proxy_add_x_forwarded_for;
|
||||||
|
proxy_buffering off;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
parca:
|
parca:
|
||||||
content: |
|
content: |
|
||||||
object_storage:
|
object_storage:
|
||||||
|
|||||||
179
scripts/benchmark.sh
Normal file
179
scripts/benchmark.sh
Normal file
@@ -0,0 +1,179 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# Benchmark script to compare GoDoxy, Traefik, Caddy, and Nginx
|
||||||
|
# Uses wrk for HTTP load testing
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# Configuration
|
||||||
|
HOST="whoami.domain.com"
|
||||||
|
DURATION="10s"
|
||||||
|
THREADS=4
|
||||||
|
CONNECTIONS=100
|
||||||
|
|
||||||
|
# Color functions for output
|
||||||
|
red() { echo -e "\033[0;31m$*\033[0m"; }
|
||||||
|
green() { echo -e "\033[0;32m$*\033[0m"; }
|
||||||
|
yellow() { echo -e "\033[1;33m$*\033[0m"; }
|
||||||
|
blue() { echo -e "\033[0;34m$*\033[0m"; }
|
||||||
|
|
||||||
|
# Check if wrk is installed
|
||||||
|
if ! command -v wrk &> /dev/null; then
|
||||||
|
red "Error: wrk is not installed"
|
||||||
|
echo "Please install wrk:"
|
||||||
|
echo " Ubuntu/Debian: sudo apt-get install wrk"
|
||||||
|
echo " macOS: brew install wrk"
|
||||||
|
echo " Or build from source: https://github.com/wg/wrk"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! command -v h2load &> /dev/null; then
|
||||||
|
red "Error: h2load is not installed"
|
||||||
|
echo "Please install h2load (nghttp2-client):"
|
||||||
|
echo " Ubuntu/Debian: sudo apt-get install nghttp2-client"
|
||||||
|
echo " macOS: brew install nghttp2"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
OUTFILE="/tmp/reverse_proxy_benchmark_$(date +%Y%m%d_%H%M%S).log"
|
||||||
|
: > "$OUTFILE"
|
||||||
|
exec > >(tee -a "$OUTFILE") 2>&1
|
||||||
|
|
||||||
|
blue "========================================"
|
||||||
|
blue "Reverse Proxy Benchmark Comparison"
|
||||||
|
blue "========================================"
|
||||||
|
echo ""
|
||||||
|
echo "Target: $HOST"
|
||||||
|
echo "Duration: $DURATION"
|
||||||
|
echo "Threads: $THREADS"
|
||||||
|
echo "Connections: $CONNECTIONS"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# Define services to test
|
||||||
|
declare -A services=(
|
||||||
|
["GoDoxy"]="http://127.0.0.1:8080/bench"
|
||||||
|
["Traefik"]="http://127.0.0.1:8081/bench"
|
||||||
|
["Caddy"]="http://127.0.0.1:8082/bench"
|
||||||
|
["Nginx"]="http://127.0.0.1:8083/bench"
|
||||||
|
)
|
||||||
|
|
||||||
|
# Array to store connection errors
|
||||||
|
declare -a connection_errors=()
|
||||||
|
|
||||||
|
# Function to test connection before benchmarking
|
||||||
|
test_connection() {
|
||||||
|
local name=$1
|
||||||
|
local url=$2
|
||||||
|
|
||||||
|
yellow "Testing connection to $name..."
|
||||||
|
|
||||||
|
# Test HTTP/1.1
|
||||||
|
local res1=$(curl -sS -w "\n%{http_code}" --http1.1 -H "Host: $HOST" --max-time 5 "$url")
|
||||||
|
local body1=$(echo "$res1" | head -n -1)
|
||||||
|
local status1=$(echo "$res1" | tail -n 1)
|
||||||
|
|
||||||
|
# Test HTTP/2
|
||||||
|
local res2=$(curl -sS -w "\n%{http_code}" --http2-prior-knowledge -H "Host: $HOST" --max-time 5 "$url")
|
||||||
|
local body2=$(echo "$res2" | head -n -1)
|
||||||
|
local status2=$(echo "$res2" | tail -n 1)
|
||||||
|
|
||||||
|
local failed=false
|
||||||
|
if [ "$status1" != "200" ] || [ "$body1" != "1" ]; then
|
||||||
|
red "✗ $name failed HTTP/1.1 connection test (Status: $status1, Body: $body1)"
|
||||||
|
failed=true
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$status2" != "200" ] || [ "$body2" != "1" ]; then
|
||||||
|
red "✗ $name failed HTTP/2 connection test (Status: $status2, Body: $body2)"
|
||||||
|
failed=true
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$failed" = true ]; then
|
||||||
|
connection_errors+=("$name failed connection test (URL: $url)")
|
||||||
|
return 1
|
||||||
|
else
|
||||||
|
green "✓ $name is reachable (HTTP/1.1 & HTTP/2)"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
blue "========================================"
|
||||||
|
blue "Connection Tests"
|
||||||
|
blue "========================================"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# Run connection tests for all services
|
||||||
|
for name in "${!services[@]}"; do
|
||||||
|
test_connection "$name" "${services[$name]}"
|
||||||
|
done
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
blue "========================================"
|
||||||
|
|
||||||
|
# Exit if any connection test failed
|
||||||
|
if [ ${#connection_errors[@]} -gt 0 ]; then
|
||||||
|
echo ""
|
||||||
|
red "Connection test failed for the following services:"
|
||||||
|
for error in "${connection_errors[@]}"; do
|
||||||
|
red " - $error"
|
||||||
|
done
|
||||||
|
echo ""
|
||||||
|
red "Please ensure all services are running before benchmarking"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
green "All services are reachable. Starting benchmarks..."
|
||||||
|
echo ""
|
||||||
|
blue "========================================"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# Function to run benchmark
|
||||||
|
run_benchmark() {
|
||||||
|
local name=$1
|
||||||
|
local url=$2
|
||||||
|
local h2_duration="${DURATION%s}"
|
||||||
|
|
||||||
|
yellow "Testing $name..."
|
||||||
|
|
||||||
|
echo "========================================"
|
||||||
|
echo "$name"
|
||||||
|
echo "URL: $url"
|
||||||
|
echo "========================================"
|
||||||
|
echo ""
|
||||||
|
echo "[HTTP/1.1] wrk"
|
||||||
|
|
||||||
|
wrk -t"$THREADS" -c"$CONNECTIONS" -d"$DURATION" \
|
||||||
|
-H "Host: $HOST" \
|
||||||
|
"$url"
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "[HTTP/2] h2load"
|
||||||
|
|
||||||
|
h2load -t"$THREADS" -c"$CONNECTIONS" --duration="$h2_duration" \
|
||||||
|
-H "Host: $HOST" \
|
||||||
|
-H ":authority: $HOST" \
|
||||||
|
"$url" | grep -vE "^(starting benchmark...|spawning thread #|progress: |Warm-up )"
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
green "✓ $name benchmark completed"
|
||||||
|
blue "----------------------------------------"
|
||||||
|
echo ""
|
||||||
|
}
|
||||||
|
|
||||||
|
# Run benchmarks for each service
|
||||||
|
for name in "${!services[@]}"; do
|
||||||
|
run_benchmark "$name" "${services[$name]}"
|
||||||
|
done
|
||||||
|
|
||||||
|
blue "========================================"
|
||||||
|
blue "Benchmark Summary"
|
||||||
|
blue "========================================"
|
||||||
|
echo ""
|
||||||
|
echo "All benchmark output saved to: $OUTFILE"
|
||||||
|
echo ""
|
||||||
|
echo "Key metrics to compare:"
|
||||||
|
echo " - Requests/sec (throughput)"
|
||||||
|
echo " - Latency (mean, stdev)"
|
||||||
|
echo " - Transfer/sec"
|
||||||
|
echo ""
|
||||||
|
green "All benchmarks completed!"
|
||||||
Reference in New Issue
Block a user