Mi servicio basado en matraz + postgresql + gunicorn + supervisor + nginx
Cuando se implementa mediante la ventana acoplable, después de ejecutar el servicio y luego acceder a la API, a veces muestra el mensaje de error y, a veces, funciona bien.
Y la base de datos de sqlachemy connect agrega los parámetros 'sslmode:disable' .
File "/usr/local/lib/python2.7/site-packages/sqlalchemy/sql/elements.py", line 287, in _execute_on_connection Return connection._execute_clauseelement(self, multiparams, params) File "/usr/local/lib/python2.7/site-packages/sqlalchemy/engine/base.py", line 1107, in _execute_clauseelement Distilled_params, File "/usr/local/lib/python2.7/site-packages/sqlalchemy/engine/base.py", line 1248, in _execute_context e, statement, parameters, cursor, context File "/usr/local/lib/python2.7/site-packages/sqlalchemy/engine/base.py", line 1466, in _handle_dbapi_exception Util.raise_from_cause(sqlalchemy_exception, exc_info) File "/usr/local/lib/python2.7/site-packages/sqlalchemy/util/compat.py", line 383, in raise_from_cause Reraise(type(exception), exception, tb=exc_tb, cause=cause) File "/usr/local/lib/python2.7/site-packages/sqlalchemy/engine/base.py", line 1244, in _execute_context Cursor, statement, parameters, context File "/usr/local/lib/python2.7/site-packages/sqlalchemy/engine/default.py", line 552, in do_execute Cursor.execute(statement, parameters) OperationalError: (psycopg2.OperationalError) server closed the connection unexpectedly This probably means the server terminated abnormally before or while processing the request.Docker para Mac: versión: 2.0.0.3 (31259)
macOS: versión 10.14.2
Pitón: versión 2.7.15
Cuando ver la información del puerto por comando
lsof -i:5432el puerto 5432 es el puerto predeterminado de la base de datos postgresql, si la consola de salida fue
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME postgres 86469 user 4u IPv6 0xxddd 0t0 TCP *:postgresql (LISTEN) postgres 86469 user 5u IPv4 0xxddr 0t0 TCP *:postgresql (LISTEN)mostraría el mensaje de error:
OperationalError: (psycopg2.OperationalError) server closed the connection unexpectedlypero si el registro de la consola de salida muestra esto:
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME com.docke 62421 user 26u IPv4 0xe93 0t0 TCP 192.168.2.7:6435->192.168.2.7:postgresql (ESTABLISHED) postgres 86460 user 4u IPv6 0xed3 0t0 TCP *:postgresql (LISTEN) postgres 86460 user 5u IPv4 0xe513 0t0 TCP *:postgresql (LISTEN) postgres 86856 user 11u IPv4 0xfe93 0t0 TCP 192.168.2.7:postgresql->192.168.2.7:6435 (ESTABLISHED)la situación, la API funcionaría bien.
Consulte el enlace https://github.com/docker/for-mac/issues/2442 , el problema no puede resolver mi problema.
Consulte el enlace Python y Sqlalchemy - Patrón de conexión -> Desconectado del servidor remoto al azar
Además, este problema no puede resolver mi problema.
matraz_sqlachemy necesita el parámetro pool_pre_ping
from flask_sqlalchemy import SQLAlchemy as _BaseSQLAlchemy class SQLAlchemy(_BaseSQLAlchemy): def apply_pool_defaults(self, app, options): super(SQLAlchemy, self).apply_pool_defaults(self, app, options) options["pool_pre_ping"] = True db = SQLAlchemy()La misma lógica para sqlalchemy.orm, (en la que se basa matraz_sqlalchemy por cierto)
engine = sqlalchemy.create_engine(connection_string, pool_pre_ping=True)Se pueden configurar más estrategias de protección, tal como se describe en el documento: https://docs.sqlalchemy.org/en/13/core/pooling.html#disconnect-handling-pessimistic
Por ejemplo, aquí está la instanciación de mi motor:
engine = sqlalchemy.create_engine(connection_string, pool_size=10, max_overflow=2, pool_recycle=300, pool_pre_ping=True, pool_use_lifo=True) sqlalchemy.orm.sessionmaker(bind=engine, query_cls=RetryingQuery)Para el código RetryingQuery, cf: Reintentar consultas sqlalchemy fallidas
Sobre la base de la solución en la respuesta y la información de la respuesta de @ MaxBlax360. Creo que la forma correcta de establecer estos valores de configuración en Flask-SQLAlchemy es configurando app.config['SQLALCHEMY_ENGINE_OPTIONS'] :
from flask import Flask from flask_sqlalchemy import SQLAlchemy app = Flask(__name__) # pool_pre_ping should help handle DB connection drops app.config['SQLALCHEMY_ENGINE_OPTIONS'] = {"pool_pre_ping": True} app.config['SQLALCHEMY_DATABASE_URI'] = \ f'postgresql+psycopg2://{POSTGRES_USER}:{dbpass}@{POSTGRES_HOST}:{POSTGRES_PORT}/{POSTGRES_DBNAME}' db = SQLAlchemy(app)Consulte también los documentos de Flask-SQLAlchemy sobre claves de configuración
Mi configuración de base de datos:
app = Flask(__name__) app.config['SQLALCHEMY_ENGINE_OPTIONS'] = {"pool_pre_ping": True} app.config['SQLALCHEMY_DATABASE_URI'] = os.environ['DATABASE_URL'] app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False # Play with following options: app.config['SQLALCHEMY_POOL_SIZE'] = 10 app.config['SQLALCHEMY_MAX_OVERFLOW'] = 20 app.config['SQLALCHEMY_POOL_RECYCLE'] = 1800 db = SQLAlchemy(app)Estoy publicando mi propia respuesta a esto, ya que ninguno de los anteriores abordó mi configuración particular (Postgres 12.2, SQLAlchemy 1.3).
Para detener los OperationalError s, tuve que pasar algunos connect_args adicionales a create_engine :
create_engine( connection_string, pool_pre_ping=True, connect_args={ "keepalives": 1, "keepalives_idle": 30, "keepalives_interval": 10, "keepalives_count": 5, } )