2016-03-23 56 views
14

Ciao ho una configurazione in cui sto usando sedano Flask SQLAlchemy e sto ottenendo questo errore a intermittenza:sedano, pallone SQLAlchemy: DatabaseError: (DatabaseError) Errore SSL: decrittazione fallito o cattivo record di Mac

(psycopg2.DatabaseError) SSL error: decryption failed or bad record mac 

ho seguito questo post:

Celery + SQLAlchemy : DatabaseError: (DatabaseError) SSL error: decryption failed or bad record mac

e anche un po 'di più e ha aggiunto un precorrere a postrun e metodi:

@task_postrun.connect 
def close_session(*args, **kwargs): 
    # Flask SQLAlchemy will automatically create new sessions for you from 
    # a scoped session factory, given that we are maintaining the same app 
    # context, this ensures tasks have a fresh session (e.g. session errors 
    # won't propagate across tasks) 
    d.session.remove() 

@task_prerun.connect 
def on_task_init(*args, **kwargs): 
    d.engine.dispose() 

Ma sto ancora vedendo questo errore. Qualcuno ha risolto questo?

Nota che lo sto eseguendo su AWS (con due server che accedono allo stesso database). Il database stesso è ospitato sul proprio server (non su RDS). Credo che le attività di background sedano totale in esecuzione siano 6 (2 + 4). Il frontend del pallone funziona usando il gunicorn.

mio thread correlato: https://github.com/celery/celery/issues/3238#issuecomment-225975220

+0

Eri in grado di trovare una soluzione per questo. –

+0

No, non ne ho ancora trovato uno – Ankit

+0

Io uso Celery, SQLAlchemy e PostgreSQL su AWS e non c'è alcun problema. L'unica differenza che posso pensare è che ho il database su RDS. Penso che si possa provare a passare a RDS temporaneamente, solo per verificare se il problema sarà ancora presente o meno. Se sparirà con RDS, allora dovrai controllare le impostazioni di PostgreSQL. –

risposta

1

Ecco il mio commento con ulteriori informazioni:

I use Celery, SQLAlchemy and PostgreSQL on AWS and there is no such problem. The only difference I can think of is that I have the database on RDS. I think you can try switching to RDS temporary, just to test if the issue will be still present or not. If it disappered with RDS then you'll need to look into PostgreSQL settings.

Secondo i paramters RDS, ho abilitato SSL:

ssl = 1, Enables SSL connections. 
ssl_ca_file = /rdsdbdata/rds-metadata/ca-cert.pem 
ssl_cert_file = /rdsdbdata/rds-metadata/server-cert.pem 
ssl_ciphers = false, Sets the list of allowed SSL ciphers. 
ssl_key_file = /rdsdbdata/rds-metadata/server-key.pem 
ssl_renegotiation_limit = 0, integer, (kB) Set the amount of traffic to send and receive before renegotiating the encryption keys. 

Per quanto riguarda Codice di inizializzazione di Celery, si tratta approssimativamente di questo

from sqlalchemy.orm import scoped_session 
from sqlalchemy.orm import sessionmaker 

import sqldb 

engine = sqldb.get_engine() 
cached_data = None 

def do_the_work(): 
    global engine, ruckus_data 
    if cached_data is not None: 
     return cached_data 
    db_session = None 
    try: 
     db_session = scoped_session(sessionmaker(
      autocommit=False, autoflush=False, bind=engine)) 
     data = sqldb.get_session().query(
      sqldb.system.MyModel).filter_by(
       my_type = sqldb.system.MyModel.TYPEA).all() 
     cached_data = {} 
     for row in data: 
      ... # put row into cached_data 
    finally: 
     if db_session is not None: 
      db_session.remove() 
    return cached_data 

Questa funzione do_the_work viene quindi chiamata dall'attività di sedici. Il sqldb.get_engine assomiglia a questo:

from sqlalchemy import create_engine 

_engine = None 

def get_engine(): 
    global _engine 
    if _engine: 
     return _engine 
    _engine = create_engine(config.SQL_DB_URL, echo=config.SQL_DB_ECHO) 
    return _engine 

Infine, lo SQL_DB_URI e SQL_DB_ECHO nel modulo di configurazione sono queste:

SQL_DB_URL = 'postgresql+psycopg2://%s:%[email protected]%s/%s' % (
    POSTGRES_USER, POSTGRES_PASSWORD, POSTGRES_HOST, POSTGRES_DB_NAME) 
SQL_DB_ECHO = False 
+0

grazie, quindi crei un nuovo motore e una sessione su ogni attività? Chiedendosi anche se ci sia un comportamento razionale dietro: 'sqldb.get_session(). Query' invece di' db_session.query'? – Ankit

+0

@Ankit La variabile del motore si trova a livello del modulo e funziona come un singleton. Il motore viene creato una sola volta e riutilizzato nell'esecuzione delle attività seguenti (almeno questo è ciò che ricordo dai miei test). Sqldb.get_session() è un problema di copia-incolla, dovrebbe essere solo 'db_session.query'. –