Tôi đã triển khai tính năng rate/limit cho bình luận như thế nào?

Tôi đã triển khai tính năng rate/limit cho bình luận như thế nào?

Những mẩu tin ngắn hàng ngày dành cho bạn
  • Mọi người thường nói đùa rằng regex là ngôn ngữ của người ngoài hành tinh. Ai mà viết được regex thì họ có năng lực của một người ngoài Trái Đất. Nói đùa vậy thôi chứ thực chất là chỉ ý regex thật khó hiểu.

    Tình cờ mình biết đến một trang web dạy chúng ta regex từng bước một. Trong quá trình học chúng ta cần tương tác với hàng chục câu hỏi từ đơn giản đến nâng cao để từng bước học cách sử dụng "ngôn ngữ ngoài hành tinh" này.

    regexlearn.com

    » Xem thêm
  • Tin vui đầu ngày. Github vừa công bố rộng rãi GitHub Models đến tất cả mọi người. Nếu còn nhớ cách đây hơn 2 tháng trước, Github có chương trình đăng ký dùng thử các models của LLMs, và trường hợp của mình thì phải một tháng sau mới được duyệt cho dùng. Thì giờ đây họ đã cho mọi người dùng Github có quyền truy cập vào rồi, không cần phải đăng ký gì nữa 🥳

    GitHub Models đang là phao cứu sinh cho mình trong khi xây dựng trang blog này 😆

    GitHub Models is now available in public preview | Github Blog

    » Xem thêm
  • Hôm trước mình thấy repository này dùng TauriSvelte để viết lại ứng dụng kiểu như là Task Manager trên Window hay Monitor trên Mac á. Tò mò tải về xem thử thì bất ngờ thứ nhất là dung lượng rất nhỏ, chỉ vài MB. Tiếp theo là tốc độ khởi động cũng rất nhanh mà ứng dụng cũng rất mượt nữa chứ 🫣

    Abdenasser/neohtop

    » Xem thêm

Vấn đề

Captcha là một cách thức được sinh ra nhằm mục đích ngăn chặn hành vi spam trên các ứng dụng, đặc biệt là đối với ứng dụng web. Nếu không có captcha, kẻ tấn công có thể dễ dàng tạo ra những đoạn mã tự động gửi truy vấn với tần suất liên tục đến chức năng nào đó nhằm phá hoại hệ thống.

Tuy vậy, captcha không phải không có nhược điểm. Có lẽ hạn chế lớn nhất của nó là gây "lú" cho người dùng. Nhiều đoạn mã được sinh ra để xác minh bạn là con người, nhưng đôi khi bạn phải tự hỏi liệu mình có là người không khi không thể dịch được những kí tự méo mó hoặc mờ tịt kia.

Chức năng bình luận trên 2coffee không sử dụng captcha để tạo ra khó khăn cho người dùng giống như trên. Thay vào đó tôi đã áp dụng một kỹ thuật gọi là "rate/limit" để hạn chế hành vi spam. Nói nôm na, nó ngăn chặn một hành vi liên tục, giới hạn số lần thực hiện trong một khoảng thời gian nhất định. Ví dụ như chỉ cho phép người dùng bình luận tối đa 3 lần trong 1 phút, hay cần phải chờ ít nhất 10 giây để cho lượt gửi bình luận tiếp theo.

Bài viết ngày hôm nay tôi xin phép được tường thuật lại quá trình triển khai tính năng rate/limit của mình. Tôi nghĩ rằng điều đó sẽ giúp ích cho bạn đọc, hoặc hy vọng được nhận lại ý kiến của bạn đọc để có thêm cách triển khai tốt hơn.

Thuật toán

Ý tưởng ban đầu rất đơn giản, vì không quá khắt khe nên tôi quyết định cho phép người dùng được gửi bình luận sau mỗi 10 giây kể từ lần gửi thành công trước đó. Sau khi gửi bình luận thành công ở một bài viết thì cần chờ tối thiểu 10 giây để gửi bình luận ở bất kỳ bài nào.

