ในคู่มือที่ครอบคลุมนี้ คุณจะสร้างตัวจำกัดอัตราแบบกระจายโดยใช้สคริปต์ Redis และ Lua เพื่อควบคุมคำขอของผู้ใช้ในสภาพแวดล้อมที่มีการรับส่งข้อมูลสูง
การจำกัดอัตราเป็นสิ่งสำคัญในระบบใดๆ เพื่อป้องกันการละเมิด จัดการการรับส่งข้อมูล และปกป้องทรัพยากรของคุณ ด้วยการใช้ประโยชน์จาก Redis และ Lua คุณจะสร้างระบบจำกัดอัตราที่มีประสิทธิภาพและปรับขนาดได้ ซึ่งสามารถรองรับคำขอจำนวนมากในขณะเดียวกันก็รักษาบริการแบ็กเอนด์ของคุณให้ปลอดภัย
นอกจากนี้เรายังจะรวมการสาธิตเชิงโต้ตอบที่ผู้ใช้สามารถจำลองการรับส่งข้อมูล สังเกตการจำกัดอัตราที่บังคับใช้ และดูบันทึกของคำขอที่ถูกบล็อก
สิ่งที่คุณจะได้เรียนรู้
-
วิธีสร้างระบบจำกัดอัตราโดยใช้ Redis
-
วิธีใช้สคริปต์ Lua กับ Redis เพื่อให้บรรลุการดำเนินการแบบอะตอมมิก
-
ทำความเข้าใจโครงสร้างข้อมูล Redis เพื่อการติดตามคำขอที่มีประสิทธิภาพ
-
เทคนิคในการจัดการการรับส่งข้อมูลสูงในระบบแบบกระจาย
-
การใช้ Docker เพื่อจำลองและปรับขนาดตัวจำกัดอัตราแบบกระจาย
ข้อกำหนดเบื้องต้น
ก่อนเริ่มต้น ตรวจสอบให้แน่ใจว่าคุณได้ติดตั้งสิ่งต่อไปนี้แล้ว:
-
Node.js (v14 หรือสูงกว่า)
-
เรดดิส
-
นักเทียบท่า (สำหรับการจำลองสภาพแวดล้อมแบบกระจาย)
-
ความเข้าใจพื้นฐานเกี่ยวกับสคริปต์ Node.js, Redis และ Lua
สารบัญ
-
สิ่งที่คุณจะได้เรียนรู้
-
ข้อกำหนดเบื้องต้น
-
ภาพรวมโครงการ
-
ขั้นตอนที่ 1:วิธีการตั้งค่าโครงการ
-
ขั้นตอนที่ 2:วิธีการตั้งค่า Redis
-
ขั้นตอนที่ 3:วิธีใช้ตัวจำกัดอัตราด้วย Redis และ Lua
-
ขั้นตอนที่ 4:วิธีสร้างเซิร์ฟเวอร์ Node.js API
-
ขั้นตอนที่ 5:วิธีทดสอบตัวจำกัดอัตรา
-
ขั้นตอนที่ 6:วิธีแสดงภาพตัวชี้วัดการจำกัดอัตรา
-
ขั้นตอนที่ 7:วิธีการปรับใช้ด้วย Docker
-
สรุป:สิ่งที่คุณได้เรียนรู้
ภาพรวมโครงการ
ในบทช่วยสอนนี้ คุณจะ:
-
สร้างตัวจำกัดอัตราโดยใช้ Redis และ Lua เพื่อบังคับใช้โควต้าคำขอ
-
ใช้สคริปต์ Lua เพื่อรับรองการทำงานของอะตอมมิก หลีกเลี่ยงสภาวะการแข่งขัน
-
ใช้อัลกอริทึมที่เก็บข้อมูลโทเค็นสำหรับการจำกัดอัตรา
-
สร้างการสาธิตเชิงโต้ตอบเพื่อจำลองปริมาณการเข้าชมที่สูงและแสดงภาพการจำกัดอัตราการดำเนินการ
สถาปัตยกรรมระบบ
คุณจะสร้างระบบด้วยส่วนประกอบต่อไปนี้:
-
เซิร์ฟเวอร์ API :จัดการคำขอของผู้ใช้ที่เข้ามา
-
เรดิส :จัดเก็บข้อมูลคำขอและบังคับใช้ขีดจำกัดอัตรา
-
สคริปต์ลัวะ :ตรวจสอบให้แน่ใจว่าการอัปเดตอะตอมมิกเป็น Redis สำหรับการจำกัดอัตรา
-
นักเทียบท่า :จำลองสภาพแวดล้อมแบบกระจายที่มีหลายอินสแตนซ์
ขั้นตอนที่ 1:วิธีการตั้งค่าโครงการ
เริ่มต้นด้วยการตั้งค่าโครงการ Node.js ของเรา:
mkdir distributed-rate-limiter
cd distributed-rate-limiter
npm init -y
ถัดไป ติดตั้งการขึ้นต่อกันที่จำเป็น:
npm install express redis dotenv
-
ด่วน :เฟรมเวิร์กเว็บเซิร์ฟเวอร์น้ำหนักเบา
-
ทำซ้ำ :สำหรับการโต้ตอบกับ Redis
-
โดเทนวี :สำหรับการจัดการตัวแปรสภาพแวดล้อม
สร้าง .env ไฟล์ที่มีเนื้อหาดังต่อไปนี้:
REDIS_HOST=localhost
REDIS_PORT=6379
PORT=3000
RATE_LIMIT=5
TIME_WINDOW=60
ตัวแปรเหล่านี้กำหนดโฮสต์ Redis พอร์ต ขีดจำกัดอัตรา (จำนวนคำขอที่อนุญาต) และกรอบเวลา (เป็นวินาที)
ขั้นตอนที่ 2:วิธีการตั้งค่า Redis
ก่อนที่เราจะเจาะลึกโค้ด ตรวจสอบให้แน่ใจว่า Redis ได้รับการติดตั้งและทำงานบนระบบของคุณแล้ว หากคุณไม่ได้ติดตั้ง Redis คุณสามารถใช้ Docker เพื่อตั้งค่าได้อย่างรวดเร็ว:
docker run -p 6379:6379 --name redis-rate-limiter -d redis
ขั้นตอนที่ 3:วิธีใช้ตัวจำกัดอัตราด้วย Redis และ Lua
เพื่อจัดการกับการจำกัดอัตราอย่างมีประสิทธิภาพ เราจะใช้อัลกอริธึมบัคเก็ตโทเค็น ในอัลกอริทึมนี้:
-
ผู้ใช้แต่ละคนมี "ถัง" ของโทเค็น
-
แต่ละคำขอใช้โทเค็น
-
โทเค็นจะเติมเป็นระยะตามอัตราที่กำหนด
เพื่อให้แน่ใจว่ามีความเป็นอะตอมมิกและหลีกเลี่ยงสภาวะการแข่งขัน เราจะใช้สคริปต์ Lua กับ Redis สคริปต์ Lua ใน Redis ดำเนินการแบบอะตอมมิก ซึ่งหมายความว่าไม่สามารถถูกขัดจังหวะด้วยการดำเนินการอื่นๆ ในขณะที่ทำงานอยู่
วิธีสร้างสคริปต์ Lua สำหรับการจำกัดอัตรา
สร้างไฟล์ชื่อ 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] :คีย์ Redis แสดงถึงจำนวนคำขอของผู้ใช้
-
ARGV[1] :ขีดจำกัดอัตรา (จำนวนคำขอสูงสุดที่อนุญาต)
-
ARGV[2] :กรอบเวลา (เป็นวินาที) สำหรับการจำกัดอัตรา
-
-
ตรรกะ :
-
หากผู้ใช้ถึงขีดจำกัดอัตราแล้ว ให้ส่งคืน
0(คำขอถูกบล็อก) -
หากผู้ใช้อยู่ภายในขีดจำกัด ให้เพิ่มจำนวนคำขอหรือตั้งค่าการนับใหม่โดยระบุวันหมดอายุหากเป็นคำขอแรก
-
ส่งคืน 1 (อนุญาตคำขอ)
-
ขั้นตอนที่ 4:วิธีสร้างเซิร์ฟเวอร์ Node.js API
สร้างไฟล์ชื่อ 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 for 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}`);
});
-
มิดเดิลแวร์ตัวจำกัดอัตรา :
-
ดึงข้อมูลที่อยู่ IP ของลูกค้าและตรวจสอบว่าอยู่ภายในขีดจำกัดอัตราหรือไม่โดยใช้สคริปต์ Lua
-
หากผู้ใช้เกินขีดจำกัด
429ส่งคำตอบแล้ว
-
-
จุดสิ้นสุด API :
- จุดสิ้นสุดรากมีการจำกัดอัตรา ดังนั้นผู้ใช้จึงสามารถเข้าถึงได้ในจำนวนที่จำกัดภายในหน้าต่างที่ระบุเท่านั้น
ขั้นตอนที่ 5:วิธีทดสอบตัวจำกัดอัตรา
-
เริ่ม Redis :
docker start redis-rate-limiter -
เรียกใช้เซิร์ฟเวอร์ Node.js :
node server.js -
จำลองคำขอ :
-
ใช้
curlหรือบุรุษไปรษณีย์เพื่อทดสอบตัวจำกัดอัตรา:curl http://localhost:3000 -
ส่งคำขอหลายรายการอย่างรวดเร็วเพื่อดูการจำกัดอัตราในการดำเนินการ
-
ขั้นตอนที่ 6:วิธีแสดงภาพตัวชี้วัดการจำกัดอัตรา
ในการตรวจสอบตัวชี้วัดการจำกัดอัตรา เช่น การใช้งานแคชและคำขอที่ถูกบล็อก เราจะเพิ่มการบันทึกลงในมิดเดิลแวร์ใน 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' });
}
}
ขั้นตอนที่ 7:วิธีการปรับใช้ด้วย Docker
มาจัดคอนเทนเนอร์แอปพลิเคชันเพื่อรันในสภาพแวดล้อมแบบกระจาย
สร้าง Dockerfile :
FROM node:14
WORKDIR /app
COPY . .
RUN npm install
EXPOSE 3000
CMD ["node", "server.js"]
สร้างและเรียกใช้คอนเทนเนอร์ Docker:
docker build -t rate-limiter .
docker run -p 3000:3000 rate-limiter
ตอนนี้คุณสามารถปรับขนาดขีดจำกัดอัตราได้ด้วยการเรียกใช้หลายอินสแตนซ์
บทสรุป:สิ่งที่คุณได้เรียนรู้
ขอแสดงความยินดี! คุณสร้างตัวจำกัดอัตราแบบกระจายโดยใช้สคริปต์ Redis และ Lua สำเร็จแล้ว ตลอดบทแนะนำนี้ คุณได้เรียนรู้วิธี:
-
ใช้การจำกัดอัตราการควบคุมคำขอของผู้ใช้ในระบบแบบกระจาย
-
ใช้สคริปต์ Lua ใน Redis เพื่อดำเนินการแบบอะตอมมิก
-
ใช้อัลกอริทึมที่เก็บข้อมูลโทเค็นเพื่อจัดการโควต้าคำขอ
-
ตรวจสอบเมตริกการจำกัดอัตราเพื่อเพิ่มประสิทธิภาพ
-
ใช้ Docker เพื่อจำลองสภาพแวดล้อมแบบกระจายที่ปรับขนาดได้
ขั้นตอนถัดไป:
-
เพิ่มการจำกัดอัตราตามรหัสผู้ใช้ :ขยายระบบเพื่อรองรับขีดจำกัดอัตราต่อผู้ใช้
-
บูรณาการกับ Nginx :ใช้ Nginx เป็นพร็อกซีย้อนกลับโดยมีการจำกัดอัตราที่สนับสนุน Redis
-
ปรับใช้กับ Kubernetes :ปรับขนาดขีดจำกัดอัตราของคุณโดยใช้ Kubernetes เพื่อความพร้อมใช้งานสูง
ขอให้สนุกกับการเขียนโค้ด!
เรียนรู้การเขียนโค้ดฟรี หลักสูตรโอเพ่นซอร์สของ freeCodeCamp ช่วยให้ผู้คนมากกว่า 40,000 คนได้งานในตำแหน่งนักพัฒนา เริ่มต้น