Расширенные расширенные функции Openresty и ограничение тока
Расширенные расширенные функции Openresty и ограничение тока

Openresty можно использовать с lua-скриптами на базе Nginx для достижения более продвинутых функций, таких как Ограничение тока、кэш、Незаконный перехват URI и другие функции.

Ограничение тока

Ограничения движения в основном включают ограничение частоты и Ограничение тока:

  • Ограничение частоты,Ограничить количество звонков в единицу времени,сосредоточиться скорость звонка
  • Ограничение тока, ограничьте количество звонков во временном окне, сосредоточьтесь на Общее количество звонков

Ограничение ток делится на Ограничение по объему запроса токаи количество подключений Ограничение тока, можно настроить в nginx.conf. Сам Nginx поставляется с Ограничением. функции тока, Openresty также реализует гибкое Ограничение Функция тока.

NginxОграничение токмодуль

limit_req_zone да Nginx Один из модулей, используемых для реализации запроса Ограничение Функция тока. это да Nginx Поставляется с функциями, не зависит от OpenResty。

По умолчанию Нгинкс использовать "leaky Алгоритм "ведро" (дырявое ведро) для выполнения запросов Ограничение тока。

Алгоритм дырявого ведра даA классический запрос Ограничение алгоритм тока,В его основе лежит структура данных, похожая на дырявое ведро. Запросы попадают в «дырявое ведро» с фиксированной скоростью.,Если дырявое ведро полное,Запрос отклоняется или задерживается. Этот алгоритм плавно ограничивает скорость запросов,Предотвратите перегрузку сервера.

Можетиспользовать limit_req_zone Директива для определения запроса площадь Тока,ииспользовать limit_req Инструкция по применению Ограничения тока Стратегия。

Простой пример выглядит следующим образом:

Язык кода:lua
копировать
worker_processes  1;
error_log logs/error.log;
events {
    worker_connections 1024;
}
http {
    limit_req_zone $binary_remote_addr zone=perip:10m rate=10r/s;
    server {
        listen 8080;
        location / {
            limit_req zone=perip burst=5;
            default_type text/html;
            content_by_lua_block {
                ngx.say("<p>hello, world</p>")
            }
        }
    }
}

вышеlimit_req_zone Определена область хранения с именем perip размером 10 МБ, используемая для хранения статуса запроса каждого IP-адреса. Переменная $binary_remote_addr представляет IP-адрес клиента. скорость=100р/м означает, что каждый IP может отправлять только 100 запросов в минуту.

Язык кода:lua
копировать
limit_req_zone $binary_remote_addr zone=perip:10m rate=10r/s;

limit_req Конфигурация применена вышеlimit_req_zone Определенные пределы. Zone=perip указывает, какую область хранения использовать.,всплеск=5 означает, что запросы за короткий период времени могут превысить лимит,Максимум более 5. Если эта сумма превышена,Тогда лишние запросы будут задерживаться.,Пока частота запросов не упадет ниже лимита. Если установить параметр nodelay,Тогда запросы, превышающие количество пакетов, будут напрямую отклонены.

Язык кода:javascript
копировать
limit_req zone=perip burst=5;

Конечно, вы также можете обратиться к указанному выше номеру запроса. Ограничение. ток способ установки количества подключений Ограничение тока。

Язык кода:javascript
копировать
limit_conn_zone $binary_remote_addr zone=concurrent:10m;

limit_conn concurrent 5;

OpenrestyОграничение токмодуль

Несколько расширений Lua, официально предоставленных OpenResty:

  • resty.limit.req, используется для ограничения количества запросов в единицу времени (секунды).
  • resty.limit.conn, используется для ограничения количества одновременных подключений.
  • resty.limit.count, используется для ограничения количества запросов в пределах временного окна, временное окно можно настроить.
  • resty.limit.traffic, используемый для объединения трех факторов для достижения более богатой стратегии ограничения.

Реализация логики в Openresty использует скрипт lua.,существоватьlocation中Можетиспользоватьaccess_by_lua_block Блоки кода для реализации логики,Вы также можете разделить логику на другие файлы.,тогда пройдиaccess_by_lua_file xxx.lua Просто процитируйте.

Ограничить количество запросов в пределах временного окна

Вот пример ограничения тока, который можно запрашивать только 100 раз каждые 60 секунд:

Язык кода:lua
копировать
worker_processes  1;
error_log logs/error.log info;   
events {
    worker_connections 1024;
}
http {
    # Объявить объект хеш-кэша
    lua_shared_dict limit_count_store 100m;

    server {
        location / {
            access_by_lua_block {
                -- Запрос на введение токмодуль
                local limit_count = require "resty.limit.count"
                
                -- Его можно вызвать только 100 раз в течение 60 секунд, а статистика сохранится в кеш.
                local lim, err = limit_count.new("limit_count_store", 100, 60)
                if not lim then
                    ngx.log(ngx.ERR, "failed to instantiate a resty.limit.count object: ", err)
                    return ngx.exit(500)
                end
                
                -- Используйте IP-адрес клиента в качестве ключа для подсчета количества запросов.
                local key = ngx.var.binary_remote_addr
                
                local delay, err = lim:incoming(key, true)
                -- Если количество запросов находится в пределах лимита, задержка для обработки текущего запроса и оставшегося количества запросов для обработки, задержка возвращает 0, err возвращает оставшееся число
                -- Если запрос отклонен, задержка возвращает ноль, ошибка возвращает отклонено
                ngx.log(ngx.INFO, "Запросить оставшийся номер:", err);
                if not delay then
                    if err == "rejected" then
                        return ngx.exit(503)
                    end
                    ngx.log(ngx.ERR, "failed to limit count: ", err)
                    return ngx.exit(500)
                end
            }   

            default_type text/html;
            content_by_lua_block {
                ngx.say("<p>hello, world</p>")
            }
        }
    }
}

Ограничить количество одновременных подключений для IP-адреса.

нижедаограничить каждыйклиент Макс1одновременные запросы。

Язык кода:lua
копировать
worker_processes  1;
error_log logs/error.log info;   
events {
    worker_connections 1024;
}
http {
    # Объявить объект хеш-кэша
    lua_shared_dict limit_count_store 100m;

    server {
        location / {
            access_by_lua_block {
               local limit_conn = require "resty.limit.conn"
               -- Ограничьте один ip клиент Макс 1 одновременные запросы
               -- burst установлен на 0. Если максимальное количество одновременных запросов превышено, будет возвращено 503.
               -- Если вы хотите разрешить внезапное увеличение параллелизма, вы можете изменить это. burst Значение (емкости дырявого ведра)
               -- Последний параметр фактически означает, что вам необходимо оценить, сколько времени займет обработка этих одновременных (или отдельных запросов), чтобы вы могли применить алгоритм дырявого ведра к запросам в ведре.
               -- Если установлено локальное lim, err = limit_conn.new("limit_conn_store", 50, 25, 0.5)
               -- Это значит, что лимит 50одновременные. запросы,и 25 дополнительных одновременных пакетных запросов,  То есть один клиент обращается к 50 +25 503 будет выброшено после
               local lim, err = limit_conn.new("limit_conn_store", 1, 0, 0.5)              
               if not lim then
                   ngx.log(ngx.ERR, "failed to instantiate a resty.limit.conn object: ", err)
                   return ngx.exit(500)
               endlocal key = ngx.var.binary_remote_addr
               -- commit это правда Указывает на необходимость обновления общего Значение ключа в dict,-- false Это означает, что вы можете просмотреть только задержку обработки текущего запроса и количество предыдущих запросов, которые еще не были обработаны. delay, err = lim:incoming(key, true)
               if not delay thenif err == "rejected" thenreturn ngx.exit(503)
                   end
                   ngx.log(ngx.ERR, "failed to limit req: ", err)
                   return ngx.exit(500)
               end-- Если такая информация, как количество запросов на подключение, добавляется в общий dict, затем запишите его в ctx, -- Потому что нам нужно сообщить вам, что соединение будет отключено позже для обработки других соединений, если lim:is_committed() thenlocal ctx = ngx.ctx
                   ctx.limit_conn = lim
                   ctx.limit_conn_key = key
                   ctx.limit_conn_delay = delay
               endlocal conn = err
               -- На самом деле здесь delay Оно должно быть целым числом, кратным времени одновременной обработки, упомянутому выше, -- Например, если в секунду обрабатывается 100 одновременных вызовов, а емкость корзины равна 200, то при одновременном поступлении 500 одновременных вызовов 200 будут отклонены. 100 обрабатываются, а затем 200 временно сохраняются в корзине. Среди 200 временно сохраненных соединений 0–100 соединений фактически должны быть задержаны на 0,5 секунды, -- 101-200 должны быть задержаны на 0,5*2=1 секунду (0,5да расчетного времени одновременной обработки, указанного выше) -- ngx.say("delay: ", delay)if delay >= 0.001 then-- ngx.sleep(delay)end
            }

            log_by_lua_block {
               local ctx = ngx.ctx
               local lim = ctx.limit_conn
               if lim thenlocal key = ctx.limit_conn_key
                   -- После того, как это соединение будет обработано, вы должны сообщить нам и обновить общий доступ. Значение в dict позволяет получать доступ к последующим соединениям для обработки: Здесь вы можете динамически обновлять предыдущее расчетное время, но не забудьте написать метод limit_conn.new, -- В противном случае local будет сбрасываться каждый раз при поступлении запроса. conn, err = lim:leaving(key, 0.5)
                   if not conn then
                       ngx.log(ngx.ERR,
                               "failed to record the connection leaving ",
                               "request: ", err)
                       returnendend
            }

            default_type text/html;
            content_by_lua_block {
                ngx.say("<p>hello, world</p>")
            }
        }
    }
}

