5

Sto provando a impostare un'attività giornaliera per la mia applicazione Django su Elastic Beanstalk. Non sembra esserci un modo accettabile per configurarlo, dato che il ritmo del sedano è la soluzione ideale per le attività periodiche in Django, ma non è eccezionale per gli ambienti con bilanciamento del carico.Attività periodiche in Django su Elean Beanstalk (possibilmente con il ritmo del sedano)

Ho visto alcune soluzioni come impostare il ritmo del sedano con leader_only = Vero, per eseguire solo un'istanza, ma questo lascia un singolo punto di errore. Ho visto altre soluzioni che consentono a molte istanze di sedano di battere e utilizzano i blocchi per assicurarsi che solo un task venga eseguito, ma non si riuscirebbe a fallire completamente a meno che le istanze non riuscite fossero riavviate? Un altro suggerimento che ho visto è di avere un'istanza separata per l'esecuzione di sedan beat, ma questo sarebbe comunque un problema a meno che non avesse un modo di riavviare se stesso se fallisse.

Esistono soluzioni decenti a questo problema? Preferirei non dover fare da babysitter a un programmatore, in quanto sarebbe piuttosto semplice non notare che il mio compito non veniva eseguito fino a poco tempo dopo.

+0

Qual è il problema con la corsa su istanza leader? Se quell'istanza fallisce i controlli di integrità verrà promossa un'altra istanza. – Gustaf

+0

Come fare se la verifica della salute fallisce se il celerybeat fallisce? –

+0

Se si è preoccupati dei punti di errore e si sta eseguendo il bilanciamento del carico a più istanze, forse è il momento di prendere in considerazione l'impostazione di un sistema di registrazione/monitoraggio dedicato o l'acquisto di un servizio. Amazon ne offre uno. Mi piace Sentry. –

risposta

0

Suggerirei di creare un management command che funziona con cron.

Utilizzando questo metodo, hai il tuo Django completo ORM, tutti i metodi, ecc. Con cui lavorare. Avvolgendo il tuo script in un tentativo/eccetto, hai la possibilità di registrare gli errori in qualsiasi modo desideri - notifiche via email, sistemi di registrazione esterni come Sentry, direttamente al DB, ecc.

I utente supervisord per eseguire cron e Funziona bene. Si basa su strumenti testati nel tempo che non ti deluderanno.

Infine, l'utilizzo di un database singleton per tenere traccia di se un processo batch è stato eseguito o è attualmente in esecuzione in un ambiente in cui sono presenti più istanze di esecuzione di bilanciamento del carico di Django non è una cattiva pratica, anche se si sente un poco icky a riguardo. Il DB è un mezzo molto affidabile per dirti se il DB è in fase di elaborazione.

L'unica cosa fastidiosa di cron è che non importa le variabili di ambiente di cui potresti aver bisogno per Django. Ho risolto questo con un semplice script Python.

Scrive il crontab all'avvio con le variabili di ambiente necessarie ecc. Incluse. Questo esempio è per Ubuntu su EBS, ma dovrebbe essere rilevante.

#!/usr/bin/env python 

# run-cron.py 
# sets environment variable crontab fragments and runs cron 

import os 
from subprocess import call 
from master.settings import IS_AWS 

# read django's needed environment variables and set them in the appropriate crontab fragment 
eRDS_HOSTNAME = os.environ["RDS_HOSTNAME"] 
eRDS_DB_NAME = os.environ["RDS_DB_NAME"] 
eRDS_PASSWORD = os.environ["RDS_PASSWORD"] 
eRDS_USERNAME = os.environ["RDS_USERNAME"] 

try: 
    eAWS_STAGING = os.environ["AWS_STAGING"] 
except KeyError: 
    eAWS_STAGING = None 

try: 
    eAWS_PRODUCTION = os.environ["AWS_PRODUCTION"] 
except KeyError: 
    eAWS_PRODUCTION = None 

eRDS_PORT = os.environ["RDS_PORT"] 

if IS_AWS: 
    fto = '/etc/cron.d/stortrac-cron' 
else: 
    fto = 'test_cron_file' 

with open(fto,'w+') as file: 
    file.write('# Auto-generated cron tab that imports needed variables and runs a python script') 

    file.write('\nRDS_HOSTNAME=') 
    file.write(eRDS_HOSTNAME) 
    file.write('\nRDS_DB_NAME=') 
    file.write(eRDS_DB_NAME) 
    file.write('\nRDS_PASSWORD=') 
    file.write(eRDS_PASSWORD) 
    file.write('\nRDS_USERNAME=') 
    file.write(eRDS_USERNAME) 
    file.write('\nRDS_PORT=') 
    file.write(eRDS_PORT) 
    if eAWS_STAGING is not None: 
     file.write('\nAWS_STAGING=') 
     file.write(eAWS_STAGING) 
    if eAWS_PRODUCTION is not None: 
     file.write('\nAWS_PRODUCTION=') 
     file.write(eAWS_PRODUCTION) 

    file.write('\n') 

    # Process queue of gobs 
    file.write('\n*/8 * * * * root python /code/app/manage.py queue --process-queue') 
    # Every 5 minutes, double-check thing is done 
    file.write('\n*/5 * * * * root python /code/app/manage.py thing --done') 
    # Every 4 hours, do this 
    file.write('\n8 */4 * * * root python /code/app/manage.py process_this') 
    # etc. 
    file.write('\n3 */4 * * * root python /ode/app/manage.py etc --silent') 
    file.write('\n\n') 

if IS_AWS: 
    args = ["cron","-f"] 
    call(args) 

E in supervisord.conf:

[program:cron] 
command = python /my/directory/runcron.py 
autostart = true 
autorestart = false 
Problemi correlati