Задать вопрос
@eoyxc
Python программистка

Flask приложение и cache в gunicorn?

Есть Flask приложение, в нем при определенных действиях использую обновление файла конфигурации, и параметров.
вызываю типа так
app.config.update(test=2)
по дефолту эта переменная в конфиругации равна 1.
и потом в шаблоне вывожу config.test

при использовании встроенного во фласк вебсервера, все работает все замечательно.
но на продакшене использую gunicorn, и вот с ним вылазят проблемы.

функция выполняется все хорошо вроде бы.
но в шаблоне при каждом рефреше отображается то 1 то 2
такое ощущение что воркеры не все обновляются или кеширует что то.

пробовала запускать вот так
PYTHONDONTWRITEBYTECODE=1 gunicorn --workers=4 --timeout=60 --bind=0.0.0.0:8000 app:app

при этом директорию pycache удаляла. не помогает.
параметр --reload также не помог.

Если запустить приложение с 1 воркером, то все работает нормально.
вопрос почему не все обновляются или синхронизируются, и как это исправить ?
  • Вопрос задан
  • 112 просмотров
Подписаться 1 Сложный 1 комментарий
Пригласить эксперта
Ответы на вопрос 1
trapwalker
@trapwalker
Программист, энтузиаст
Тут кеш ни при чем. Когда вы запускаете с одним воркером или просто дев-сервер, то запущен только один процесс. Именно его конфиг вы и апдейтите.
Когда процессов несколько, а вы выполняете апдейт только в одном, то изменение только там и остаётся. Это не кэш. У каждого процесса своя память, а ваши изменения не затрагивают код, только меняют значение переменной в одном из процессов.
Вот и весь секрет.
Ключевая ошибка вот тут у вас в понимании:
использую обновление файла конфигурации, и параметров.

Вы не трогаете файл конфигурации по факту вот тем своим кодом, что привели, но даже если бы вы в этом файле конфигурации что-то поправили и сохранили, то его нужно в каждом процессе перезагрузить. Ну сделать релоад этого модуля, например.
Вообще это не очень хорошая схема динамического обновления конфигурации.
Используйте какой-нибудь механизм pub/sub (подписок на события), чтобы отправить каждому процессу сигнал об изменении конфигурации.
Ещё можно сделать механизм обнаружения изменения конфигурации в файле, чтобы этот механизм постоянно мониторил таймштамп изменения файла и сравнивал с временем своего обновления конфигурации (в памяти). При нестыковке просто перезагружаете конфигурацию. Это будет работать в каждом процессе.
Ну или лучше погуглите готовые решения для этой задачи. Их много существует. Так будет лучше.

И да, тут надо понимать, что пока у вас простой сервер и в нем не много параметров конфигурации, можно легко контролировать каждый параметр и возможные побочные эффекты от его динамического изменения. Но в сложном проекте можно легко потерять из виду какой-то побочный эффект или неявное промежуточное состояние, когда измененный вот так вот параметр конфигурации приведёт к неконсистентности состояния всего процесса.
В таких случаях при обнаружении процессом признаков изменения конфигурации имеет смысл процессу просто самостоятельно завершиться штатно закрыв все свои соединения. Ещё хорошей идеей было бы сделать это через небольшой рандомный интервал времени, чтобы все ваши процессы делали это не одновременно.
gunicorn, кажется, должен просто запускать новые процессы взамен завершившихся, чтобы сохранить нужное их количество. Тут я не уверен, нужно смотреть. Но новые процессы будут запускаться уже с новой конфигурацией, загруженной штатно, обычным и единственным способом. За счет рандомной паузы перед самозавершением процесса вы не получите мгновенного отказа всех серверных процессов.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы