uWSGI,Flask,sqlalchemy和postgres:SSL错误:解密失败或logging失败

我正在尝试使用uWSGI + Nginx设置应用程序Web服务器,该应用程序使用SQLAlchemy运行Flask应用程序以与Postgres数据库进行通信。

当我向networking服务器发出请求时,其他响应将是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进行pipe理,它有一个configuration:

 [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的configuration看起来像:

 [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分叉有关。 但除此之外,我还不清楚需要做什么。

这个问题最终成了uwsgi的分歧。

当使用主进程处理多个进程时,uwsgi会在主进程中初始化应用程序,然后将应用程序复制到每个工作进程。 问题是,如果在初始化应用程序时打开数据库连接,则会有多个进程共享相同的连接,这会导致上述错误。

解决方法是为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 

作为替代方案,您可以处理引擎。 这就是我解决问题的方法。

如果在创建应用程序期间发生查询,也就是在创建应用程序本身的模块中,则可能会发生此类问题。 如果这样,引擎分配一个连接池,然后uwsgi分叉。

通过调用“engine.dispose()”,连接池本身就会关闭,只要有人开始再次查询,就会出现新的连接。 因此,如果您在创建应用程序的模块末尾执行此操作,则会在UWSGI分叉之后创建新的连接。