หนึ่งในสิ่งดีที่สุดของ Serverless คือความสามารถในการ Scale แม้ Traffic Spike โตใหญ่ แต่การ Scale ไม่ได้ฟรี ทั้งทางการเงินและเทคนิค นั่นคือเหตุผลที่นักพัฒนาต้องควบคุม Scalability ของแอปพลิเคชัน นี่คือเหตุผลหลักที่คุณต้องการ Rate Limiting Mechanism ใน Serverless App:
1. ปกป้องทรัพยากร (Protect your resources): หากคุณให้ Public API Traffic Spikes อาจลดคุณภาพบริการ และนำไปสู่ Service Outage สำหรับผู้ใช้ทุกคน คุณต้องปกป้องระบบจาก Cascading Failures และ Self-inflicted DDoS Incidents Bug ในแอปอาจก่อให้เกิดปัญหาเหล่านี้ Internal Process ที่ Retry Endpoint ตลอดเวลาเมื่อล้มเหลว สามารถทำให้ Resources หมดง่ายๆ
2. จัดการ User Quotas (Manage user quotas): คุณอาจต้องการกำหนด Quotas ให้ Users เพื่อ Fair Use หรือหากให้บริการใน Pricing Tiers ต่างๆ
3. ควบคุมต้นทุน (Control the cost): มีตัวอย่างจริงมากมายว่า Uncontrolled System ก่อให้เกิด Bills ใหญ่โต นี่เป็นความเสี่ยงสำคัญสำหรับ Serverless Apps เนื่องจากลักษณะ Highly Scalable Rate Limiting จะช่วยควบคุมต้นทุนเหล่านี้
โซลูชัน (Solutions)
มี Rate Limiting Solutions หลายตัวใน Layer ต่างๆ จะรายการ 3 ตัวหลักพร้อม Pros/Cons แบบสรุป
1. Concurrency Level ของ Function:
Cloud Providers สร้าง Containers หลายตัวเพื่อ Scale Function Executions คุณตั้ง Limit สำหรับ Max Concurrent Containers/Instances ได้ แม้ช่วย Limit Concurrency ได้ แต่ไม่ควบคุมว่าจะเรียก Function กี่ครั้งต่อวินาที
วิธี Limit Concurrency สำหรับ AWS Lambda และ Google Cloud Functions
Pros:
- No Overhead
- ตั้งค่าง่าย
Cons:
- ไม่ใช่โซลูชันสมบูรณ์ ควบคุมแค่ Concurrency จำนวน Executions ต่อวินาทีไม่ถูกจำกัด
2. Rate Limiting บน API Gateway
หากเข้าถึง Functions ผ่าน API Gateway คุณสามารถนำ Rate Limiting Policy ไปใช้กับ API Gateway ทั้ง AWS และ GCP มีคู่มือการตั้งค่า
Pros:
- No Overhead
- ตั้งค่าง่าย
Cons:
- ใช้ได้ก็ต่อเมื่อใช้ API Gateway
- ไม่รองรับกรณีซับซ้อน เช่น Quotas ต่อ User หรือต่อ IP
3. Rate Limiting ด้วย Redis
นี่คือโซลูชันที่สมบูรณ์และทรงพลังที่สุด มี Redis-based Rate Limiting Libraries หลายตัว ใน บล็อกของ Jeremy Daly เขาปฏิเสธ Elasticache ว่า this adds a "non-serverless" component and another thing to manage Upstash กลายเป็นทางเลือกดีด้วย Serverless Model และ Per-request Pricing
Pros:
- ทรงพลัง Implement Custom Logic ที่เข้ากับ User Model ของคุณได้
- Scalable Solution ดู วิธีที่ Github ใช้ Redis สำหรับ Rate Limiting
- Rich Ecosystem หลาย Open Source Libraries: redis_rate, redis-cell, node-ratelimiter
Cons:
- Overhead ของการใช้ Redis
โค้ด: Rate Limiting ด้วย Redis
ขอบคุณ Rate Limiting Libraries ใช้ Rate Limiting กับ Application Code ได้ง่าย โค้ดตัวอย่างด้านล่างจำกัดการ Exec AWS Lambda Function ต่อ IP ต่อวินาที:
const RateLimiter = require("async-ratelimiter");
const Redis = require("ioredis");
const { getClientIp } = require("request-ip");
const rateLimiter = new RateLimiter({
db: new Redis("YOUR_REDIS_URL"),
max: 1,
duration: 5_000,
});
module.exports.hello = async (event) => {
const clientIp = getClientIp(event) || "NA";
const limit = await rateLimiter.get({ id: clientIp });
if (!limit.remaining) {
return {
statusCode: 429,
body: JSON.stringify({
message: "Sorry, you are rate limited. Wait for 5 seconds",
}),
};
}
return {
statusCode: 200,
body: JSON.stringify({ message: "hello!" }),
};
};
เยี่ยมชม Tutorial สำหรับตัวอย่างเต็ม
Reading List
Google Cloud Rate Limiting Strategies
Throttling Third-party API Calls with AWS Lambda
Rate Limit Your API Usage with Cloud Endpoints Quotas
How GitHub Scaled API Rate Limiter with Redis