[Redis] incr, expire 로 API 호출 스로틀링 구현하기

Woong·2024년 11월 25일
0

Typescript

목록 보기
3/3
  • x-real-ip, x-forwarded-for 로 client IP 획득
    • 단, x-real-ip, x-forwarded-for 는 클라이언트와 proxy 에서 임의로 조작 가능하므로 맹신할 수 없다.
getClientIp(request) {
    try {
        let clientIp = request.headers['x-real-ip']
        if (!clientIp) {
            const forwardedIpList = request.headers['x-forwarded-for']
            if (forwardedIpList) {
                clientIp = forwardedIpList.split(',')[0]
            }
        }
        return clientIp
    } catch (error) {
        logger.error(`failed to get client ip: `, error)
        return null
    }
}
  • Redis incr, expire 를 이용하여 스로틀링 로직 구현
    async isRequestAllowed(originKey, redisClient) {
        const expiredSec = 600
        const throttleCount = 50
        try {
            if (!originKey) {
                return true
            }
            let redisKey = `throttle:${originKey}`
            const count = await redisClient.incr(redisKey)
            // expire 를 통해 스로틀링할 시간 범위 지정
            if (count === 1) {
                await redisClient.expire(key, expiredSec)
            }

            if (count > throttleCount) {
                // expire 되기 전 threshold 초과
                return false
            }
            return true
        } catch (error) {
            logger.error(`failed to check request allowed: `, error)
            return true
        }
    }

0개의 댓글