Lúc này cần triển khai được thuật toán có đầu vào là id người dùng, đầu ra là true/false. True nếu chưa vượt quá limit và false nếu đã bình luận quá nhiều. Dựa vào đó để cho phép họ gửi được hay không.

Có nhiều cách để giải quyết vấn đề này, đơn giản nhất là cứ mỗi lần bình luận sẽ lấy ra bình luận cuối cùng của họ rồi kiểm tra thời gian xem có hợp lệ. Cách này thì triển khai nhanh, đơn giản nhưng nếu sau này bình luận nhiều lên thì truy vấn có phần chậm chạp. Hơn nữa việc mở rộng sau này có phần phức tạp hơn. Ví dụ như thay đổi thuật toán để cho phép họ gửi tối đa 3 bình luận trong thời gian một phút chẳng hạn. Lúc đó truy vấn sẽ phức tạp và nhiều khả năng sẽ chậm hơn.

Vì đang sử dụng Redis, tôi có thêm một cách là tận dụng chức năng khóa hết hạn (ttl) của một key trong Redis. Tôi sẽ tạo ra một key có dạng "comment_limit:" chứa một giá trị boolean có thời gian hết hạn là khoảng thời gian giữa các lần bình luận liên tiếp. Mỗi khi bình luận, chỉ cần kiểm tra key "comment_limit:" có tồn tại hay không, nếu có thì chắc chắn là họ không được phép bình luận và ngược lại.

Ưu điểm của cách này là thời gian kiểm tra điều kiện tương đối nhanh, chỉ mất một truy vấn lấy ra key "comment_limit:". Tuy vậy, cần phải viết nhiều mã hơn để xử lý logic.

Triển khai

Triển khai rất đơn giản, bạn cần có máy chủ Redis để tạo ra các key có ttl. Mỗi khi gọi hàm tạo bình luận thì kiểm tra xem đã có key "comment_limit:" chưa.

Ví dụ trong trường hợp user_id của tôi bằng 1:

GET comment_limit:1

Nếu comment_limit:1 trả về true hãy bắn ra một lỗi không được phép bình luận. Ngược lại nếu là null thì cho phép thêm bình luận rồi sau đó thêm một key comment_limit:1 với thời gian hết hạn là thời gian bạn thiết lập. Giả sử là 10 giây:

SET comment_limit:1 true EX 10

Khi đó, cứ sau 10 giây thì comment_limit:1 sẽ tự động bị xóa và trả lại logic được phép bình luận cho người dùng.

Tổng kết

Có nhiều cách để triển khai thuật toán rate/limit cho phần bình luận. Tôi đang áp dụng cách sử dụng tính năng key tự động xóa kết hợp với việc quy ước tên của key để tạo ra logic kiểm tra tính khả dụng của hoạt động bình luận. Còn bạn có cách nào khác hãy để lại bình luận cho mọi người biết nhé!

hoặc
* Bản tin tổng hợp được gửi mỗi 1-2 tuần, huỷ bất cứ lúc nào.
Author

Xin chào, tôi tên là Hoài - một anh Dev kể chuyện bằng cách viết ✍️ và làm sản phẩm 🚀. Với nhiều năm kinh nghiệm lập trình, tôi đã đóng góp một phần công sức cho nhiều sản phẩm mang lại giá trị cho người dùng tại nơi đang làm việc, cũng như cho chính bản thân. Sở thích của tôi là đọc, viết, nghiên cứu... Tôi tạo ra trang Blog này với sứ mệnh mang đến những bài viết chất lượng cho độc giả của 2coffee.dev.Hãy theo dõi tôi qua các kênh LinkedIn, Facebook, Instagram, Telegram.

Bạn thấy bài viết này có ích?
Không

Bình luận (0)

Nội dung bình luận...