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

การจำกัดอัตราการใช้งานใน Next.js ด้วย Vercel Edge และ Upstash Redis

ในบทความนี้ ผมจะแนะนำคุณตลอดกระบวนการปรับใช้การจำกัดอัตราในเว็บแอปพลิเคชันของคุณโดยใช้ Vercel Edge Middleware และไลบรารี @upstash/ratelimit อย่างหลังใช้ Redis ที่แบ็กเอนด์เพื่อจัดเก็บและจัดการข้อมูลขีดจำกัดอัตรา

ข้อดีของการใช้ Vercel Edge

Vercel Edge เป็นแพลตฟอร์มคอมพิวเตอร์ที่ทำการคำนวณในตำแหน่งที่ใกล้กับผู้ใช้มากที่สุด ฉันจะใช้ Vercel Edge Middleware ซึ่งจะสกัดกั้นคำขอก่อนที่จะไปถึงแบ็กเอนด์ ฉันเชื่อว่านี่เหมาะอย่างยิ่งสำหรับการดำเนินการจำกัดอัตราด้วยเหตุผลหลายประการ:

  • มันถูกแยกออกจากแบ็กเอนด์ของคุณ ทำให้คุณสามารถบล็อกการรับส่งข้อมูลที่ตำแหน่ง Edge ก่อนที่จะไปถึงแบ็กเอนด์
  • รวดเร็วและไม่มีปัญหาการสตาร์ทขณะเครื่องเย็น ส่งผลให้มีค่าใช้จ่ายน้อยที่สุด
  • คุ้มค่ากว่าเมื่อเปรียบเทียบกับฟังก์ชันไร้เซิร์ฟเวอร์

ทำไมถึง @upstash/ratelimit?

  • @upstash/ratelimit เป็นไลบรารีจำกัดอัตราที่ออกแบบและทดสอบสำหรับฟังก์ชัน Edge โดยเฉพาะ
  • รองรับ Redis หลายภูมิภาคเพื่อเวลาแฝงที่เหมาะสมที่สุดจากตำแหน่ง Edge
  • Upstash Redis เป็น Redis ที่มีการจัดการเพียงตัวเดียวที่สามารถเข้าถึงได้จากฟังก์ชัน Edge เนื่องจากมี REST API

จากที่กล่าวมา มาเริ่มดำเนินการกันเลย:

ขั้นตอนที่ 1:ตั้งค่า Redis

สร้างฐานข้อมูล Redis บน Upstash Console หรือ Upstash CLI 09 และ 12 จะจำเป็นสำหรับขั้นตอนต่อไป

การจำกัดอัตราการใช้งานใน Next.js ด้วย Vercel Edge และ Upstash Redis

ขั้นตอนที่ 2:การตั้งค่า Next.js

สร้างแอปพลิเคชัน Next.js (ตรวจสอบสิ่งนี้สำหรับกรอบงานอื่นๆ)

npx create-next-app@latest --typescript

ติดตั้ง @upstash/ratelimit:

npm i @upstash/ratelimit

สร้าง middleware.ts (ระดับบนสุดในโฟลเดอร์โครงการของคุณ):

import { NextFetchEvent, NextRequest, NextResponse } from "next/server";
 
import { Ratelimit } from "@upstash/ratelimit";
import { Redis } from "@upstash/redis";
 
const redis = new Redis({
 url: "https://us1-merry-snake-32728.upstash.io",
 token: "AX_sAdsdfsgODM5ZjExZGEtMmmVjNmE345445kGVmZTk5MzQ=",
});
 
const ratelimit = new Ratelimit({
 redis: redis,
 limiter: Ratelimit.slidingWindow(5, "10 s"),
});
 
export default async function middleware(
 request: NextRequest,
 event: NextFetchEvent,
): Promise<Response | undefined> {
 const ip = request.ip ?? "127.0.0.1";
 const { success, pending, limit, reset, remaining } =
 await ratelimit.limit(ip);
 return success
 ? NextResponse.next()
 : NextResponse.redirect(new URL("/blocked", request.url));
}
 
export const config = {
 matcher: "/",
};

อย่าลืมแทนที่ URL และโทเค็น Redis ของคุณ รหัสใช้ 24 อัลกอริธึมและอนุญาต 5 คำขอจาก IP เดียวกันใน 10 วินาที หากคุณมีพร็อพเพอร์ตี้เฉพาะสำหรับผู้ใช้ (รหัสผู้ใช้ อีเมล ฯลฯ) คุณสามารถใช้คุณสมบัตินั้นแทน IP ได้ หากคำขอมีอัตราจำกัด มิดเดิลแวร์จะเปลี่ยนเส้นทางไปที่ 30 หน้า.

มาสร้าง 40 กันเถอะ :

import styles from "@/styles/Home.module.css";
 
export default function Blocked() {
 return (
 <div>
 <main className={styles.main}>
 <h3>Access blocked.</h3>
 </main>
 </div>
 );
}

นั่นคือทั้งหมด! ตอนนี้คุณสามารถปรับใช้แอปกับ Vercel:58

รีเฟรชเพจ คุณควรถูกเปลี่ยนเส้นทางไปยังเพจที่ถูกบล็อกหลังจากผ่านไป 3 ครั้ง

โทรระยะไกลน้อยลงพร้อมแคช

การโทรระยะไกลกับคำขอแต่ละรายการไม่มีประสิทธิภาพ คุณสมบัติที่มีประโยชน์ของแพ็คเกจ @uptash/ratelimit ก็คือมันจะแคชข้อมูลตราบใดที่ฟังก์ชัน edge นั้น "ร้อน" ซึ่งหมายความว่าข้อมูลจะถูกดึงมาจาก Redis เมื่อฟังก์ชันเป็น "เย็น" เท่านั้น ซึ่งจะช่วยลดจำนวนการโทรระยะไกล การแคชสามารถทำได้โดยการประกาศ 65 วัตถุภายนอกตัวจัดการ 70 .

อัลกอริทึมการจำกัดอัตรา

ในตัวอย่างข้างต้น เราได้ใช้อัลกอริธึมหน้าต่างบานเลื่อน คุณสามารถใช้หน้าต่างคงที่และอัลกอริธึมบัคเก็ตรั่วไหลได้ ทั้งนี้ขึ้นอยู่กับความต้องการของคุณ ตรวจสอบที่นี่

Redis หลายภูมิภาค

ควรมีฐานข้อมูล Redis หลายฐานข้อมูลในภูมิภาคต่างๆ เพื่อปรับปรุงประสิทธิภาพจากฟังก์ชัน Edge คุณสามารถกำหนดค่า Redis ได้หลายภูมิภาคตามที่อธิบายไว้ที่นี่

ลิงก์

การจำกัดอัตราด้วย Next.js (ไม่ใช่ Edge)

มิดเดิลแวร์ Vercel Edge

SDK การจำกัดอัตรา