Расширенные расширенные функции 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
Неразрушающее увеличение изображений одним щелчком мыши, чтобы сделать их более четкими артефактами искусственного интеллекта, включая руководства по установке и использованию.
boy illustration
Копикодер: этот инструмент отлично работает с Cursor, Bolt и V0! Предоставьте более качественные подсказки для разработки интерфейса (создание навигационного веб-сайта с использованием искусственного интеллекта).
boy illustration
Новый бесплатный RooCline превосходит Cline v3.1? ! Быстрее, умнее и лучше вилка Cline! (Независимое программирование AI, порог 0)
boy illustration
Разработав более 10 проектов с помощью Cursor, я собрал 10 примеров и 60 подсказок.
boy illustration
Я потратил 72 часа на изучение курсорных агентов, и вот неоспоримые факты, которыми я должен поделиться!
boy illustration
Идеальная интеграция Cursor и DeepSeek API
boy illustration
DeepSeek V3 снижает затраты на обучение больших моделей
boy illustration
Артефакт, увеличивающий количество очков: на основе улучшения характеристик препятствия малым целям Yolov8 (SEAM, MultiSEAM).
boy illustration
DeepSeek V3 раскручивался уже три дня. Сегодня я попробовал самопровозглашенную модель «ChatGPT».
boy illustration
Open Devin — инженер-программист искусственного интеллекта с открытым исходным кодом, который меньше программирует и больше создает.
boy illustration
Эксклюзивное оригинальное улучшение YOLOv8: собственная разработка SPPF | SPPF сочетается с воспринимаемой большой сверткой ядра UniRepLK, а свертка с большим ядром + без расширения улучшает восприимчивое поле
boy illustration
Популярное и подробное объяснение DeepSeek-V3: от его появления до преимуществ и сравнения с GPT-4o.
boy illustration
9 основных словесных инструкций по доработке академических работ с помощью ChatGPT, эффективных и практичных, которые стоит собрать
boy illustration
Вызовите deepseek в vscode для реализации программирования с помощью искусственного интеллекта.
boy illustration
Познакомьтесь с принципами сверточных нейронных сетей (CNN) в одной статье (суперподробно)
boy illustration
50,3 тыс. звезд! Immich: автономное решение для резервного копирования фотографий и видео, которое экономит деньги и избавляет от беспокойства.
boy illustration
Cloud Native|Практика: установка Dashbaord для K8s, графика неплохая
boy illustration
Краткий обзор статьи — использование синтетических данных при обучении больших моделей и оптимизации производительности
boy illustration
MiniPerplx: новая поисковая система искусственного интеллекта с открытым исходным кодом, спонсируемая xAI и Vercel.
boy illustration
Конструкция сервиса Synology Drive сочетает проникновение в интрасеть и синхронизацию папок заметок Obsidian в облаке.
boy illustration
Центр конфигурации————Накос
boy illustration
Начинаем с нуля при разработке в облаке Copilot: начать разработку с минимальным использованием кода стало проще
boy illustration
[Серия Docker] Docker создает мультиплатформенные образы: практика архитектуры Arm64
boy illustration
Обновление новых возможностей coze | Я использовал coze для создания апплета помощника по исправлению домашних заданий по математике
boy illustration
Советы по развертыванию Nginx: практическое создание статических веб-сайтов на облачных серверах
boy illustration
Feiniu fnos использует Docker для развертывания личного блокнота Notepad
boy illustration
Сверточная нейронная сеть VGG реализует классификацию изображений Cifar10 — практический опыт Pytorch
boy illustration
Начало работы с EdgeonePages — новым недорогим решением для хостинга веб-сайтов
boy illustration
[Зона легкого облачного игрового сервера] Управление игровыми архивами
boy illustration
Развертывание SpringCloud-проекта на базе Docker и Docker-Compose