Lua 流控工具说明
Если вы обнаружите дефекты или у вас есть предложения по улучшению, пожалуйста, свяжитесь со мной: mahaixing@gmail.com.
Файл описания
limiters
restry
limit_conf.lua.sample
limit.lua
nginx.conf.test
test*.lua
utils.lua
Идея скрипта ограничения основана на цепочке правил. После того как запрос пользователя поступает в nginx, он переходит в цепочку правил ограничения, определённую в скрипте ограничения. В цепочке правил каждый элемент обрабатывается по очереди. Если какое-либо правило ограничения соответствует запросу, цепочка прерывается и выполняется цикл, возвращая информацию об ограничении. Исключение составляют случаи, когда в правиле явно указано, что необходимо обратиться к следующему правилу в цепочке.
Необходимо написать скрипт ограничения, например (some_business_limit.lua
):
local conf = {
redis = {...}
some_limit_rule_1 = {...}
some_limit_rule_2 = {...}
}
-- Если не передаётся conf, то будет выполнен поиск в package.path
-- файла limit_conf.lua
local limit = require "limit":new(conf)
funciton some_who_1(limit)
return true, "some_limit_rule_1"
end
function some_who_2(limit)
local redis = limit:get_redis()
-- some_redis_operation
-- target find
if is_target then
return true, "some_limit_rule_2"
else
return false
end
end
function some_message(limit, data)
-- вернуть страницу
limit.send_redirect("limit.html")
-- вернуть json
limit.send_redirect("xxx.html", data)
end
limit:who({some_who_1, some_who_2}):execute()
В блоке http nginx путь поиска Lua-интерпретатора задаётся в package.path
, чтобы найти файл сценария. В разделе location, где требуется ограничение, добавьте access_by_lua_file
, чтобы указать файл сценария Lua (конечно, вы также можете использовать content_by_lua
). Например:
http {
lua_package_path "/some_place/limit/limit-common/?.lua;;";
server {
location /some_url {
access_by_lua_file /some_place/some_business_limit.lua;
}
}
```
## 3. Файл конфигурации
Файл конфигурации используется для настройки redis и цепочки правил ограничения. См. пример файла `limit_conf.lua`. Здесь:
1. Раздел redis имеет фиксированное имя, не рекомендуется изменять имя и структуру.
2. `default_rule` — это цепочка правил по умолчанию. Она будет использоваться, если не указана функция `who`. Если функция `who` указана, эту цепочку можно не настраивать.
3. `xxx_rule` — настраиваемая цепочка правил.
4. Каждый атрибут в цепочке правил должен соответствовать имени файла (без расширения .lua) в каталоге `limiters/xxx.lua`.
### 3.1 bucket
Файл `limiters/bucket.lua` использует токен для ограничения потока. Параметры конфигурации:
* В файле конфигурации nginx необходимо настроить общий dict, например:
```
http {
lua_shared_dict my_limit_conn_store 100m;
server {
location / {
...
}
```
* `bucket_dict_name`
Общий dict, строка, должен совпадать с файлом конфигурации nginx.
* `bucket_rate`
Ограничение скорости запроса, число, например, 200 означает 200 запросов в секунду.
* `bucket_burst = 0,`
Разрешённая скорость всплеска, число, например 100 означает, что разрешена скорость всплеска 100 в дополнение к скорости 200 запросов в секунду.
* `bucket_target = ”ip“`
Целевой объект ограничения, строка, может быть настроена только на ip или uri.
*ip:* представляет клиентский IP-адрес.
*uri:* представляет адрес запроса.
### 3.2 cookie
Файл `limiters/cookie.lua`, основанный на ограничении потока cookie, параметры конфигурации:
* `cookie_domain` домен cookie, строка, например «example.com».
* `cookie_path` путь, строка, например "/".
* `cookie_key` ключ cookie, строка, например "example_limit".
* `cookie__value` значение cookie, строка, например "1".
### 3.3 date_range
Файл `limiter/date_range.lua`, основанный на временном диапазоне ограничения потока, параметры конфигурации:
* `start_datetime`
Время начала, формат таблицы, например {year=2018, month=03, day=30, hour=0, min=0, sec=0}.
* `end_datetime` время окончания, формат таблицы, например {year=2018, month=04, day=30, hour=0, min=0, sec=0}.
* `week_day` конкретная неделя, может быть таблицей, такой как {3,4,5}, или целым числом, таким как 1 (представляющим понедельник), но независимо от того, является ли она таблицей или целым числом, значение должно быть между 1 и 7.
### 3.4 limiter
Файл `limiters/limiter`, без условий ограничения потока, все целевые запросы ограничены, без параметров конфигурации, просто используйте пустую таблицу, например:
default_rule = {
limiter = {}
}
### 4. Ключевые функции
### 4.1 Целевой объект ограничения, функция who
В конфигурации location блока nginx ограничение применяется к URL. Однако конкретный целевой объект ограничения различается в зависимости от приложения, и необходимо определить целевой объект ограничения на основе параметров. Например:
1. Некоторые бизнес-ограничения являются базовым соответствием одному и тому же URL, но могут соответствовать целевому объекту ограничения на основе параметра запроса.
2. Некоторые из них основаны на пользователе, сохранённом в redis, а затем соответствуют целевому клиенту запроса.
3. Некоторые основаны на чёрном и белом списках, сохранённых в redis.
Поэтому в сценарии ограничения необходимо реализовать функцию who для конкретного бизнеса, которая используется для определения того, является ли текущий запрос объектом ограничения.
Например, на основе URL-адреса (или cookie) найдите чёрный список в redis.
Например, на основе URL-адреса (или cookie), найдите, принадлежит ли он ограниченному адресу в redis.
Например, на основе URL-адреса (или cookie), определите, относится ли он к конкретному бизнесу.
Прототип функции who:
function some_who_func(limit)
Возвращаемое значение не более 2, возвращающее true должно возвращать как минимум два значения, возвращаемое значение указывает:
1. логическое значение, является ли запрос объектом ограничения;
2. таблица содержит следующие данные:
1. rule: имя правила, применимого к этому объекту. **Например:** «xxx_rule», если равно nil, то используется имя правила по умолчанию «default_rule».
2. message: функция типа, применимая к возвращаемой функции message для данной цели.
Если равно nil, используется функция message по умолчанию `default_message`, см. `limit.lua`.
3. data: тип table, опционально, данные, которые необходимо передать в обработку функции message.
Может быть равно nil, что означает отсутствие данных, требующих обработки функцией message.
Функция who может быть задана несколько раз и передана в limit как таблица, например:
limit:who({who_func1, who_func2, who_func3})
Также может быть только одна функция, например:
limit:who(who_func_single)
После того как функция who найдёт цель, скрипт прекратит вызывать последующие функции who. Функция who, нашедшая цель, должна возвращать true, а также цепочку ограничения потока, применяемую к цели, функцию message, которая будет применяться, и дополнительные данные, которые должны быть переданы. Если функция who возвращает false, сценарий ограничения потока вызовет следующую функцию who для поиска.
Если функция who не настроена, limit будет использовать функцию who по умолчанию, возвращая правило по умолчанию `defualt_rule` и сообщение по умолчанию `default_message`.
### 4.2 Функция message
Функция message используется для возврата данных ответа браузеру после запроса на ограничение потока. Прототип функции message выглядит следующим образом:
function some_message(limit, data)
Где:
1. limit — это класс управления, который можно получить из класса limit или информации о конфигурации, а также информации о параметрах запроса (параметры, передаваемые через GET и POST), см. `limit.lua`;
2. data — это данные, возвращаемые соответствующей функцией who, используются при необходимости.
В функции message можно выводить mime-заголовок и другие заголовки HTTP в соответствии с бизнес-требованиями.
Можно вернуть данные в формате JSON, XML или другом формате.
Можно просто перейти на указанную страницу.
*Можно указать функцию message для каждого объекта ограничения потока, см. описание функции who.*
## 5. Расширение
Если есть новое правило ограничения потока, можно расширить этот скрипт. Создайте новый файл правил `some_new_rule.lua` в каталоге `limiters`. Файл должен соответствовать следующему шаблону:
local assert = assert local utils = require "utils"
local _M = require("limiters.limiter"):new()
function _M:process_config()
end
function _M:execute()
-- Если текущий запрос не нужно ограничивать
return false
-- Если текущий запрос ограничен, нет необходимости ссылаться на следующее правило
return true, false
-- Если текущий запрос ограничен, необходимо ссылаться на следующее правило
return true, true
end
return _M
Вы можете оставить комментарий после Вход в систему
Неприемлемый контент может быть отображен здесь и не будет показан на странице. Вы можете проверить и изменить его с помощью соответствующей функции редактирования.
Если вы подтверждаете, что содержание не содержит непристойной лексики/перенаправления на рекламу/насилия/вульгарной порнографии/нарушений/пиратства/ложного/незначительного или незаконного контента, связанного с национальными законами и предписаниями, вы можете нажать «Отправить» для подачи апелляции, и мы обработаем ее как можно скорее.
Опубликовать ( 0 )