Merge pull request #364 from getAlby/fix/rate-limit-fixup

fix: improve rate limit handling
This commit is contained in:
kiwiidb
2023-05-23 13:44:34 +02:00
committed by GitHub
2 changed files with 24 additions and 9 deletions

View File

@@ -41,8 +41,8 @@ vim .env # edit your config
+ `HOST`: (default: "localhost:3000") Host the app should listen on
+ `PORT`: (default: 3000) Port the app should listen on
+ `DEFAULT_RATE_LIMIT`: (default: 10) Requests per second rate limit
+ `STRICT_RATE_LIMIT`: (default: 10) Requests per burst rate limit (e.g. 1 request each 10 seconds)
+ `BURST_RATE_LIMIT`: (default: 1) Rate limit burst
+ `STRICT_RATE_LIMIT`: (default: 10) Requests per second rate limit for resource-intensive APIs (e.g. sending a payment)
+ `BURST_RATE_LIMIT`: (default: 1) Specifies the maximum number of requests that can pass at the same moment
+ `ENABLE_PROMETHEUS`: (default: false) Enable Prometheus metrics to be exposed
+ `PROMETHEUS_PORT`: (default: 9092) Prometheus port (path: `/metrics`)
+ `WEBHOOK_URL`: Optional. Callback URL for incoming and outgoing payment events, see below.

29
main.go
View File

@@ -8,6 +8,7 @@ import (
"net/http"
"os"
"os/signal"
"strconv"
"sync"
"time"
@@ -125,7 +126,8 @@ func main() {
}
e.Use(middleware.Recover())
e.Use(middleware.BodyLimit("250K"))
e.Use(middleware.RateLimiter(middleware.NewRateLimiterMemoryStore(20)))
// set the default rate limit defining the overal max requests/second
e.Use(middleware.RateLimiter(middleware.NewRateLimiterMemoryStore(rate.Limit(c.DefaultRateLimit))))
e.Logger = logger
e.Use(middleware.RequestID())
@@ -184,8 +186,9 @@ func main() {
InvoicePubSub: service.NewPubsub(),
}
// strict rate limit for requests for sending payments
strictRateLimitMiddleware := createRateLimitMiddleware(c.StrictRateLimit, c.BurstRateLimit)
secured := e.Group("", tokens.Middleware(c.JWTSecret), middleware.RateLimiter(middleware.NewRateLimiterMemoryStore(rate.Limit(c.DefaultRateLimit))))
secured := e.Group("", tokens.Middleware(c.JWTSecret))
securedWithStrictRateLimit := e.Group("", tokens.Middleware(c.JWTSecret), strictRateLimitMiddleware)
RegisterLegacyEndpoints(svc, e, secured, securedWithStrictRateLimit, strictRateLimitMiddleware, tokens.AdminTokenMiddleware(c.AdminToken))
@@ -304,12 +307,24 @@ func main() {
svc.Logger.Info("LNDhub exiting gracefully. Goodbye.")
}
func createRateLimitMiddleware(seconds int, burst int) echo.MiddlewareFunc {
config := middleware.RateLimiterMemoryStoreConfig{
Rate: rate.Every(time.Duration(seconds) * time.Second),
Burst: burst,
func createRateLimitMiddleware(requestsPerSecond int, burst int) echo.MiddlewareFunc {
config := middleware.RateLimiterConfig{
Store: middleware.NewRateLimiterMemoryStoreWithConfig(
middleware.RateLimiterMemoryStoreConfig{Rate: rate.Limit(requestsPerSecond), Burst: burst},
),
IdentifierExtractor: func(ctx echo.Context) (string, error) {
userId := ctx.Get("UserID")
id := ctx.RealIP()
if userId != nil {
userIdAsInt64 := ctx.Get("UserID").(int64)
id = strconv.FormatInt(userIdAsInt64, 10)
}
return id, nil
},
}
return middleware.RateLimiter(middleware.NewRateLimiterMemoryStoreWithConfig(config))
return middleware.RateLimiterWithConfig(config)
}
func createCacheClient() *cache.Client {