ORM система
## Теоретическая документация ORM системы
### Введение в высокопроизводительную ORM архитектуру
Данная ORM система представляет собой промышленное решение для работы с распределенными базами данных PostgreSQL. Она спроектирована для работы в высоконагруженных production-средах, где требуются гарантированная производительность, отказоустойчивость и безопасность. Архитектура системы основана на микросервисных принципах, где каждый компонент отвечает за конкретную задачу и может масштабироваться независимо.
Основная философия системы заключается в предоставлении типобезопасного интерфейса для работы с базой данных, который предотвращает распространенные ошибки на этапе компиляции, а не во время выполнения. Система автоматически генерирует оптимальные SQL-запросы, управляет пулами соединений, кэширует результаты и обеспечивает безопасность данных.
### Принципы проектирования
Система построена на нескольких ключевых принципах. Принцип единственной ответственности гарантирует, что каждый модуль отвечает только за одну конкретную задачу. Например, модуль построения запросов не занимается безопасностью, а модуль безопасности не управляет соединениями. Это упрощает тестирование, отладку и развитие системы.
Принцип типобезопасности реализуется через строгую систему типов Rust. Все параметры запросов проходят валидацию типов на этапе компиляции, что исключает целый класс ошибок, связанных с несоответствием типов данных. Генераторы запросов используют дженерики для обеспечения правильного построения SQL в зависимости от структуры данных.
Принцип производительности воплощается через многоуровневое кэширование, пакетную обработку запросов и интеллектуальное управление соединениями. Система автоматически определяет, когда использовать реплики для чтения, когда повышать таймауты, и как распределять нагрузку между узлами базы данных.
### Архитектура системы
Архитектурно система разделена на несколько логических слоев. Слой доступа к данным отвечает за физическое подключение к базе данных, управление пулами соединений и выполнение SQL-запросов. Он включает в себя менеджер соединений, который создает и поддерживает несколько типов пулов для разных видов операций.
Слой построения запросов предоставляет типобезопасный API для генерации SQL. Этот слой абстрагирует разработчика от конкретного диалекта SQL и обеспечивает безопасное построение даже сложных запросов с JOIN, подзапросами и агрегатными функциями. Все параметры автоматически экранируются для предотвращения SQL-инъекций.
Слой безопасности реализует многоуровневую защиту. Он включает в себя валидацию входных данных, детектирование SQL-инъекций, ограничение частоты запросов и блокировку подозрительных IP-адресов. Безопасность применяется на нескольких уровнях: на уровне отдельных запросов, на уровне сессий и на уровне всей системы.
Слой кэширования использует двухуровневую архитектуру. Первый уровень — быстрый in-memory LRU кэш для часто запрашиваемых данных. Второй уровень — распределенный кэш на основе конкурентных хэш-таблиц. Оба уровня поддерживают TTL (время жизни записей) и автоматическую инвалидацию устаревших данных.
Слой мониторинга собирает метрики производительности в реальном времени. Он отслеживает количество запросов, время отклика, использование соединений, hit-ratio кэша и другие ключевые показатели. На основе этих метрик система может автоматически масштабироваться и адаптироваться к изменяющейся нагрузке.
### Система типов и безопасность
Система использует строгую типизацию для всех операций с базой данных. Тип QueryParameter представляет параметры запроса и обеспечивает их безопасную передачу в SQL. Для каждого типа данных предусмотрена соответствующая валидация: строки проверяются на максимальную длину, числа — на допустимые диапазоны, даты — на корректность формата.
Условия запросов представлены типом Condition, который поддерживает все стандартные SQL-операторы сравнения. Условия могут комбинироваться через AND и OR, группироваться в скобках и включать подзапросы. Каждое условие проходит валидацию перед построением SQL, что предотвращает синтаксические ошибки.
Безопасность реализована на нескольких уровнях. На уровне параметров все значения автоматически экранируются. На уровне запросов анализируется структура SQL на наличие потенциально опасных конструкций. На уровне системы отслеживается частота запросов с каждого IP-адреса и блокируются подозрительные паттерны поведения.
### Управление соединениями и производительность
Менеджер соединений использует несколько пулов для разных типов операций. Primary pool предназначен для критически важных операций записи и гарантирует минимальное количество активных соединений. Read pool оптимизирован для операций чтения и может масштабироваться в зависимости от нагрузки. Write pool специализируется на операциях модификации данных и использует увеличенные таймауты.
Для распределенных баз данных система поддерживает работу с репликами. Запросы на чтение автоматически распределяются между доступными репликами с использованием различных стратегий балансировки: round-robin, least connections или latency-based. Система постоянно мониторит задержку реплик и исключает из ротации те, что отстают слишком сильно.
Пакетная обработка запросов позволяет объединять несколько операций в одну транзакцию, что значительно повышает производительность при массовых вставках или обновлениях. Batch processor автоматически определяет оптимальный размер пакета и время его отправки, балансируя между задержкой и пропускной способностью.
### Система кэширования
Двухуровневая система кэширования предназначена для ускорения доступа к часто запрашиваемым данным. L1 кэш использует алгоритм LRU (Least Recently Used) и хранится в оперативной памяти. Он идеален для данных, к которым обращаются многократно в течение короткого промежутка времени.
L2 кэш построен на основе конкурентных хэш-таблиц и может распределяться между несколькими экземплярами приложения. Он служит для хранения данных, которые используются реже, но всё равно требуют быстрого доступа. Оба уровня кэша поддерживают TTL, что гарантирует актуальность данных.
Для запросов с параметрами используется хеширование: SQL-запрос и его параметры преобразуются в уникальный ключ, по которому происходит поиск в кэше. Это позволяет эффективно кэшировать даже параметризованные запросы с разными значениями параметров.
### Мониторинг и масштабирование
Система собирает детальную статистику по всем аспектам работы. Metrics collector отслеживает количество запросов, процент успешных операций, среднее время отклика, количество активных соединений и эффективность кэширования. Эти данные используются для анализа производительности и выявления узких мест.
Performance monitor предоставляет метрики в реальном времени через broadcast-каналы. Это позволяет внешним системам мониторинга получать данные без опроса. Система поддерживает различные форматы экспорта метрик, включая JSON и Prometheus-совместимый формат.
Auto scaler анализирует метрики нагрузки и автоматически принимает решения о масштабировании. При увеличении нагрузки система может увеличивать количество соединений в пулах или добавлять реплики для чтения. При снижении нагрузки происходит обратный процесс для экономии ресурсов.
Alert system отслеживает критические метрики и генерирует предупреждения при достижении пороговых значений. Настраиваются пороги для максимального времени отклика, минимального процента попаданий в кэш, максимального использования памяти и других важных показателей.
### Конфигурация и развертывание
Система использует иерархическую конфигурацию с поддержкой нескольких источников. Базовые настройки могут загружаться из переменных окружения, файлов конфигурации или задаваться программно. Каждый параметр проходит строгую валидацию, что предотвращает ошибки конфигурации в production-среде.
Для разных окружений (разработка, тестирование, production) предусмотрены разные профили конфигурации. Production-конфигурация включает максимальные уровни безопасности, подробное логирование и агрессивное кэширование. Development-конфигурация фокусируется на удобстве отладки и подробных сообщениях об ошибках.
Система поддерживает graceful shutdown и перезапуск без потери данных. При получении сигнала остановки система завершает текущие запросы, освобождает соединения, сохраняет состояние кэша и только затем завершает работу. Это гарантирует целостность данных и отсутствие прерванных транзакций.
## Детальная документация модулей
### Модуль построения запросов
Модуль query предоставляет типобезопасный API для построения SQL-запросов. Каждый тип запроса (SELECT, INSERT, UPDATE, DELETE) представлен отдельным построителем, который гарантирует корректность генерируемого SQL.
SelectBuilder позволяет создавать сложные SELECT-запросы с поддержкой JOIN, WHERE, ORDER BY, GROUP BY и HAVING. Он использует дженерики для обеспечения типобезопасности при работе с результатами запросов. Метод fields() определяет список возвращаемых полей, при этом можно использовать как конкретные имена столбцов, так и символ ‘*’ для выбора всех полей.
Join операции поддерживают различные типы: INNER, LEFT, RIGHT, FULL, CROSS и NATURAL. Для каждого JOIN можно указать условие соединения и алиас таблицы. Система автоматически проверяет корректность условий JOIN и предотвращает создание некорректных запросов.
Условия WHERE могут быть простыми (сравнение поля с значением) или составными (комбинация условий через AND/OR). Поддерживаются все стандартные операторы сравнения, а также специальные операторы для работы с NULL, диапазонами значений и множествами. Условия могут группироваться в скобках для управления приоритетом выполнения.
InsertBuilder специализируется на операциях вставки данных. Он поддерживает вставку одиночных и множественных строк, конфликтные ситуации (ON CONFLICT) и возвращение вставленных данных (RETURNING). Для конфликтных ситуаций предусмотрены две стратегии: DO NOTHING (пропуск вставки) и DO UPDATE (обновление существующих строк).
UpdateBuilder и DeleteBuilder следуют аналогичным принципам. Они обеспечивают безопасное построение операций модификации и удаления данных с поддержкой условий WHERE, RETURNING и дополнительных SQL-конструкций вроде USING и FROM.
### Модуль параметров запросов
Модуль parameter определяет систему типобезопасных параметров запросов. Тип QueryParameter представляет значение, которое может быть передано в SQL-запрос. Для каждого поддерживаемого типа данных (строка, число, булево значение, дата, JSON и т.д.) предусмотрен соответствующий вариант enum.
Каждый параметр проходит валидацию перед использованием. Строки проверяются на максимальную длину, числа — на допустимые диапазоны, даты — на корректность формата, JSON — на синтаксическую правильность. При обнаружении некорректного значения система возвращает ошибку на этапе построения запроса, а не во время выполнения в базе данных.
Метод to_sql() преобразует параметр в строковое представление, безопасное для включения в SQL-запрос. Для строк выполняется экранирование специальных символов, для дат добавляются соответствующие SQL-литералы, для бинарных данных используется hex-кодирование.
ParameterList представляет собой коллекцию параметров для использования в подготовленных выражениях. Он обеспечивает безопасное хранение и доступ к параметрам по индексу, что важно для запросов с большим количеством позиционных параметров.
### Модуль управления соединениями
HighPerformanceConnectionManager является центральным компонентом для работы с базой данных. Он создает и управляет несколькими пулами соединений, оптимизированными для разных типов операций.
Primary pool предназначен для критически важных операций, требующих гарантированной доступности. Он поддерживает минимальное количество активных соединений, что позволяет быстро обрабатывать запросы без задержек на установление соединения. Таймауты в этом пуле настроены на баланс между надежностью и производительностью.
Read pool оптимизирован для операций чтения. Он может содержать больше соединений, чем primary pool, так как запросы на чтение обычно менее требовательны к ресурсам и могут выполняться параллельно. Таймауты в этом пуле сокращены для быстрого освобождения соединений при простое.
Write pool специализируется на операциях модификации данных. Он использует увеличенные таймауты, так как операции записи могут занимать больше времени из-за блокировок и проверок целостности. Размер этого пула ограничен для предотвращения чрезмерной конкуренции за ресурсы базы данных.
Для распределенных конфигураций система поддерживает replica pools — пулы соединений к репликам базы данных. Запросы на чтение автоматически распределяются между репликами с использованием выбранной стратегии балансировки. Система постоянно мониторит состояние реплик и исключает из балансировки те, что не отвечают или отстают в репликации.
Метод get_pool_for_query() анализирует тип SQL-запросов и автоматически выбирает наиболее подходящий пул. SELECT-запросы направляются в read pool или replica pools, в то время как INSERT, UPDATE и DELETE — в write pool. Это позволяет оптимизировать использование ресурсов базы данных.
### Модуль безопасности
AdvancedSecurityLayer реализует многоуровневую систему защиты. Она сочетает несколько подходов к безопасности, создавая комплексную защиту от различных типов атак.
Первый уровень защиты — ограничение частоты запросов (rate limiting). Для каждого IP-адреса отслеживается количество запросов в минуту, при превышении лимита последующие запросы блокируются. Это защищает от DoS-атак и предотвращает чрезмерную нагрузку на базу данных.
Второй уровень — детектирование SQL-инъекций. Система анализирует структуру SQL-запросов на наличие потенциально опасных конструкций. Используется комбинация белого списка (разрешенные паттерны) и черного списка (запрещенные паттерны). Белый список включает корректно сформированные запросы SELECT, INSERT, UPDATE, DELETE с параметрами. Черный список содержит паттерны, характерные для SQL-инъекций: UNION SELECT, DROP TABLE, SQL-комментарии в середине запроса и т.д.
Третий уровень — анализ паттернов поведения. Система отслеживает типы запросов, их частоту и другие характеристики для каждого клиента. При обнаружении аномального поведения (например, резкое увеличение количества запросов или смена типа операций) IP-адрес может быть временно заблокирован для дополнительной проверки.
Четвертый уровень — блокировка IP-адресов. Система поддерживает списки разрешенных и заблокированных IP-адресов. Блокировка может быть как временной (на определенный период), так и постоянной. Автоматическая блокировка применяется при обнаружении явных атак, ручная блокировка доступна администраторам системы.
QueryAnalyzer проверяет семантическую корректность SQL-запросов. Он анализирует структуру запроса, определяет тип операции, проверяет наличие опасных конструкций (например, DROP или TRUNCATE без явного разрешения). Также он проверяет, что запрос ссылается только на разрешенные таблицы, если такой список задан в конфигурации.
### Модуль кэширования
MultiLevelCache реализует двухуровневую систему кэширования результатов запросов. Эта архитектура сочетает скорость доступа к оперативной памяти с возможностью хранения больших объемов данных.
Первый уровень (L1 кэш) использует алгоритм LRU (Least Recently Used) для управления памятью. Он хранит наиболее часто используемые данные в оперативной памяти, обеспечивая минимальное время доступа. Когда кэш достигает максимального размера, наименее используемые элементы удаляются. Этот уровень идеально подходит для данных с высокой локальностью обращения.
Второй уровень (L2 кэш) построен на основе конкурентных хэш-таблиц. Он может хранить больше данных, чем L1 кэш, и обеспечивает хорошую производительность при конкурентном доступе. Данные в L2 кэше сохраняются дольше, что полезно для информации, которая запрашивается реже, но всё равно требует быстрого доступа.
Оба уровня кэша поддерживают TTL (Time To Live) — время жизни записей. Когда запись находится в кэше дольше заданного времени, она считается устаревшей и удаляется при следующем обращении. Это гарантирует актуальность данных и предотвращает использование устаревшей информации.
QueryResultCache является специализированной оберткой над MultiLevelCache для кэширования результатов SQL-запросов. Он использует MD5-хеш SQL-запроса и его параметров в качестве ключа кэша. Это позволяет эффективно кэшировать параметризованные запросы, так как разные значения параметров создают разные ключи.
Метод should_cache_query() определяет, следует ли кэшировать результат запроса, на основе времени его выполнения. Быстрые запросы (менее заданного порога) обычно не кэшируются, так как выигрыш в производительности будет незначительным. Медленные запросы кэшируются для ускорения последующих обращений.
### Модуль мониторинга
MetricsCollector отвечает за сбор статистики о работе системы. Он собирает данные в реальном времени и предоставляет их для анализа. Собираемые метрики включают общее количество запросов, количество успешных и неудачных запросов, среднее время выполнения, количество запросов в секунду, эффективность кэширования и количество активных соединений.
Система использует атомарные операции для сбора метрик, что обеспечивает высокую производительность даже при большом количестве конкурентных запросов. Метрики собираются без блокировок, что минимизирует влияние мониторинга на производительность основной системы.
QueryTimer измеряет время выполнения отдельных запросов. Он запускается при начале обработки запроса и останавливается при завершении. Помимо времени выполнения, он собирает дополнительную информацию: тип запроса, IP-адрес клиента, количество затронутых строк, использование кэша и реплики.
PerformanceMonitor предоставляет метрики в реальном времени через broadcast-каналы. Он периодически вычисляет агрегированные показатели (например, среднее время ответа за последнюю секунду) и отправляет их всем подписчикам. Это позволяет внешним системам мониторинга получать данные без необходимости опрашивать систему.
AlertSystem отслеживает критические метрики и генерирует предупреждения при достижении пороговых значений. Настраиваются пороги для максимального количества запросов в секунду, максимального времени ответа, минимального процента попаданий в кэш и других важных показателей. Предупреждения имеют разные уровни серьезности: информационные, предупреждения, критические и ошибки.
### Модуль балансировки нагрузки
ReadReplicaBalancer распределяет запросы на чтение между доступными репликами базы данных. Он поддерживает несколько стратегий балансировки, каждая из которых оптимальна для определенных сценариев использования.
Стратегия Round Robin равномерно распределяет запросы между репликами в циклическом порядке. Она проста в реализации и обеспечивает хорошее распределение нагрузки при однородных репликах. Однако она не учитывает текущую загрузку каждой реплики.
Стратегия Least Connections направляет запросы на реплику с наименьшим количеством активных соединений. Это позволяет более эффективно использовать ресурсы реплик, особенно когда они имеют разную производительность или текущую нагрузку. Эта стратегия требует отслеживания состояния соединений для каждой реплики.
Стратегия Latency Based выбирает реплику с наименьшей задержкой. Она постоянно измеряет время отклика каждой реплики и выбирает наиболее быструю. Это особенно полезно в географически распределенных системах, где реплики находятся в разных регионах.
Стратегия Weighted Round Robin учитывает вес каждой реплики. Вес может отражать производительность реплики, её приоритет или другие характеристики. Реплики с большим весом получают больше запросов. Это позволяет учитывать различия в аппаратном обеспечении реплик.
Система постоянно отслеживает состояние реплик через health checks. Если реплика перестает отвечать или начинает отставать в репликации, она временно исключается из балансировки. После восстановления работоспособности реплика автоматически возвращается в пул.
NodeMetrics хранит метрики для каждой реплики: количество активных соединений, среднее время ответа, количество ошибок, время последней проверки здоровья и статус доступности. Эти данные используются для принятия решений при балансировке и для мониторинга состояния системы.
### Модуль автоматического масштабирования
AutoScaler анализирует метрики нагрузки и автоматически принимает решения о масштабировании ресурсов. Он работает на основе настраиваемых правил, которые определяют условия для увеличения или уменьшения количества ресурсов.
Основные метрики для принятия решений включают загрузку CPU, использование памяти, количество активных соединений и количество запросов в секунду. Каждая метрика сравнивается с пороговыми значениями, заданными в конфигурации.
Правило масштабирования вверх (scale up) срабатывает, когда метрики нагрузки превышают верхние пороги. Например, если загрузка CPU превышает 80% или количество активных соединений превышает 1000, система может увеличить количество реплик или расширить пулы соединений.
Правило масштабирования вниз (scale down) срабатывает, когда метрики нагрузки опускаются ниже нижних порогов. Это позволяет экономить ресурсы в периоды низкой нагрузки. Например, если загрузка CPU ниже 30% и количество активных соединений меньше 100, система может уменьшить количество реплик.
AutoScalingConfig содержит все настройки для автоматического масштабирования: максимальное количество реплик, пороговые значения для CPU и соединений, интервал проверки метрик. Конфигурация позволяет точно настроить поведение системы под конкретные требования и нагрузки.
Система использует скользящее среднее для метрик, чтобы избежать реакции на кратковременные всплески нагрузки. Это предотвращает частое масштабирование при временных изменениях нагрузки и обеспечивает стабильность работы.
### Основной серверный модуль
SqlServer является центральным компонентом, который объединяет все подсистемы ORM. Он координирует работу менеджера соединений, системы безопасности, кэширования, мониторинга и балансировки нагрузки.
Метод execute_query() обрабатывает одиночные SQL-запросы. Он выполняет полный цикл обработки: проверка безопасности, выбор пула соединений, выполнение запроса, кэширование результата и сбор метрик. Для SELECT-запросов результат преобразуется в JSON для удобства использования.
Метод execute_batch() обрабатывает пакеты запросов. Он группирует запросы по типу (чтение/запись) и выполняет их параллельно или последовательно в зависимости от требований к консистентности. Пакетная обработка значительно повышает производительность при массовых операциях.
BatchProcessor управляет асинхронной обработкой запросов в фоновом режиме. Он накапливает запросы в буфере и выполняет их при достижении определенного размера пакета или по истечении таймаута. Это позволяет объединять множество мелких запросов в более крупные транзакции.
Система prepared statements кэширует подготовленные выражения для часто выполняемых запросов. Используется MD5-хеш SQL-запроса в качестве ключа кэша. Это уменьшает нагрузку на базу данных, так как подготовка запроса выполняется только один раз при первом использовании.
ServerHealth предоставляет информацию о состоянии сервера: доступность базы данных, статистика соединений, время работы, количество подготовленных выражений. Эта информация используется для health checks и мониторинга.
### Конфигурационная система
Конфигурационная система использует иерархический подход с поддержкой нескольких источников. Базовые значения могут быть заданы в коде, переопределены в файлах конфигурации и окончательно заданы через переменные окружения.
DatabaseConfig содержит настройки подключения к базе данных: URL основной базы и реплик, размеры пулов соединений, таймауты, параметры повторных попыток подключения. Каждый параметр проходит валидацию, что предотвращает ошибки из-за некорректных настроек.
SecurityConfig определяет параметры безопасности: максимальное количество запросов в минуту, таймаут запросов, максимальная длина запроса, списки разрешенных таблиц и заблокированных IP-адресов, включение различных механизмов защиты.
CacheConfig управляет настройками кэширования: включение кэша запросов, размер кэша, время жизни записей, использование подготовленных выражений, размер кэша подготовленных выражений.
SqlServerConfig объединяет все конфигурации в единую структуру. Он также включает настройки логирования, которые определяют уровень детализации логов и их формат.
ConfigError определяет все возможные ошибки конфигурации с понятными сообщениями. Это упрощает диагностику проблем при развертывании системы в разных окружениях.
Система поддерживает hot reload конфигурации для некоторых параметров. Это позволяет изменять настройки без перезапуска приложения, что важно для production-среды.
### Утилиты и вспомогательные функции
Вспомогательные функции предоставляют общую функциональность, используемую в различных модулях системы. Они включают валидацию, форматирование и другие утилиты.
Функция is_valid_sql() выполняет базовую проверку SQL-запроса. Она проверяет, что запрос не пустой, не превышает максимальную длину и начинается с допустимого ключевого слова SQL. Это первичная проверка перед более глубоким анализом.
Функции is_valid_table_name() и is_valid_column_name() проверяют корректность имен таблиц и столбцов. Они обеспечивают, что имена содержат только допустимые символы и не превышают максимальную длину, определенную базой данных.
Функция format_duration() преобразует временные интервалы в удобочитаемый формат. Она автоматически выбирает наиболее подходящие единицы измерения (секунды, миллисекунды, микросекунды) в зависимости от величины интервала.
Константы по умолчанию определяют стандартные значения для различных параметров системы. Они используются, когда значения не заданы в конфигурации, и обеспечивают разумные настройки для большинства сценариев использования.
Тестовые утилиты предоставляют функции для тестирования системы, включая генерацию тестовых строк подключения и создание тестовых данных. Они упрощают написание unit-тестов и интеграционных тестов.
### Инициализация и управление жизненным циклом
Модуль init отвечает за инициализацию системы и управление её жизненным циклом. Он обеспечивает корректный запуск, остановку и перезапуск всех компонентов системы.
Функция initialize_sql_server() выполняет полную инициализацию системы. Она загружает конфигурацию, создает все необходимые компоненты, устанавливает соединения с базой данных, запускает фоновые задачи и регистрирует сервер в глобальном исполнителе запросов.
Процесс инициализации включает несколько этапов. Сначала загружается и валидируется конфигурация. Затем создаются менеджер соединений, система безопасности, кэш и другие компоненты. После этого устанавливаются соединения с базой данных и проверяется их работоспособность. Наконец, запускаются фоновые задачи для мониторинга, health checks и обслуживания.
Функция shutdown_sql_server() выполняет graceful shutdown системы. Она останавливает прием новых запросов, дожидается завершения текущих запросов, освобождает соединения с базой данных, сохраняет состояние кэша и корректно завершает работу всех компонентов. Это предотвращает потерю данных и гарантирует целостность системы.
Функция restart_sql_server() обеспечивает перезапуск системы без прерывания обслуживания. Она выполняет graceful shutdown, кратковременную паузу и повторную инициализацию. Это полезно для применения изменений конфигурации или обновления версии системы.
Фоновые задачи включают периодические health checks базы данных, очистку устаревших записей в кэше, ротацию логов и проверку алертов. Они запускаются при инициализации системы и работают независимо от основного потока обработки запросов.
Глобальный QueryExecutor предоставляет единую точку входа для выполнения запросов. Он управляет жизненным циклом сервера и обеспечивает доступ к нему из других частей приложения. Исполнитель запросов также предоставляет информацию о состоянии сервера и возможности управления им.