[RUBY] Kombinieren Sie regelmäßige Aufgaben in einer Elastic Beanstalk-Worker-Umgebung mit FIFO-Warteschlangen

: information_desk_person: Übersicht

https://docs.aws.amazon.com/elasticbeanstalk/latest/dg/using-features-managing-env-tiers.html#worker-periodictasks

If you configure your worker environment with an existing SQS queue and choose an Amazon SQS FIFO queue, periodic tasks aren't supported.

Es besagt, dass die FIFO-Warteschlange und reguläre Aufgaben nicht zusammen verwendet werden können.

: writing_hand: Richtlinie für Gegenmaßnahmen

Selbst wenn die Anzahl der Einheiten aufgrund der automatischen Skalierung zunimmt oder abnimmt, werden "periodische Aufgaben der Arbeitsumgebung" nicht mehr als einmal ausgeführt. Der Mechanismus besteht darin, dass die Instanz, die in die AWSEBWorkerCronLeaderRegistry von DynamoDB geschrieben werden kann, als Leader verwendet und nur von dieser Leader-Instanz ausgeführt wird.

Verwenden wir die Auswahl des Leiters und führen Sie cron in EC2 der Worker-Umgebung aus, um die kombinierte Verwendung des Titels zu realisieren.

: Computer: Überprüfungsumgebung

Ruby 2.6 running on 64bit Amazon Linux 2/3.1.1

: Warnung: Bitte beachten Sie, dass es sich um "Amazon Linux 2" handelt.

Schritt: eins :: Erstellen Sie eine Dummy-Datei cron.yaml und lassen Sie sie "AWSEBWorkerCronLeaderRegistry" schreiben

cron.yaml


version: 1
cron: # UTC
  - name: "dummy-job"  #Alles ist gut
    url: "/health"  #Alles ist gut
    schedule: "7 7 7 7 7" #Alles ist gut

Schritt: zwei :: Bereiten Sie ein Skript vor, um festzustellen, ob Sie ein Anführer sind

bin/eb_is_worker_leader


#!/usr/bin/env bash

#Beenden Sie, wenn nicht EC2
if [[ ! -f /var/lib/cloud/data/instance-id ]]; then
  exit
fi
instance_id=$(cat /var/lib/cloud/data/instance-id)

#Rufen Sie den Tabellennamen AWSEBWorkerCronLeaderRegistry ab
table_name=$(awk -F': ' '$1=="registry_table" {printf $2}' /etc/aws-sqsd.d/default.yaml)
#Ein Führer, der regelmäßig aktualisiert wird_ID abrufen(ex: i-XXXXX.${registration-record.worker_id})
leader_id=$(aws dynamodb get-item --region ${AWS_REGION} --table-name ${table_name} --key '{"id": {"S": "leader-election-record"} }' | jq -r .Item.leader_id.S)

echo ${leader_id} | grep -q ${instance_id}
exit $?

Schritt: drei :: Cron setzen

Wenn der in Schritt 2 erstellte bin / eb_is_worker_leader erfolgreich ist, setzen Sie cron, um den Prozess auszuführen. Wenn Sie beispielsweise Folgendes verwenden: gem: wann immer, um cron in Ruby festzulegen, ist dies wie folgt.

schedule.rb


job_type :leader_runner, "cd :path && bin/eb_is_worker_leader && bin/rails runner -e :environment ':task' :output"

every :hour do
  leader_runner "SomeModel.ladeeda"
end

Die in wann immer angegebenen "Läufer" lauten wie folgt. Zum Vergleich sehen Sie, dass nur "bin / eb_is_worker_leader" hinzugefügt wurde.

job_type :runner,  "cd :path && bin/rails runner -e :environment ':task' :output"
Bonus: Aktualisieren Sie cron mit wann immer

bash:.platform/hooks/postdeploy/XX_update_cron.sh


#!/usr/bin/env bash

#Tu nichts, wenn nicht ein Arbeiter
env_name=$(jq -r .Name /opt/elasticbeanstalk/config/ebenvinfo/envtier.json)
if [[ ! ${env_name} = 'Worker' ]]; then
  exit
fi

/opt/elasticbeanstalk/.rbenv/shims/bundle exec whenever --user webapp --update-crontab

: Punch: Zusammenfassung

Diese werden auf allen Worker-Instanzen ausgeführt. Da cron weiterhin nur den Reader verarbeitet, wird die doppelte Ausführung regulärer Aufgaben verhindert.

: books: Ähnliche Lösung

: Warnung: Beide sind für "Amazon Linux 1"

Diese bestimmen den Leader anhand der Anzahl der Instanzen. In der Methode dieses Artikels denke ich, dass es eine einfache Implementierung sein wird, indem "AWSEBWorkerCronLeaderRegistry" umgeleitet wird.

Recommended Posts

Kombinieren Sie regelmäßige Aufgaben in einer Elastic Beanstalk-Worker-Umgebung mit FIFO-Warteschlangen
Verwenden Sie den Konstruktor mit Argumenten in cucumber-picocontainer