Управление загрузкой с помощью PostgreSQL и pg_headerkit

от автора

Привет, Хабр!

Supabase – это крутой open-source аналог Firebase, с его помощью можно организовать крутые штуки вроде ограничения скорости запросов.

Supabase – это инструмент, который дает возможность создавать масштабируемые серверные решения, используя PostgreSQL. С его помощью можно легко управлять базами данных, аутентификацией, хранением данных и реальным временем, но без всяких vendor lock-ins.

Rate Limiting контролирует поток запросов, чтобы ваш сервер не ушел в нокаут от перегрузки. Это спасает сервера от DDOS-атакти помогает обеспечить более равномерное распределение ресурсов среди пользователей.

pg_headerkit

pg_headerkit – это расширение PostgreSQL, предназначенное для управления HTTP-заголовками прямо из вашей базы данных. Это расширение позволяет вам манипулировать HTTP-заголовками на уровне бдшки, что открывает широкие возможности для контроля и управления вашими API-запросами.

С pg_headerkit можно установить различные правила и логику для обработки входящих и исходящих HTTP-запросов. Например, вы можете настроить ограничение скорости на основе IP-адреса или API-ключа, а также управлять кэшированием или даже блокировать запросы, не соответствующие определенным критериям.

Для установки pg_headerkit потребуется иметь учетку supbase и установить dbdev на гитхабе.

Устанавливаем:

SELECT dbdev.install('burggraf-pg_headerkit'); CREATE EXTENSION "burggraf-pg_headerkit" VERSION '1.0.0';

Далее создадмим проект на официальном сайте Supabase.

Войдите в Supabase Dashboard. Откройте раздел SQL.

Запустим SQL-запрос для создания таблицы rate_limit:

CREATE TABLE rate_limit (     api_key VARCHAR(255) NOT NULL,     last_request_time TIMESTAMP NOT NULL DEFAULT now(),     request_count INTEGER NOT NULL DEFAULT 1 );

Реализация ограничения скорости запросов

Входим в нашу БД постгреса и создаем расширение pg_headerkit:

psql -U username -d database  CREATE EXTENSION pg_headerkit;

Создадим таблицу, которая будет использоваться для контроля скорости запросов:

CREATE TABLE rate_limit (     api_key VARCHAR(255) NOT NULL,     last_request_time TIMESTAMP NOT NULL DEFAULT now(),     request_count INTEGER NOT NULL DEFAULT 1 );

Напишем функцию, которая будет проверять и обновлять счетчик запросов:

CREATE OR REPLACE FUNCTION check_rate_limit() RETURNS TRIGGER AS $$ DECLARE     time_difference INTERVAL; BEGIN     -- Проверяем время с последнего запроса     SELECT now() - last_request_time INTO time_difference FROM rate_limit WHERE api_key = NEW.api_key;     IF time_difference > INTERVAL '1 minute' THEN         -- Сброс счетчика запросов после 1 минуты         UPDATE rate_limit SET request_count = 1, last_request_time = now() WHERE api_key = NEW.api_key;     ELSE         -- Увеличиваем счетчик запросов         UPDATE rate_limit SET request_count = request_count + 1 WHERE api_key = NEW.api_key;         IF (SELECT request_count FROM rate_limit WHERE api_key = NEW.api_key) > 10 THEN             -- Превышен лимит запросов             RAISE EXCEPTION 'Превышен лимит запросов';         END IF;     END IF;     RETURN NEW; END; $$ LANGUAGE plpgsql;

Cоздадим триггер, который будет вызывать нашу функцию при каждом запросе:

CREATE TRIGGER rate_limit_trigger BEFORE INSERT ON your_table FOR EACH ROW EXECUTE FUNCTION check_rate_limit();

Теперь каждый раз, когда кто-то пытается сделать запрос, наш триггер проверяет, не превышен ли лимит запросов, и если да, то выкидывает исключение.

Другие возможности

Можно настроить более гибкие ограничения скорости, которые будут меняться в зависимости от времени суток. Например, установить более жесткие ограничения в часы пик и более мягкие в нерабочее время:

CREATE OR REPLACE FUNCTION dynamic_rate_limit() RETURNS TRIGGER AS $$ DECLARE     current_hour INT; BEGIN     current_hour := EXTRACT(HOUR FROM now());      IF current_hour BETWEEN 8 AND 18 THEN         -- Жесткие ограничения в рабочее время     ELSE         -- Мягкие ограничения в нерабочее времни]     END IF;      RETURN NEW; END; $$ LANGUAGE plpgsql;  CREATE TRIGGER dynamic_rate_limit_trigger BEFORE INSERT ON your_table FOR EACH ROW EXECUTE FUNCTION dynamic_rate_limit();

Можно создать более сложную систему лимитов, которая будет учитывать, к примеру, разные уровни доступа пользователей или их группы:

CREATE OR REPLACE FUNCTION user_specific_rate_limit() RETURNS TRIGGER AS $$ DECLARE     user_role VARCHAR; BEGIN     SELECT role INTO user_role FROM users WHERE api_key = NEW.api_key;     IF user_role = 'premium' THEN         -- Высокие лимиты для премиум пользователей     ELSE         -- Стандартные лимиты для обычных пользователей     END IF;     -- [Остальная логика функции]     RETURN NEW; END; $$ LANGUAGE plpgsql;

Можно использовать pg_headerkit для добавления HTTP-заголовков в ответ, информирующих пользователя о текущем состоянии его лимитов:

CREATE OR REPLACE FUNCTION add_rate_limit_headers() RETURNS TRIGGER AS $$ DECLARE     remaining_requests INTEGER; BEGIN     SELECT (10 - request_count) INTO remaining_requests FROM rate_limit WHERE api_key = NEW.api_key;      PERFORM headerkit.add('X-RateLimit-Remaining', remaining_requests::TEXT);      RETURN NEW; END; $$ LANGUAGE plpgsql;

Если у вас есть список IP-адресов, с которых не должно быть доступа к вашему API, вы можете легко заблокировать их:

CREATE TABLE blocked_ips (     ip_address VARCHAR(15) );  INSERT INTO blocked_ips (ip_address) VALUES ('192.168.1.1');  CREATE OR REPLACE FUNCTION check_blocked_ips() RETURNS TRIGGER AS $$ BEGIN     IF EXISTS (SELECT 1 FROM blocked_ips WHERE ip_address = NEW.ip_address) THEN         RAISE EXCEPTION 'Доступ запрещен с вашего IP-адреса';     END IF;      RETURN NEW; END; $$ LANGUAGE plpgsql;  CREATE TRIGGER ip_block_trigger BEFORE INSERT ON your_requests_table FOR EACH ROW EXECUTE FUNCTION check_blocked_ips();

pg_headerkit только улучшит производительность баз данных за счет более гибкого и точного управления загрузкой, и обеспечивает возможность более тонкой настройки процессов в соответствии с потребностями конкретной системы.

Больше практических инструментов и навыков эксперты отрасли показывают в рамках онлайн-курса PostgreSQL для администраторов баз данных и разработчиков. Присоединяйтесь.


ссылка на оригинал статьи https://habr.com/ru/articles/785290/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *