Nyx con Ejemplos

Rate Limiting del Proxy

Rate limiting por IP usando una ventana deslizante. Cuenta requests en ventanas de 1 segundo; devuelve HTTP 429 al superarse el límite. Para rate limiting distribuido entre múltiples instancias del proxy, usar nyx-kv INCR + EXPIRE.

Código

// nyx-proxy rate limiting — per-IP sliding window
// Rate limiting nyx-proxy — ventana deslizante por IP

var ip_counts: Map = Map.new()
var window_start: Map = Map.new()

fn now_seconds() -> int {
    return time()
}

// Check if an IP has exceeded the rate limit
// Returns true if allowed, false if rate-limited
fn rate_check(ip: String, max_per_sec: int) -> bool {
    let now: int = now_seconds()

    // Initialize window if new IP
    if not ip_counts.contains(ip) {
        ip_counts.insert(ip, "1")
        window_start.insert(ip, int_to_string(now))
        return true
    }

    // Reset window if more than 1 second elapsed
    let start_s: String = window_start.get(ip)
    let start: int = string_to_int(start_s)
    if now - start >= 1 {
        ip_counts.insert(ip, "1")
        window_start.insert(ip, int_to_string(now))
        return true
    }

    // Increment count
    let count_s: String = ip_counts.get(ip)
    let count: int = string_to_int(count_s) + 1
    ip_counts.insert(ip, int_to_string(count))

    return count <= max_per_sec
}

fn main() -> int {
    let max_rps: int = 5  // allow 5 requests per second per IP
    let ip: String = "192.168.1.100"

    // Simulate 8 rapid requests from the same IP
    var i: int = 0
    while i < 8 {
        let ok: bool = rate_check(ip, max_rps)
        if ok {
            print("request " + int_to_string(i + 1) + ": ALLOWED")
        } else {
            print("request " + int_to_string(i + 1) + ": 429 Too Many Requests")
        }
        i = i + 1
    }
    return 0
}

Salida

request 1: ALLOWED
request 2: ALLOWED
request 3: ALLOWED
request 4: ALLOWED
request 5: ALLOWED
request 6: 429 Too Many Requests
request 7: 429 Too Many Requests
request 8: 429 Too Many Requests

Explicación

El rate limiting es la primera línea de defensa tanto contra el abuso como contra clientes descontrolados. El contador de ventana fija que se ve aquí es la implementación más simple: para cada IP, recordar cuándo empezó su ventana y cuántos requests han llegado; reiniciar el contador en cada segundo nuevo. No es perfecto — un cliente que golpea el límite exacto puede llegar a ráfagas de 2x el límite — pero es barato y suficientemente bueno para la mayoría de los proxies. En un despliegue con múltiples instancias los contadores se desincronizan porque cada instancia solo ve su propio tráfico; la solución es mantener los conteos en nyx-kv con INCR + EXPIRE para que todas las instancias compartan una única vista. Para una equidad más estricta, el token bucket o una ventana deslizante real son los siguientes pasos.

← Anterior Siguiente →

Source: examples/by-example/88-proxy-ratelimit.nx