nginx 1.18에 OpenResty 얹어서 인증/리밋 로직을 Lua로 처리하는 게이트웨이 만들어봄. 전에는 express + 미들웨어로 했는데, 단순 체크만 하는 거면 openresty 쪽이 훨씬 빠르고 리소스도 덜 먹는다.
토큰 검증(JWT 간단 버전) 예제.
location /api/ {
access_by_lua_block {
local jwt = require "resty.jwt"
local auth = ngx.var.http_authorization
if not auth then
ngx.exit(401)
end
local token = string.gsub(auth, "Bearer ", "")
local verified = jwt:verify("mysecret", token)
if not verified.verified then
ngx.status = 401
ngx.say(verified.reason)
ngx.exit(401)
end
ngx.req.set_header("X-User-Id", verified.payload.sub)
}
proxy_pass http://backend;
}
레이트 리밋은 resty.limit.req + shared dict.
http {
lua_shared_dict req_limit 10m;
}
location /api/ {
access_by_lua_block {
local limit = require("resty.limit.req").new("req_limit", 200, 100)
local delay, err = limit:incoming(ngx.var.binary_remote_addr, true)
if not delay then
if err == "rejected" then
ngx.exit(429)
end
end
}
}
체감 성능. wrk -t4 -c200 기준, 같은 토큰 검증 로직을 node 미들웨어로 할 때 대비 openresty가 약 3.2배 throughput. 근데 복잡한 로직 lua로 짜는 게 유지보수적으로 힘들어서 "라우팅 + 인증 + 레이트리밋" 수준에서만 쓰는 게 답이라고 본다.
lua_shared_dict 크기 잘 잡아야 함. 넘치면 eviction 돌고 결국 정확도 떨어진다. 주요 도메인당 10~20m 추천.