Ответы пользователя по тегу Проектирование программного обеспечения
  • Хорошая ли стратегия разбивать монолит джанго на микросервисы джанго?

    @Jack444
    Вообще на самом деле джанго можно сделать аля-микросервисным если рассматривать каждое приложение как отдельный микросервис.
    В Джанго можно подключить для любой модели отдельную базу данных которая может находится на отдельном сервере или другом порту.
    Всё что требуется добавить в модель следующие:
    class MyModel(Model):
        class Meta:
            using = 'default'  # дефолтная база из DATABASES из settings.py

    Использование отдельных баз данных это дело одно, но вам скорее всего хотелось бы чтобы каждое приложение работало на отдельном порту, это тоже не проблема, в каждом приложении создайте systemd.service который запустит экземляр на другом порту и делайте жесткую ссылку в systemd/system, после через nginx проксируйте по location на порт приложения.
    Чисто так технически можно перенести экземпляры на разные серверы и поправить конфиги.
    Важно чтобы секретный ключ был один и тот же везде, иначе будет много проблем, по безопасности всё ок если не раскрывать его третьим лицам.
    Как вариант секретный ключ и другие данные можно хранить в .env и подгружать их в settings.py.
    Если хотите сохранить чистоту коду, то экземляры можно раскидать по папкам, в каждой из них набросать по минималке README.txt с инфой на каком порту запущено, какие команды для остановки и перезапуска, какие паки нельзя трогать а какие можно, можно только ту в которой висит приложение а все остальные папки которые не взаимодействуют из этого приложения можно снести.

    В общем какой-то такой вариант можно реализовать, но я бы рекомендовал оставить как есть и по возможности старые сервисы переписывать на микросервисы FastAPI а новые эндпоинты сразу пилить на нём.
    Ответ написан
    Комментировать
  • Как организовать структуру базы данных для нескольких типов пользователей?

    @Jack444
    Таблицы client/agent/user_data можно в одну таблицу user упаковать, + добавить поля is_client bool и is_agent bool, но так как вы уже сделали связь к role то перекидывайте туда роли client и agent, если возможно использование нескольких ролей для пользователя то используйте не name varchar a names varchar[] чтобы поле было массивом.
    Ещё обычно создаётся таблица permissiion которая привязывается к ролям и юзерам + дополнительно хранит поля table_name и action, либо вместо таблицы типом JSONB добавить ячейку в роли и юзеры.
    Вообще postgre изначально умеет работать с пользователями и можно использовать такие фичи как CREATE USER и ALTER ROLE но такой вариант может оказаться костыльным и логику с правами лучше перекинуть на уровень приложения.
    Ответ написан
  • Как ускорить проект на Python?

    @Jack444
    Первое что бросается в глаза так это то что сессия создаётся для каждого запроса, в итоге питон очень много времени затрачивает на инициализацию и подготовку подключений, сессиию надо создать в create_gather и после передовать в main.

    aiohttp под капотом имеет лимит в 100 tcp подключений в пуле, если на сервере ресурсов хватает то конечно хотелось бы иметь возможность держать хотя-бы 500 подключений на один воркер, ещё aiohttp получая ответ приводит заголовки в CMultiDict, лично у меня на тестах он работал в 20 раз медленее чем стандартный словарь

    Я бы заменил aiohttp на httpcore, httpcore это минимальный клиентский интерфейс который используется в другой популярной библиотеке httpx.
    httpcore работает с байтами, заголовки с ответа элементарно сплитятся и возвращаются в виде списка кортежей, можно задать хоть 1000 подключений в пуле, настроить keep-alive и слать запросы по протоколу HTTP/2.0, результат в разы быстрее чем aiohttp.

    Создав большое количество подключений + задач столько же или в разы больше то скрипт начнёт подвисать на обработке цикла событий, чтобы снизить издержки стоит установить uvloop, он работает под linux.

    Вместо bs4 я бы использовал parsel, по скоростям не могу сказать, чисто вкусовщина.
    Если учитывать что у вас там милион доменов и они все разные то скорее всего вам нужны какие-то общие данные в виде тегов meta/title/h1 то быстрее будет написать свою функцию для анализа html.

    psycopg нужно заменить на asyncpg он очень быстро преобразует python типы в типы postgresql.
    asyncpg позволяет создать пул подключений к базе а после создать воркеров в количестве созданных подключений, каждый воркер должен прослушивать asyncio.Queue, в очередь можно сразу закидывать аргументы для asyncpg.
    Все данные желательно кэшировать локально в dict, в словаре хоть миллион хоть 100 миллионов ключей, доступ к ним по методу .get() отрабатывается за доли микросекунды но потребление оперативной будет не малой. Пришедший и распарсенный ответ чекаем в локальном кэше, если данные изменились то отправляем задачу в очередь на обновление, если нет такого ключа то аппем куда-то значения для одного запроса INSERT с множеством VALUES, для обработки INSERT отдельную задачу надо сделать чтобы чекать раз в несколько секунд VALUES и если они есть то генерить SQL и отправлять в очередь.
    Ответ написан