Другие Ограничение частотыи Ограничение Метод тока также является аналогичным методом обработки.

boy illustration
Учебное пособие по Jetpack Compose для начинающих, базовые элементы управления и макет
boy illustration
Код js веб-страницы, фон частицы, код спецэффектов
boy illustration
【новый! Суперподробное】Полное руководство по свойствам компонентов Figma.
boy illustration
🎉Обязательно к прочтению новичкам: полное руководство по написанию мини-программ WeChat с использованием программного обеспечения Cursor.
boy illustration
[Забавный проект Docker] VoceChat — еще одно приложение для мгновенного чата (IM)! Может быть встроен в любую веб-страницу!
boy illustration
Как реализовать переход по странице в HTML (html переходит на указанную страницу)
boy illustration
Как решить проблему зависания и низкой скорости при установке зависимостей с помощью npm. Существуют ли доступные источники npm, которые могут решить эту проблему?
boy illustration
Серия From Zero to Fun: Uni-App WeChat Payment Practice WeChat авторизует вход в систему и украшает страницу заказа, создает интерфейс заказа и инициирует запрос заказа
boy illustration
Серия uni-app: uni.navigateЧтобы передать скачок значения
boy illustration
Апплет WeChat настраивает верхнюю панель навигации и адаптируется к различным моделям.
boy illustration
JS-время конвертации
boy illustration
Обеспечьте бесперебойную работу ChromeDriver 125: советы по решению проблемы chromedriver.exe не найдены
boy illustration
Поле комментария, щелчок мышью, специальные эффекты, js-код
boy illustration
Объект массива перемещения объекта JS
boy illustration
Как открыть разрешение на позиционирование апплета WeChat_Как использовать WeChat для определения местонахождения друзей
boy illustration
Я даю вам два набора из 18 простых в использовании фонов холста Power BI, так что вам больше не придется возиться с цветами!
boy illustration
Получить текущее время в js_Как динамически отображать дату и время в js
boy illustration
Вам необходимо изучить сочетания клавиш vsCode для форматирования и организации кода, чтобы вам больше не приходилось настраивать формат вручную.
boy illustration
У ChatGPT большое обновление. Всего за 45 минут пресс-конференция показывает, что OpenAI сделал еще один шаг вперед.
boy illustration
Copilot облачной разработки — упрощение разработки
boy illustration
Микросборка xChatGPT с низким кодом, создание апплета чат-бота с искусственным интеллектом за пять шагов
boy illustration
CUDA Out of Memory: идеальное решение проблемы нехватки памяти CUDA
boy illustration
Анализ кластеризации отдельных ячеек, который должен освоить каждый&MarkerгенетическийВизуализация
boy illustration
vLLM: мощный инструмент для ускорения вывода ИИ
boy illustration
CodeGeeX: мощный инструмент генерации кода искусственного интеллекта, который можно использовать бесплатно в дополнение к второму пилоту.
boy illustration
Машинное обучение Реальный бой LightGBM + настройка параметров случайного поиска: точность 96,67%
boy illustration
Бесшовная интеграция, мгновенный интеллект [1]: платформа больших моделей Dify-LLM, интеграция без кодирования и встраивание в сторонние системы, более 42 тысяч звезд, чтобы стать свидетелями эксклюзивных интеллектуальных решений.
boy illustration
LM Studio для создания локальных больших моделей
boy illustration
Как определить количество слоев и нейронов скрытых слоев нейронной сети?
boy illustration
[Отслеживание целей] Подробное объяснение ByteTrack и детали кода