Trong bài viết này, tôi sẽ hướng dẫn bạn quy trình triển khai giới hạn tốc độ trong ứng dụng web của bạn bằng cách sử dụng Vercel Edge Middleware và thư viện @upstash/ratelimit. Cái sau sử dụng Redis ở phần phụ trợ để lưu trữ và quản lý dữ liệu giới hạn tốc độ.
Ưu điểm của việc sử dụng Vercel Edge
Vercel Edge là một nền tảng điện toán thực hiện các phép tính ở những vị trí gần người dùng nhất. Tôi sẽ sử dụng Vercel Edge Middleware, phần mềm này chặn các yêu cầu trước khi chúng đến phần phụ trợ. Tôi tin rằng đây là giải pháp lý tưởng để triển khai giới hạn tốc độ vì một số lý do:
- Nó được tách rời khỏi phần phụ trợ của bạn, cho phép bạn chặn lưu lượng truy cập ở vị trí biên trước khi nó đến phần phụ trợ.
- Nó nhanh và không gặp vấn đề khi khởi động nguội, giúp giảm thiểu chi phí.
- Nó tiết kiệm chi phí hơn so với các chức năng không có máy chủ.
Tại sao lại @upstash/ratelimit?
- @upstash/ratelimit là thư viện giới hạn tốc độ được thiết kế và kiểm tra riêng cho các chức năng biên.
- Nó hỗ trợ Redis đa vùng để có độ trễ tối ưu từ các vị trí biên.
- Upstash Redis là Redis được quản lý duy nhất có thể được truy cập từ các hàm biên nhờ API REST của nó.
Như đã nói, hãy bắt đầu thực hiện:
Bước 1:Thiết lập lại
Tạo cơ sở dữ liệu Redis trên Upstash Console hoặc Upstash CLI. UPSTASH_REDIS_REST_URL và UPSTASH_REDIS_REST_TOKEN sẽ cần thiết cho các bước tiếp theo.

Bước 2:Thiết lập Next.js
Tạo một ứng dụng Next.js. (Kiểm tra phần này để biết các khung khác)
npx create-next-app@latest --typescript Cài đặt @upstash/ratelimit:
npm i @upstash/ratelimit Tạo middleware.ts (cấp cao nhất trong thư mục dự án của bạn):
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: "/",
};
Đừng quên thay thế url và mã thông báo redis của bạn. Mã sử dụng slidingWindow thuật toán và cho phép 5 yêu cầu từ cùng một IP trong 10 giây. Nếu bạn có thuộc tính duy nhất cho một người dùng (userid, email, v.v.), bạn có thể sử dụng thuộc tính đó thay vì IP. Nếu yêu cầu bị giới hạn tốc độ thì phần mềm trung gian sẽ chuyển hướng yêu cầu đó đến blocked trang.
Hãy tạo pages/blocked.tsx :
import styles from "@/styles/Home.module.css";
export default function Blocked() {
return (
<div>
<main className={styles.main}>
<h3>Access blocked.</h3>
</main>
</div>
);
}
Thế thôi! Bây giờ bạn có thể triển khai ứng dụng lên Vercel:vercel deploy
Làm mới trang, bạn sẽ được chuyển hướng đến trang bị chặn sau 3 lần.
Ít cuộc gọi từ xa hơn nhờ bộ nhớ đệm
Sẽ không hiệu quả khi thực hiện cuộc gọi từ xa với mỗi yêu cầu. Một tính năng hữu ích của gói @uptash/ratelimit là nó lưu trữ dữ liệu miễn là chức năng cạnh "nóng". Điều này có nghĩa là dữ liệu chỉ được lấy từ Redis khi chức năng này ở trạng thái "lạnh", giúp giảm số lượng lệnh gọi từ xa. Bộ nhớ đệm có thể được triển khai bằng cách khai báo ratelimit đối tượng bên ngoài trình xử lý function middleware .
Thuật toán giới hạn tốc độ
Trong ví dụ trên chúng ta đã sử dụng thuật toán cửa sổ trượt. Tùy thuộc vào nhu cầu của bạn, bạn có thể sử dụng thuật toán cửa sổ cố định và nhóm rò rỉ. Kiểm tra ở đây
Redis đa khu vực
Sẽ rất hợp lý khi có nhiều cơ sở dữ liệu Redis ở các vùng khác nhau để cải thiện hiệu suất từ các chức năng biên. Bạn có thể định cấu hình Redis nhiều vùng như được giải thích tại đây
Liên kết
Giới hạn tốc độ với Next.js (không cạnh)
Phần mềm trung gian Vercel Edge
SDK giới hạn tỷ lệ