Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> Redis

สร้าง Distributed Rate Limiter ที่ Scalable ด้วย Redis & Lua – คู่มือทีละขั้นตอน

สร้าง Distributed Rate Limiter ที่ Scalable ด้วย Redis & Lua – คู่มือทีละขั้นตอน

ในคู่มือครอบคลุมนี้ คุณจะสร้าง distributed rate limiter ใช้ Redis และ Lua scripting ควบคุม user requests ในสภาพแวดล้อม high-traffic

Rate limiting สำคัญในทุกระบบ เพื่อป้องกันการใช้งานผิดวัตถุประสงค์ จัดการ traffic และปกป้องทรัพยากร ด้วยการใช้ Redis และ Lua คุณจะสร้างระบบ rate limiting ที่มีประสิทธิภาพ ขยายสเกลได้ จัดการ request จำนวนมากได้ ในขณะที่ backend services ของคุณปลอดภัย

เรายังรวม interactive demo ให้ผู้ใช้ simulate traffic สังเกต rate limits ถูกบังคับใช้ และดู logs ของ blocked requests

สิ่งที่คุณจะได้เรียนรู้

  • วิธีสร้าง rate limiting system ด้วย Redis
  • วิธีใช้ Lua scripts กับ Redis เพื่อ atomic operations
  • เข้าใจ Redis data structures สำหรับ request tracking ที่มีประสิทธิภาพ
  • เทคนิคจัดการ high traffic ใน distributed system
  • ใช้ Docker จำลองและขยายสเกล distributed rate limiter

ข้อกำหนดเบื้องต้น (Prerequisites)

ก่อนเริ่ม ตรวจสอบว่าติดตั้งแล้ว:

  • Node.js (v14 หรือสูงกว่า)
  • Redis
  • Docker (สำหรับจำลอง distributed environment)
  • ความเข้าใจพื้นฐาน Node.js, Redis, และ Lua scripting

สารบัญ

  • สิ่งที่คุณจะได้เรียนรู้
  • ข้อกำหนดเบื้องต้น
  • Project Overview
  • Step 1: How to Set Up the Project
  • Step 2: How to Set Up Redis
  • Step 3: How to Implement the Rate Limiter with Redis and Lua
  • Step 4: How to Create the Node.js API Server
  • Step 5: How to Test the Rate Limiter
  • Step 6: How to Visualize Rate Limiting Metrics
  • Step 7: How to Deploy with Docker
  • Conclusion: What You've Learned

Project Overview

ใน tutorial นี้ คุณจะ:

  1. สร้าง rate limiter ใช้ Redis และ Lua บังคับ request quotas
  2. ใช้ Lua scripts รับรอง atomic operations ป้องกัน race conditions
  3. Implement token bucket algorithm สำหรับ rate limiting
  4. สร้าง interactive demo จำลอง high traffic และ visualize rate limiting ใน action

System Architecture

คุณจะสร้างระบบด้วย components ต่อไป:

  1. API Server: จัดการ incoming user requests
  2. Redis: เก็บ request data และบังคับ rate limits
  3. Lua Scripts: รับรอง atomic updates ไป Redis สำหรับ rate limiting
  4. Docker: จำลอง distributed environment ด้วย multiple instances

Step 1: How to Set Up the Project

เริ่มต้นตั้งค่า Node.js project:

mkdir distributed-rate-limiter
cd distributed-rate-limiter
npm init -y

ติดตั้ง dependencies ที่ต้องการ:

npm install express redis dotenv
  • express: lightweight web server framework
  • redis: 互动กับ Redis
  • dotenv: จัดการ environment variables

สร้างไฟล์ .env ด้วยเนื้อหา:

REDIS_HOST=localhost
REDIS_PORT=6379
PORT=3000
RATE_LIMIT=5
TIME_WINDOW=60

ตัวแปรเหล่านี้กำหนด Redis host, port, rate limit (จำนวน request ที่อนุญาต), และ time window (วินาที)

Step 2: How to Set Up Redis

ก่อนลงโค้ด ตรวจสอบว่า Redis ติดตั้งและรันอยู่บนระบบ หากยังไม่มี Redis ใช้ Docker setup เร็วๆ:

docker run -p 6379:6379 --name redis-rate-limiter -d redis

Step 3: How to Implement the Rate Limiter with Redis and Lua

เพื่อจัดการ rate limiting อย่างมีประสิทธิภาพ เราจะใช้ token bucket algorithm ใน algorithm นี้:

  1. แต่ละ user มี "bucket" ของ tokens
  2. แต่ละ request consume token หนึ่ง
  3. Tokens refill periodically ตามอัตราที่ตั้งไว้

เพื่อให้ได้ atomicity และหลีกเลี่ยง race conditions เราจะใช้ Lua scripting กับ Redis Lua scripts ใน Redis execute แบบ atomic หมายความว่าไม่ถูก interrupt โดย operations อื่นขณะรัน

วิธีสร้าง Lua Script สำหรับ Rate Limiting

สร้างไฟล์ rate_limiter.lua:

