Редактиране:Сега с актуализирания код смятам, че вашата методология е фундаментално погрешна, освен това, което докладвате.
Начинът, по който сте го внедрили, изисква да стартирате KEYS
в производството - това е лошо. Докато увеличавате мащаба, вие ще причинявате нарастващо и ненужно натоварване от блокиране на системата на сървъра. Както казва всяка част от документацията по него, не използвайте keys
в производството. Имайте предвид, че кодирането на времето на изтичане в името на ключа не ви дава полза. Ако направите тази част от името на ключа клеймо за време на създаване или дори произволно число, нищо няма да се промени. Всъщност, ако премахнете този бит, нищо няма да се промени.
Вместо това по-разумен маршрут би бил да се използва ключово име, което не зависи от времето. Използването на изтичане се справя с тази функция вместо вас. Позволете ни да наречем вашето нещо с ограничена скорост „сесия“. Вашето ключово име без времевата марка е "идентификаторът на сесията". Като зададете на него изтичане на 60s, той вече няма да бъде наличен при 61s. Така че можете безопасно да увеличавате и сравнявате резултата с вашия лимит, без да е необходимо да знаете текущото време или времето на изтичане. Всичко, от което се нуждаете, е статично име на ключ и подходящо изтичане, зададено върху него.
Ако INCR
несъществуващ ключ, Redis ще върне "1", което означава, че е създал ключа и го е увеличил с една стъпка/извикване. така че основно логиката е следната:
- създайте идентификатор на „сесия“
- брояч на увеличение с помощта на ID
- сравнете резултата с ограничението
- ако count ==1, задайте изтичане на 60 сек.
- id count> ограничение, отхвърляне
Стъпка 3.1 е важна. Брой 1 означава, че това е нов ключ в Redis и искате да зададете изтичането си върху него. Всичко друго означава, че срокът на валидност вече трябва да е зададен. Ако го зададете в 3.2, ще нарушите процеса, защото той ще запази брояча за повече от 60 секунди.
С това не е необходимо да имате динамични имена на ключове въз основа на времето на изтичане и следователно не е необходимо да използвате keys
за да разберете дали има съществуваща "сесия" за обекта с ограничена скорост. Освен това прави кода ви много по-опростен и предсказуем, както и намалява двупосочните пътувания до Redis – което означава, че ще бъде по-малко натоварване на Redis и ще работи по-добре. Относно това как да направите това с клиентската библиотека, която използвате, не мога да кажа, защото не съм толкова запознат с нея. Но основната последователност трябва да бъде преводима към нея, тъй като е доста проста и проста.
Това, което не сте показали обаче, е нещо в подкрепа на твърдението, че изтичането на срока не се случва. Всичко, което сте направили, е да покажете, че на Redis наистина е казано и да зададете изтичане. За да подкрепите твърдението си, трябва да покажете, че ключът не изтича. Което означава, че трябва да покажете извличане на ключа след изтичане на срока на валидност и че броячът не е бил "нулиран" чрез повторно създаване след изтичане. Един от начините да видите, че изтичането се случва, е да използвате известия за ключово пространство. С това ще можете да видите Redis да казва, че ключът е изтекъл.
Този процес ще се провали малко, ако направите няколко прозореца за ограничаване на скоростта или ако имате много по-голям прозорец (т.е. 10 минути), в който случай сортираните набори може да са по-разумна опция за предотвратяване на предното зареждане на заявките - по желание. Но както е написан вашият пример, горното ще работи добре.