ในคู่มือครอบคลุมนี้ คุณจะสร้าง 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 นี้ คุณจะ:
- สร้าง rate limiter ใช้ Redis และ Lua บังคับ request quotas
- ใช้ Lua scripts รับรอง atomic operations ป้องกัน race conditions
- Implement token bucket algorithm สำหรับ rate limiting
- สร้าง interactive demo จำลอง high traffic และ visualize rate limiting ใน action
System Architecture
คุณจะสร้างระบบด้วย components ต่อไป:
- API Server: จัดการ incoming user requests
- Redis: เก็บ request data และบังคับ rate limits
- Lua Scripts: รับรอง atomic updates ไป Redis สำหรับ rate limiting
- 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 นี้:
- แต่ละ user มี "bucket" ของ tokens
- แต่ละ request consume token หนึ่ง
- 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
Inputs:
- KEYS[1]: Redis key แทน request count ของ user
- ARGV[1]: rate limit (จำนวน request สูงสุดที่อนุญาต)
- ARGV[2]: time window (วินาที) สำหรับ rate limit
Logic:
- หาก user ชน rate limit คืน
0(request blocked) - หาก user อยู่ใน limit increment request count หรือ set ใหม่พร้อม expiration หากเป็น request แรก
- คืน 1 (request allowed)
- หาก user ชน rate limit คืน
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}`);
});
Rate Limiter Middleware:
- ดึง IP address ของ client และตรวจสอบว่าอยู่ใน rate limit ด้วย Lua script
- หาก user เกิน limit ส่ง response
429
API Endpoint:
- Root endpoint มี rate limit ผู้ใช้เข้าถึงได้จำนวนจำกัดภายใน time window ที่ระบุ
Step 5: How to Test the Rate Limiter
Start Redis:
docker start redis-rate-limiterRun Node.js Server:
node server.jsSimulate 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 นี้ คุณเรียนรู้ว่า:
- Implement rate limiting ควบคุม user requests ใน distributed system
- ใช้ Lua scripts ใน Redis ทำ atomic operations
- Apply token bucket algorithm จัดการ request quotas
- Monitor rate limiting metrics เพื่อ optimize performance
- ใช้ Docker จำลอง scalable distributed environment
Next Steps:
Add Rate Limiting by User ID: ขยายระบบรองรับ rate limits ต่อ user
Integrate with Nginx: ใช้ Nginx เป็น reverse proxy พร้อม Redis-backed rate limiting
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