Chỉnh sửa:Bây giờ với mã được cập nhật, tôi tin rằng phương pháp luận của bạn về cơ bản còn thiếu sót ngoài những gì bạn đang báo cáo.
Theo cách bạn đã triển khai nó, bạn yêu cầu chạy KEYS
trong sản xuất - điều này thật tệ. Khi bạn mở rộng quy mô, bạn sẽ gây ra tải trọng chặn hệ thống ngày càng tăng và không cần thiết trên máy chủ. Như mọi tài liệu về nó đều nói, không sử dụng các khóa keys
trong sản xuất. Lưu ý rằng việc mã hóa thời gian hết hạn trong tên khóa không mang lại lợi ích gì cho bạn. Nếu bạn đặt phần đó của tên khóa làm dấu thời gian tạo, hoặc thậm chí là một số ngẫu nhiên thì sẽ không có gì thay đổi. Thật vậy, nếu bạn loại bỏ bit đó, sẽ không có gì thay đổi.
Thay vào đó, một lộ trình lành mạnh hơn sẽ là sử dụng tên khóa không phụ thuộc vào thời gian. Việc sử dụng hết hạn sẽ xử lý chức năng đó cho bạn. Hãy để chúng tôi gọi điều giới hạn tỷ lệ của bạn là "phiên". Tên khóa của bạn không có dấu thời gian là "ID phiên". Bằng cách đặt thời hạn 60 giây cho nó, nó sẽ không còn khả dụng ở mốc 61 giây nữa. Vì vậy, bạn có thể gia tăng một cách an toàn và so sánh kết quả với giới hạn của bạn mà không cần biết thời gian hiện tại hoặc thời gian hết hạn. Tất cả những gì bạn cần là tên khóa tĩnh và thời hạn thích hợp được đặt trên đó.
Nếu bạn INCR
một khóa không tồn tại, Redis sẽ trả về "1" nghĩa là nó đã tạo khóa và tăng nó lên trong một bước / lệnh gọi. về cơ bản logic diễn ra như thế này:
- tạo ID "phiên"
- bộ đếm gia tăng sử dụng ID
- so sánh kết quả với giới hạn
- nếu đếm ==1, hãy đặt thời hạn thành 60 giây
- số lượng id> giới hạn, từ chối
Bước 3.1 là quan trọng. Số 1 có nghĩa là đây là khóa mới trong Redis và bạn muốn đặt thời hạn của mình trên đó. Bất kỳ điều gì khác có nghĩa là thời hạn đã được đặt sẵn. Nếu bạn đặt nó ở 3.2, bạn sẽ phá vỡ quá trình vì nó sẽ bảo quản bộ đếm trong hơn 60 giây.
Với điều này, bạn không cần phải có các tên khóa động dựa trên thời gian hết hạn và do đó không cần sử dụng các khóa keys
để tìm hiểu xem có "phiên" hiện tại cho đối tượng giới hạn tỷ lệ hay không. Nó cũng làm cho mã của bạn đơn giản và dễ dự đoán hơn nhiều, cũng như giảm các chuyến đi khứ hồi đến Redis - có nghĩa là nó sẽ tải xuống Redis thấp hơn và hoạt động tốt hơn. Về cách thực hiện điều đó với thư viện máy khách mà bạn đang sử dụng, tôi không thể nói vì tôi không quen thuộc với nó. Nhưng trình tự cơ bản nên được dịch sang nó vì nó khá cơ bản và đơn giản.
Tuy nhiên, những gì bạn chưa hiển thị là bất cứ điều gì để hỗ trợ khẳng định rằng việc hết hạn sẽ không xảy ra. Tất cả những gì bạn đã làm là cho thấy rằng Redis thực sự đang được yêu cầu và thiết lập thời hạn. Để hỗ trợ yêu cầu của bạn, bạn cần chứng minh rằng khóa không hết hạn. Có nghĩa là bạn cần hiển thị việc truy xuất khóa sau thời gian hết hạn và bộ đếm không được "đặt lại" bằng cách được tạo lại sau khi hết hạn. Một cách bạn có thể biết thời gian hết hạn đang diễn ra là sử dụng thông báo không gian phím. Với điều đó, bạn sẽ có thể thấy Redis nói rằng một khóa đã hết hạn.
Trường hợp quá trình này sẽ không thành công một chút là nếu bạn thực hiện nhiều cửa sổ để giới hạn tốc độ hoặc nếu bạn có một cửa sổ lớn hơn nhiều (ví dụ:10 phút), trong trường hợp đó, các bộ được sắp xếp có thể là một tùy chọn lành mạnh hơn để ngăn tải trước các yêu cầu - nếu muốn. Nhưng như ví dụ của bạn đã viết, ở trên sẽ hoạt động tốt.