Created
October 6, 2022 00:53
-
-
Save davidoram/5aedd432fb352de56174cae1421769fd to your computer and use it in GitHub Desktop.
Load test HTTP server with 'golang.org/x/time/rate' rate limiter
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
/* | |
Run via `go run main.go` | |
Test via `curl -i localhost:4000` | |
Load test via https://github.com/rakyll/hey | |
hey -n 500000 -c 50 -q 166 -m GET http://localhost:4000 | |
Summary: | |
Total: 61.0789 secs | |
Slowest: 0.0740 secs | |
Fastest: 0.0000 secs | |
Average: 0.0010 secs | |
Requests/sec: 8186.1292 | |
Total data: 6000000 bytes | |
Size/request: 12 bytes | |
Response time histogram: | |
0.000 [1] | | |
0.007 [498465] |■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ | |
0.015 [1096] | | |
0.022 [213] | | |
0.030 [183] | | |
0.037 [39] | | |
0.044 [1] | | |
0.052 [0] | | |
0.059 [1] | | |
0.067 [0] | | |
0.074 [1] | | |
Latency distribution: | |
10% in 0.0003 secs | |
25% in 0.0005 secs | |
50% in 0.0008 secs | |
75% in 0.0013 secs | |
90% in 0.0019 secs | |
95% in 0.0025 secs | |
99% in 0.0042 secs | |
Details (average, fastest, slowest): | |
DNS+dialup: 0.0000 secs, 0.0000 secs, 0.0740 secs | |
DNS-lookup: 0.0000 secs, 0.0000 secs, 0.0105 secs | |
req write: 0.0000 secs, 0.0000 secs, 0.0329 secs | |
resp wait: 0.0009 secs, 0.0000 secs, 0.0349 secs | |
resp read: 0.0000 secs, 0.0000 secs, 0.0315 secs | |
Status code distribution: | |
[200] 500000 responses | |
*/ | |
import ( | |
"fmt" | |
"net/http" | |
"golang.org/x/time/rate" | |
"log" | |
) | |
// Max 8400 requests per second with a burst of 8500 | |
var limiter = rate.NewLimiter(8400, 8500) | |
func main () { | |
mux := http.NewServeMux() | |
mux.HandleFunc("/", helloHandler) | |
log.Print("Listening on :4000...") | |
http.ListenAndServe(":4000", limitMiddleware(mux)) | |
} | |
func limitMiddleware(next http.Handler) http.Handler { | |
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { | |
if limiter.Allow() == false { | |
http.Error(w, http.StatusText(429), http.StatusTooManyRequests) | |
return | |
} | |
next.ServeHTTP(w, r) | |
}) | |
} | |
func helloHandler(w http.ResponseWriter, r *http.Request) { | |
fmt.Fprintf(w, "Hello World!") | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment