[RUBY] Combinez des tâches périodiques dans un environnement de travail Elastic Beanstalk avec des files d'attente FIFO

: information_desk_person: Présentation

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.

Il indique que la file d'attente FIFO et les tâches régulières ne peuvent pas être utilisées ensemble.

: writing_hand: Politique de contre-mesure

Même si le nombre d'unités augmente ou diminue en raison de la mise à l'échelle automatique, les «tâches périodiques de l'environnement de travail» ne sont pas exécutées plus d'une fois. Le mécanisme est que l'instance qui peut être écrite dans ʻAWSEBWorkerCronLeaderRegistry` de DynamoDB est utilisée comme leader et exécutée uniquement par cette instance leader.

Utilisons la sélection du leader et exécutons cron dans EC2 de l'environnement de travail pour réaliser l'utilisation combinée du titre.

: ordinateur: environnement de vérification

Ruby 2.6 running on 64bit Amazon Linux 2/3.1.1

: avertissement: ʻVeuillez noter qu'il s'agit d'Amazon Linux 2`.

Étape: un :: Créez un cron.yaml factice et faites-le écrire ʻAWSEBWorkerCronLeaderRegistry`

cron.yaml


version: 1
cron: # UTC
  - name: "dummy-job"  #Tout va bien
    url: "/health"  #Tout va bien
    schedule: "7 7 7 7 7" #Tout va bien

Étape: deux :: Préparez un script pour déterminer si vous êtes un leader

bin/eb_is_worker_leader


#!/usr/bin/env bash

#Quitter quand pas EC2
if [[ ! -f /var/lib/cloud/data/instance-id ]]; then
  exit
fi
instance_id=$(cat /var/lib/cloud/data/instance-id)

#Obtenez le nom de la table AWSEBWorkerCronLeaderRegistry
table_name=$(awk -F': ' '$1=="registry_table" {printf $2}' /etc/aws-sqsd.d/default.yaml)
#Un leader mis à jour régulièrement_Obtenir l'identifiant(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 $?

Étape: trois :: définir cron

Si le bin / eb_is_worker_leader créé à l'étape 2 réussit, définissez cron pour exécuter le processus. Par exemple, si vous utilisez: gem: every pour définir cron dans Ruby, ce sera comme suit.

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

Les coureurss fournis dans chaque fois sont les suivants. Par comparaison, vous pouvez voir que seul bin / eb_is_worker_leader a été ajouté.

job_type :runner,  "cd :path && bin/rails runner -e :environment ':task' :output"
Bonus: mettre à jour cron avec chaque fois que

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


#!/usr/bin/env bash

#Ne rien faire si ce n'est un travailleur
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: Résumé

Ceux-ci exécuteront cron sur toutes les instances de travail. Puisque cron continue de traiter uniquement pour le lecteur, il empêche l'exécution en double des tâches régulières.

: livres: solution similaire

: avertissement: les deux sont pour ʻAmazon Linux 1`

Ceux-ci déterminent le leader en fonction du nombre d'instances. Dans la méthode de cet article, je pense que ce sera une implémentation simple en détournant ʻAWSEBWorkerCronLeaderRegistry`.

Recommended Posts

Combinez des tâches périodiques dans un environnement de travail Elastic Beanstalk avec des files d'attente FIFO
Utiliser le constructeur avec des arguments dans cucumber-picocontainer