chore: benchmark script
This commit is contained in:
@@ -1,8 +1,32 @@
|
|||||||
# url-shortener
|
# url-shortener
|
||||||
> Lightning fast, lightweight and minimal self-hosted url shortener
|
> Lightning fast, lightweight and minimal self-hosted url shortener
|
||||||
|
|
||||||
|
## Benchmark
|
||||||
|
|
||||||
## Self-hosted
|
## Self-hosted
|
||||||
|
|
||||||
|
- Run via docker-compose
|
||||||
|
```bash
|
||||||
|
docker-compose up
|
||||||
|
|
||||||
|
docker-compose exec -it app migrate
|
||||||
|
docker-compose exec -it app cli --create-user=Admin
|
||||||
|
```
|
||||||
|
|
||||||
|
- Run via docker cli
|
||||||
|
```bash
|
||||||
|
docker run \
|
||||||
|
--name url-shortener \
|
||||||
|
-p 4000:4000 \
|
||||||
|
-e ENV="production" \
|
||||||
|
-e DATABASE_URL="sqlite3://./sqlite/data.db?journal_mode=wal&synchronous=normal&foreign_keys=true" \
|
||||||
|
-e APP_URL="http://localhost:4000" \
|
||||||
|
sjdonado/url-shortener
|
||||||
|
|
||||||
|
docker exec -it url-shortener migrate
|
||||||
|
docker exec -it url-shortener cli --create-user=Admin
|
||||||
|
```
|
||||||
|
|
||||||
- Dokku
|
- Dokku
|
||||||
```dockerfile
|
```dockerfile
|
||||||
FROM sjdonado/url-shortener
|
FROM sjdonado/url-shortener
|
||||||
@@ -26,20 +50,6 @@ dokku run url-shortener migrate
|
|||||||
dokku run url-shortener cli --create-user=Admin
|
dokku run url-shortener cli --create-user=Admin
|
||||||
```
|
```
|
||||||
|
|
||||||
- Run
|
|
||||||
```bash
|
|
||||||
docker run \
|
|
||||||
--name url-shortener \
|
|
||||||
-p 4000:4000 \
|
|
||||||
-e ENV="production" \
|
|
||||||
-e DATABASE_URL="sqlite3://./sqlite/data.db?journal_mode=wal&synchronous=normal&foreign_keys=true" \
|
|
||||||
-e APP_URL="http://localhost:4000" \
|
|
||||||
sjdonado/url-shortener
|
|
||||||
|
|
||||||
docker exec -it url-shortener migrate
|
|
||||||
docker exec -it url-shortener cli --create-user=Admin
|
|
||||||
```
|
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
**REST API**
|
**REST API**
|
||||||
|
|||||||
Executable
+117
@@ -0,0 +1,117 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
api_url="http://localhost:4001/api/links"
|
||||||
|
num_links=100
|
||||||
|
num_requests=10
|
||||||
|
resource_usage_interval=1 # Interval in seconds for resource usage logging
|
||||||
|
|
||||||
|
function get_resource_usage {
|
||||||
|
while true; do
|
||||||
|
docker stats --no-stream --format "{{.MemUsage}} {{.CPUPerc}}" url-shortener >> resource_usage.txt
|
||||||
|
sleep $resource_usage_interval
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
function calculate_average_usage {
|
||||||
|
total_mem=0
|
||||||
|
count=0
|
||||||
|
|
||||||
|
while read -r line; do
|
||||||
|
mem=$(echo $line | awk '{print $1}')
|
||||||
|
|
||||||
|
# Convert memory to MiB if necessary
|
||||||
|
if [[ $mem == *MiB ]]; then
|
||||||
|
mem=$(echo $mem | sed 's/MiB//')
|
||||||
|
elif [[ $mem == *GiB ]]; then
|
||||||
|
mem=$(echo $mem | sed 's/GiB//')
|
||||||
|
mem=$(echo "$mem * 1024" | bc)
|
||||||
|
fi
|
||||||
|
|
||||||
|
total_mem=$(echo "$total_mem + $mem" | bc)
|
||||||
|
((count++))
|
||||||
|
done < resource_usage.txt
|
||||||
|
|
||||||
|
avg_mem=$(echo "scale=2; $total_mem / $count" | bc)
|
||||||
|
rm resource_usage.txt
|
||||||
|
|
||||||
|
echo "Average Memory Usage: $avg_mem MiB"
|
||||||
|
}
|
||||||
|
|
||||||
|
function measure {
|
||||||
|
total_time=0
|
||||||
|
declare -a refer_links
|
||||||
|
|
||||||
|
# Start resource usage logging in the background
|
||||||
|
nohup bash -c "$(declare -f get_resource_usage); get_resource_usage" &> /dev/null &
|
||||||
|
resource_usage_pid=$!
|
||||||
|
disown
|
||||||
|
|
||||||
|
echo "Creating $num_links short links..."
|
||||||
|
for ((i=1; i<=num_links; i++)); do
|
||||||
|
response=$(curl --silent --request POST \
|
||||||
|
--url $api_url \
|
||||||
|
--header "X-Api-Key: $api_key" \
|
||||||
|
--header "Content-Type: application/json" \
|
||||||
|
--data "{ \"url\": \"https://kagi.com\" }")
|
||||||
|
# echo "API Response for link $i: $response"
|
||||||
|
|
||||||
|
refer=$(echo $response | awk -F'"' '/"refer":/{print $(NF-1)}')
|
||||||
|
if [[ -n $refer ]]; then
|
||||||
|
refer_links+=("$refer")
|
||||||
|
else
|
||||||
|
echo "Failed to create short link $i"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
echo "Accessing each link $num_requests times concurrently..."
|
||||||
|
> times.txt # Ensure times.txt is created and empty
|
||||||
|
|
||||||
|
for refer in "${refer_links[@]}"; do
|
||||||
|
for ((i=1; i<=num_requests; i++)); do
|
||||||
|
(
|
||||||
|
start_time=$(date +%s%6N)
|
||||||
|
curl -s "$refer" >> /dev/null
|
||||||
|
end_time=$(date +%s%6N)
|
||||||
|
elapsed_time=$(echo "$end_time - $start_time" | bc)
|
||||||
|
echo $elapsed_time >> times.txt
|
||||||
|
) &
|
||||||
|
done
|
||||||
|
done
|
||||||
|
|
||||||
|
wait
|
||||||
|
|
||||||
|
# Stop resource usage logging
|
||||||
|
if kill -0 $resource_usage_pid 2>/dev/null; then
|
||||||
|
kill $resource_usage_pid
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Read all elapsed times and calculate total
|
||||||
|
while read -r time; do
|
||||||
|
total_time=$(echo "$total_time + $time" | bc)
|
||||||
|
done < times.txt
|
||||||
|
rm times.txt
|
||||||
|
|
||||||
|
echo "****Results****"
|
||||||
|
|
||||||
|
calculate_average_usage
|
||||||
|
echo "Average Response Time: $(echo "scale=2; $total_time / ($num_links * $num_requests)" | bc) µs"
|
||||||
|
}
|
||||||
|
|
||||||
|
echo "Setup..."
|
||||||
|
|
||||||
|
docker-compose up -d
|
||||||
|
# Ensure migrations are done
|
||||||
|
docker-compose exec -T app migrate
|
||||||
|
|
||||||
|
# Create a new user and capture the API key
|
||||||
|
output=$(docker-compose exec -T app cli --create-user=Admin)
|
||||||
|
api_key=$(echo "$output" | awk -F' ' '/X-Api-Key:/{print $NF}')
|
||||||
|
echo "Captured API Key: $api_key"
|
||||||
|
|
||||||
|
echo "Waiting for database to be ready..."
|
||||||
|
sleep 5
|
||||||
|
|
||||||
|
measure
|
||||||
|
|
||||||
|
# Clean up
|
||||||
|
docker-compose down
|
||||||
+1
-1
@@ -6,4 +6,4 @@ services:
|
|||||||
DATABASE_URL: sqlite3://./sqlite/data.db?journal_mode=wal&synchronous=normal&foreign_keys=true
|
DATABASE_URL: sqlite3://./sqlite/data.db?journal_mode=wal&synchronous=normal&foreign_keys=true
|
||||||
APP_URL: http://0.0.0.0:4001
|
APP_URL: http://0.0.0.0:4001
|
||||||
ports:
|
ports:
|
||||||
- 4000:4000
|
- 4001:4000
|
||||||
|
|||||||
Reference in New Issue
Block a user