UWSGI, Flask, sqlalchemy и postgres: ошибка SSL: ошибка дешифрования или неудачная запись mac
Я пытаюсь настроить веб-сервер приложения с помощью uWSGI + Nginx, который запускает приложение Flask с использованием SQLAlchemy для связи с базой данных Postgres.
Когда я делаю запросы на веб-сервер, каждый другой ответ будет ошибкой 500.
Ошибка:
Traceback (most recent call last):
File "/var/env/argos/lib/python3.3/site-packages/sqlalchemy/engine/base.py", line 867, in _execute_context
context)
File "/var/env/argos/lib/python3.3/site-packages/sqlalchemy/engine/default.py", line 388, in do_execute
cursor.execute(statement, parameters)
psycopg2.OperationalError: SSL error: decryption failed or bad record mac
The above exception was the direct cause of the following exception:
sqlalchemy.exc.OperationalError: (OperationalError) SSL error: decryption failed or bad record mac
Ошибка запускается простым методом Flask-SQLAlchemy
:
result = models.Event.query.get(id)
uwsgi
управляется supervisor
, который имеет конфигурацию:
[program:my_app]
command=/usr/bin/uwsgi --ini /etc/uwsgi/apps-enabled/myapp.ini --catch-exceptions
directory=/path/to/my/app
stopsignal=QUIT
autostart=true
autorestart=true
и uwsgi
config выглядит так:
[uwsgi]
socket = /tmp/my_app.sock
logto = /var/log/my_app.log
plugins = python3
virtualenv = /path/to/my/venv
pythonpath = /path/to/my/app
wsgi-file = /path/to/my/app/application.py
callable = app
max-requests = 1000
chmod-socket = 666
chown-socket = www-data:www-data
master = true
processes = 2
no-orphans = true
log-date = true
uid = www-data
gid = www-data
Самое большее, что я могу получить, это то, что он имеет какое-то отношение к uwsgi forking. Но помимо этого я не понимаю, что нужно сделать.
Ответы
Ответ 1
Проблема закончилась тем, что была открыта uwsgi.
При работе с несколькими процессами с помощью мастер-процесса uwsgi инициализирует приложение в основном процессе, а затем копирует приложение для каждого рабочего процесса. Проблема в том, что если вы открываете соединение с базой данных при инициализации своего приложения, то у вас есть несколько процессов, разделяющих одно и то же соединение, что приводит к ошибке выше.
Решение состоит в том, чтобы установить параметр конфигурации lazy
для uwsgi, что заставляет полностью загружать приложение в каждый процесс:
lazy
Установите ленивый режим (загрузите приложения в рабочих вместо мастера).
Этот параметр может иметь последствия использования памяти, поскольку семантика копирования по-записи не может использоваться. Когда lazy включен, только рабочие перезагружаются сигналами перезагрузки uWSGI; хозяин останется в живых. Таким образом, изменения конфигурации uWSGI не поднимаются при перезагрузке ведущим устройством.
Также существует опция lazy-apps
:
lazy-apps
Загружайте приложения в каждый рабочий вместо мастера.
Этот параметр может иметь последствия использования памяти, поскольку семантика копирования по-записи не может использоваться. В отличие от лени, это влияет только на загрузку приложений, а не на поведение мастеров при перезагрузке.
Эта конфигурация uwsgi закончила работать для меня:
[uwsgi]
socket = /tmp/my_app.sock
logto = /var/log/my_app.log
plugins = python3
virtualenv = /path/to/my/venv
pythonpath = /path/to/my/app
wsgi-file = /path/to/my/app/application.py
callable = app
max-requests = 1000
chmod-socket = 666
chown-socket = www-data:www-data
master = true
processes = 2
no-orphans = true
log-date = true
uid = www-data
gid = www-data
# the fix
lazy = true
lazy-apps = true
Ответ 2
В качестве альтернативы вы можете утилизировать двигатель. Вот как я решил проблему.
Такие проблемы могут возникать, если во время создания приложения возникает запрос, то есть в модуле, который сам создает приложение. Если это указано, двигатель выделяет пул соединений, а затем вилки uwsgi.
Вызывая 'engine.dispose()', сам пул подключений закрыт, и новые соединения появятся, как только кто-то снова начнет делать запросы. Поэтому, если вы сделаете это в конце модуля, где вы создаете приложение, новые соединения будут созданы после вилки UWSGI.