Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Построение распределённых Django систем

Построение распределённых Django систем

Александр Ковалёв @ Moscow Python Conf 2017
"Занимаюсь разработкой почти 25 лет. Последние 4 года пишу backend и утилиты на Python. В докладе расскажу, из чего можно построить сеть однотипных веб-сайтов с централизованным управлением пользователями и публикуемыми материалами. Как обычно, пишем максимально абстрактный код, чтобы избежать постоянного переписывания кода и "допиливания" под каждый сайт. Я рассмотрю выбранный и отвергнутый инструментарий (Django, Redis, RabbitMQ, Celery, Docker), подход к синхронизации данных, вспомню про любимые аббревиатуры DRY и MVP и расскажу про некоторые ошибки и недоработки. Постараюсь успеть рассказать про deploy".
Видео: https://conf.python.ru/distributed-django/

Moscow Python Meetup
PRO

October 20, 2017
Tweet

More Decks by Moscow Python Meetup

Other Decks in Programming

Transcript

  1. Построение
    распределённых
    Django систем
    Александр Ковалев
    https://alkov.pro

    View Slide

  2. О себе
     Почти 25 лет в разработке:
     Assembler
     C/C++
     FoxBase/FoxPro/Clipper
     PHP
     Perl
     VBA (Макросы Microsoft Office)
     1С 7.7 - 8.3

    View Slide

  3. Disclaimer
    #1 Не напрягаться!
    #2 Не пинать!
    #3 ТЗ не ругать!

    View Slide

  4. Структура проекта
    site# 1 1
    site# 1 2
    site# 1
    site# 3
    site# 4
    site# 5
    site# 6
    site# 7
    site# 8
    site# 9
    site# 1 0
    site# 2
    service

    View Slide

  5. site# N
    service
    Структура проекта
    R E S T
    Frontend
    Content
    Editor
    R E S T
    Django Django

    View Slide

  6. site# N
    service
    Структура проекта
    R E S T
    Django Django

    View Slide

  7. site# N
    service
    Структура проекта
    Django Django
    Celery
    Redis
    Celery
    Redis
    REST REST

    View Slide

  8. class RedisStorage:
    _db = None
    _tries = 3
    def __init__(self):
    self._host = getattr(settings, 'REDIS_HOST', 'localhost')
    self._port = getattr(settings, 'REDIS_PORT', 6379)
    self._db_num = getattr(settings, 'REDIS_DB', 0)
    def connect(self):
    self._db = redis.StrictRedis(host=self._host,
    port=self._port,
    db=self._db_num)
    def execute(self, func_name, *args, **kwargs):
    if not self._db:
    self.connect()
    result = False
    for i in range(self._tries - 1):
    try:
    func = getattr(self._db, func_name, None)
    result = func(*args, **kwargs)
    except (ConnectionError, TimeoutError):

    View Slide

  9. class RedisCache:
    _media_change = 'change/media'
    _key_changes = 'change/site'
    _key_email = 'send/email'
    def __init__(self):
    self._rs = RedisStorage()
    self._media_sync_tries = getattr(settings, 'MEDIA_SYNC_TRIES', 3)
    self._chunk_size = getattr(settings, 'SITE_SYNC_CHUNK_SIZE', 10)
    self._send_tries = getattr(settings, 'SITE_SYNC_SEND_TRIES', 3)
    def push_media_change(self, filename, action='update', tries=0):
    if filename:
    print('FILENAME: {}'.format(filename))
    if tries <= self._media_sync_tries:
    _key = self._media_change
    self._rs.rpush(_key, json.dumps({
    'filename': filename,
    'action': action,
    'tries': tries,
    }))
    def iter_media_changes(self):

    View Slide

  10. site# N
    service
    Изменение данных
    Django Django
    Celery
    Redis
    Celery
    Redis
    ►создание
    ►изменение
    ►удаление!

    View Slide

  11. site# N
    service
    Пользовательский
    ввод
    Django Django
    Celery
    Redis
    Celery
    Redis

    View Slide

  12. site# N
    service
    Синхронизация
    Django Django
    Celery
    Redis
    Celery
    Redis

    View Slide

  13. site# N
    service
    Авторизация
    Django Django
    Celery
    Redis
    Celery
    Redis
    API
    JSON
    Web
    Token

    View Slide

  14. Ключевые элементы
    class BaseModel, class BaseManager
    class RedisStorage, class RedisCache
    class API

    View Slide

  15. Профит
    При изменении моделей не нужно дорабатывать синхронизацию
    Простая и удобная работа с кэшем и запросами к API
    «Лучше день потерять, потом за пять минут долететь» :)
    Но это не точно! ;)
    Не DDOS’им свои же сервера
    Сайты можно переустановить без потери данных

    View Slide

  16. Что дальше?
    Возможно сделать свои async tasks вместо Celery
    Рассмотреть варианты масштабирования
    Много интересных связанных сервисов. Это намек ;)
    Нагрузочное тестирование
    Оптимизация деплоя (оставить ли вообще docker?)

    View Slide

  17. Спасибо за внимание!
    Вопросы? Я здесь:
    [email protected]
    https://alkov.pro
    https://www.facebook.com/alkov.pro
    https://github.com/alkovpro
    https://github.com/devopshq/crosspm
    https://github.com/devopshq/youtrack
    А тут я кодил:

    View Slide