2017-02-22 2 views
1

Ich wurde vor kurzem gezwungen, meine App auf Amazon zu verschieben und Auto-Skalierung zu verwenden, ich bin zu einem Problem mit Cron-Jobs und automatischer Skalierung gestolpert.Horizontale Skalierung und Cron-Jobs

Ich habe alle 15 Minuten einen Cron-Job, der prüft, ob Subskriptionen berechnet werden sollten, die Abfrage wählt alle überfälligen Subskriptionen aus und versucht sie zu belasten. Sie ändert ihren Status nach der Verarbeitung, aber sie werden in einem Batch abgerufen und der Vorgang dauert 1-3 Minuten.

Wenn ich mehrere Instanzen mit dem gleichen Cron-Job habe, könnte es simutanoisly feuern und die Abonnements mehrere Male aufladen. Das ist tatsächlich einmal passiert.

Was ist der beste Ansatz hier? Irgendwie den Tisch sperren oder?

Ich benutze Amazon elastische Bohnenstange und symfony3.

+0

beste Ansatz ist eine Warteschlange und eine Warteschlange Job pro Abogebühr Anfrage. Siehe RabbitMQ, AMQP, Pheanstalk usw. Andernfalls richten Sie eine tmp-Sperrdatei mit einem eindeutigen Pfad/Namen ein, und wenn die Datei vorhanden ist, wird Ihr anderer Cron nicht gestartet. Andernfalls wird die tmp-Datei erstellt ('touch ('/ tmp/unique.lock')'), und am Ende oder den Ausnahmen/Skripten wird die tmp-Datei entfernt. Das Problem mit letzterem ist, dass Sie überwachen müssen, ob es läuft, sonst läuft es überhaupt nicht. –

+0

http://queues.io/ Sie könnten der Frage auch einige Amazon-verwandte Tags hinzufügen. –

+0

Aber wie würde der temporäre Film über Amazon-Instanzen geteilt werden? Dies sind separate Server – user3908531

Antwort

1

Zumindest können Sie dedizierte Micro-Instanz für Abonnement-Gebühren (nicht automatisch skaliert natürlich), nur mit Cron-Jobs. Einfachster Weg, der sicherste (natürlich wird es sicher, wenn Sie Ihre Subskriptionsverarbeitungslogik von Front-End-Servern verschieben, die möglicherweise hinter dem VPC-Subnetz gehackt werden können, das nicht vom globalen Netzwerk verfügbar ist).

Aber wenn Sie nicht wollen, können Sie immer noch einen anderen Ansatz verwenden. Sie haben erwähnt, dass Sie Beanstalk verwenden. Beanstalk erlauben, verzögerte Jobs zu verwenden.

So möglicher Ansatz ist:

1) Wenn Sie Abonnement erstellen, können Sie berechnen, wenn es aufgeladen werden soll und dann den Job mit berechneter Verzögerung Beanstalk Rohr schieben.

2) Dann erhalten Arbeiter den Job (mit Abonnement) pünktlich. Nur ein Arbeiter erhält den bestimmten Job, also funktioniert es, wenn Sie Autoscaling verwenden.

3) In Worker, überprüfen Sie das Abonnement (wahrscheinlich kann es gelöscht oder inaktiv usw.) und wenn es bereit zum Laden, nur den Code zum Aufladen ausführen. Berechnen Sie dann die nächste Ladezeit und schieben Sie den neuen verzögerten Job (mit Abonnement) in die Warteschlange.

Beanstalk hat Symfony bundle und powerful PHP library