local key = KEYS[1]
local limit = tonumber(ARGV[1])
local window = tonumber(ARGV[2])
local current = redis.call("get", key)
if current and tonumber(current) >= limit then
    return 0
else
    if current then
        redis.call("incr", key)
    else
        redis.call("set", key, 1, "EX", window)
    end
    return 1
end
  1. Inputs:

    • KEYS[1]: Redis key แทน request count ของ user
    • ARGV[1]: rate limit (จำนวน request สูงสุดที่อนุญาต)
    • ARGV[2]: time window (วินาที) สำหรับ rate limit
  2. Logic:

    • หาก user ชน rate limit คืน 0 (request blocked)
    • หาก user อยู่ใน limit increment request count หรือ set ใหม่พร้อม expiration หากเป็น request แรก
    • คืน 1 (request allowed)

Step 4: How to Create the Node.js API Server

สร้างไฟล์ server.js:

require('dotenv').config();
const express = require('express');
const redis = require('redis');
const fs = require('fs');
const path = require('path');
const app = express();
const client = redis.createClient({ host: process.env.REDIS_HOST, port: process.env.REDIS_PORT });
const rateLimitScript = fs.readFileSync(path.join(__dirname, 'rate_limiter.lua'), 'utf8');
const RATE_LIMIT = parseInt(process.env.RATE_LIMIT);
const TIME_WINDOW = parseInt(process.env.TIME_WINDOW);
// Middleware สำหรับ rate limiting
async function rateLimiter(req, res, next) {
    const ip = req.ip;
    try {
        const allowed = await client.eval(rateLimitScript, 1, ip, RATE_LIMIT, TIME_WINDOW);
        if (allowed === 1) {
            next();
        } else {
            res.status(429).json({ message: 'Too many requests. Please try again later.' });
        }
    } catch (err) {
        console.error('Error in rate limiter:', err);
        res.status(500).json({ message: 'Internal server error' });
    }
}
app.use(rateLimiter);
app.get('/', (req, res) => {
    res.send('Welcome to the Rate Limited API!');
});
const PORT = process.env.PORT;
app.listen(PORT, () => {
    console.log(`Server running on port ${PORT}`);
});
  1. Rate Limiter Middleware:

    • ดึง IP address ของ client และตรวจสอบว่าอยู่ใน rate limit ด้วย Lua script
    • หาก user เกิน limit ส่ง response 429
  2. API Endpoint:

    • Root endpoint มี rate limit ผู้ใช้เข้าถึงได้จำนวนจำกัดภายใน time window ที่ระบุ

Step 5: How to Test the Rate Limiter

  1. Start Redis:

    docker start redis-rate-limiter
  2. Run Node.js Server:

    node server.js
  3. Simulate Requests:

    • ใช้ curl หรือ Postman ทดสอบ rate limiter:
    curl https://localhost:3000
    • ส่ง multiple requests เร็วๆ เพื่อดู rate limiting ใน action

Step 6: How to Visualize Rate Limiting Metrics

เพื่อ monitor rate limiting metrics เช่น cache hits และ blocked requests เราเพิ่ม logging ใน middleware ใน server.js:

async function rateLimiter(req, res, next) {
    const ip = req.ip;
    try {
        const allowed = await client.eval(rateLimitScript, 1, ip, RATE_LIMIT, TIME_WINDOW);
        if (allowed === 1) {
            console.log(`Allowed request from ${ip}`);
            next();
        } else {
            console.log(`Blocked request from ${ip}`);
            res.status(429).json({ message: 'Too many requests. Please try again later.' });
        }
    } catch (err) {
        console.error('Error in rate limiter:', err);
        res.status(500).json({ message: 'Internal server error' });
    }
}

Step 7: How to Deploy with Docker

มา containerize application เพื่อรันใน distributed environment

สร้าง Dockerfile:

FROM node:14
WORKDIR /app
COPY . .
RUN npm install
EXPOSE 3000
CMD ["node", "server.js"]

Build และ Run Docker Container:

docker build -t rate-limiter .
docker run -p 3000:3000 rate-limiter

ตอนนี้คุณ scale rate limiter ได้โดยรัน multiple instances

Conclusion: What You've Learned

ยินดีด้วย! คุณสร้าง distributed rate limiter ด้วย Redis และ Lua scripts เรียบร้อยแล้ว ตลอด tutorial นี้ คุณเรียนรู้ว่า:

  1. Implement rate limiting ควบคุม user requests ใน distributed system
  2. ใช้ Lua scripts ใน Redis ทำ atomic operations
  3. Apply token bucket algorithm จัดการ request quotas
  4. Monitor rate limiting metrics เพื่อ optimize performance
  5. ใช้ Docker จำลอง scalable distributed environment

Next Steps:

  1. Add Rate Limiting by User ID: ขยายระบบรองรับ rate limits ต่อ user

  2. Integrate with Nginx: ใช้ Nginx เป็น reverse proxy พร้อม Redis-backed rate limiting

  3. Deploy with Kubernetes: Scale rate limiter ด้วย Kubernetes สำหรับ high availability

Happy coding!

Learn to code for free. freeCodeCamp's open source curriculum has helped more than 40,000 people get jobs as developers. Get started