web-dev-qa-db-fra.com

Elastic Beanstalk désactive le changement d'état d'intégrité basé sur les réponses 4xx

J'ai une API de repos fonctionnant sur Elastic Beanstalk, ce qui fonctionne très bien. Tout ce qui concerne les applications fonctionne bien et fonctionne comme prévu.

L'application est une API de repos, utilisée pour rechercher différents utilisateurs.

example url: http://service.com/user?uid=xxxx&anotherid=xxxx

Si un utilisateur avec l'un des identifiants est trouvé, l'API répond par 200 OK, sinon, répond par 404 Not Found selon. HTTP/1.1 défenitions du code d'état.

Il n'est pas rare que notre API réponde 404 Not Found sur de nombreuses demandes, et le haricot élastique transfère notre environnement de OK dans Warning ou même dans Degraded à cause de cela. Et il semble que nginx ait refusé la connexion à l'application en raison de cet état dégradé. (il semble qu'il ait un seuil de 30% + dans les états warninget 50% + dans les états degraded. C'est un problème, car l'application fonctionne réellement comme prévu, mais les paramètres par défaut d'Elastic Beanstalks - pense c'est un problème, alors que ce n'est vraiment pas le cas.

Quelqu'un connaît-il un moyen de modifier le seuil des avertissements 4xx et des transitions d'état dans EB, ou de les désactiver complètement?

Ou dois-je vraiment faire un traitement des symptômes et cesser d'utiliser 404 Not Found lors d'un appel comme celui-ci? (je n'aime vraiment pas cette option)

48
Martin Hansen

Mise à jour: AWS EB inclut enfin un paramètre intégré pour cela: https://stackoverflow.com/a/51556599/1123355

Ancienne solution: Après avoir plongé dans l'instance EB et passé plusieurs heures à chercher où le démon de vérification de la santé d'EB rapporte les codes d'état à EB pour évaluation, je enfin trouvé, et est venu avec un patch qui peut servir de solution de contournement parfaitement fine pour empêcher 4xx codes de réponse pour transformer l'environnement en état d'intégrité de l'environnement Degraded, ainsi que pour vous avertir inutilement avec cet e-mail:

Environment health has transitioned from Ok to Degraded. 59.2 % of the requests are erroring with HTTP 4xx.

La logique de rapport du code d'état se trouve dans healthd-appstat, un Ruby script développé par l'équipe EB qui surveille en permanence /var/log/nginx/access.log et signale les codes d'état à EB, en particulier dans le chemin suivant:

/opt/elasticbeanstalk/lib/Ruby/lib/Ruby/gems/2.2.0/gems/healthd-appstat-1.0.1/lib/healthd-appstat/plugin.rb

Le suivant .ebextensions le fichier corrigera ce script Ruby pour éviter de signaler 4xx les codes de réponse reviennent à EB. Cela signifie que l'EB ne dégradera jamais la santé de l'environnement en raison de 4xx des erreurs, car il ne saura tout simplement pas qu'elles se produisent. Cela signifie également que la page "Santé" de votre environnement EB affichera toujours 0 pour le 4xx nombre de codes de réponse.

container_commands:
    01-patch-healthd:
        command: "Sudo /bin/sed -i 's/\\# normalize units to seconds with millisecond resolution/if status \\&\\& status.index(\"4\") == 0 then next end/g' /opt/elasticbeanstalk/lib/Ruby/lib/Ruby/gems/2.2.0/gems/healthd-appstat-1.0.1/lib/healthd-appstat/plugin.rb"
    02-restart-healthd:
        command: "Sudo /usr/bin/kill $(/bin/ps aux | /bin/grep -e '/bin/bash -c healthd' | /usr/bin/awk '{ print $2 }')"
        ignoreErrors: true

Oui, c'est un peu moche, mais cela fait le travail, au moins jusqu'à ce que l'équipe EB fournisse un moyen d'ignorer 4xx erreurs via un paramètre de configuration. Incluez-le avec votre application lors de votre déploiement, dans le chemin suivant par rapport au répertoire racine de votre projet:

.ebextensions/ignore_4xx.config

Bonne chance et faites-moi savoir si cela a aidé!

57
Elad Nava

Il existe une personnalisation de la règle de surveillance de l'intégrité dédiée appelée Ignorer HTTP 4xx (capture d'écran ci-jointe) Il suffit de l'activer et EB ne dégradera pas l'intégrité de l'instance sur les erreurs 4xx. enter image description here

25
A G

Merci pour votre réponse Elad Nava , j'ai eu le même problème et votre solution a parfaitement fonctionné pour moi!

Cependant, après avoir ouvert un ticket dans le AWS Support Center, ils m'ont recommandé de modifier la configuration nginx pour ignorer 4xx lors du bilan de santé au lieu de modifier le script Ruby. Pour ce faire , J'ai également dû ajouter un fichier de configuration au .ebextensions répertoire, afin d'écraser le répertoire par défaut nginx.conf fichier:

files:
  "/tmp/nginx.conf":
    content: |

      # Elastic Beanstalk Managed

      # Elastic Beanstalk managed configuration file
      # Some configuration of nginx can be by placing files in /etc/nginx/conf.d
      # using Configuration Files.
      # http://docs.amazonwebservices.com/elasticbeanstalk/latest/dg/customize-containers.html
      #
      # Modifications of nginx.conf can be performed using container_commands to modify the staged version
      # located in /tmp/deployment/config/etc#nginx#nginx.conf

      # Elastic_Beanstalk
      # For more information on configuration, see:
      #   * Official English Documentation: http://nginx.org/en/docs/
      #   * Official Russian Documentation: http://nginx.org/ru/docs/

      user  nginx;
      worker_processes  auto;

      error_log  /var/log/nginx/error.log;

      pid        /var/run/nginx.pid;


      worker_rlimit_nofile 1024;

      events {
          worker_connections  1024;
      }

      http {

          ###############################
          # CUSTOM CONFIG TO IGNORE 4xx #
          ###############################

          map $status $loggable {
            ~^[4]  0;
            default 1;
          }

          map $status $modstatus {
            ~^[4]  200;
            default $status;
          }

          #####################
          # END CUSTOM CONFIG #
          #####################

          port_in_redirect off;
          include       /etc/nginx/mime.types;
          default_type  application/octet-stream;


          # This log format was modified to ignore 4xx status codes!
          log_format  main   '$remote_addr - $remote_user [$time_local] "$request" '
                             '$status $body_bytes_sent "$http_referer" '
                             '"$http_user_agent" "$http_x_forwarded_for"';

          access_log  /var/log/nginx/access.log  main;

          log_format healthd '$msec"$uri"'
                             '$modstatus"$request_time"$upstream_response_time"'
                             '$http_x_forwarded_for' if=$loggable;

          sendfile        on;
          include /etc/nginx/conf.d/*.conf;

          keepalive_timeout  1200;

      }

container_commands:
  01_modify_nginx:
    command: cp /tmp/nginx.conf /tmp/deployment/config/#etc#nginx#nginx.conf

Bien que cette solution soit beaucoup plus détaillée, je pense personnellement qu'elle est plus sûre à implémenter, tant qu'elle ne dépend d'aucun script propriétaire AWS. Ce que je veux dire, c'est que si, pour une raison quelconque, AWS décide de supprimer ou de modifier leur Ruby script (croyez-moi ou non, ils adorent changer de script sans préavis), il y a de grandes chances que la solution avec sed ne fonctionnera plus.

13
Adriano Valente

Voici une solution basée sur réponse d'Adriano Valente . Je n'ai pas pu obtenir le $loggable un peu de travail, bien que sauter la journalisation pour les 404 semble être une bonne solution. J'ai simplement créé un nouveau .conf fichier qui définit le $modstatus variable, puis a remplacé le format de journal healthd pour utiliser $modstatus au lieu de $status. Cette modification a également nécessité le redémarrage de nginx. Cela fonctionne sur Amazon Linux 2016.09 v2.3.1 64 bits d'Elastic Beanstalk exécutant Ruby 2.3 (Puma).

# .ebextensions/nginx.conf

files:
  "/tmp/nginx.conf":
    content: |

      # Custom config to ignore 4xx in the health file only
      map $status $modstatus {
        ~^[4]  200;
        default $status;
      }

container_commands:
  modify_nginx_1:
    command: "cp /tmp/nginx.conf /etc/nginx/conf.d/custom_status.conf"
  modify_nginx_2:
    command: Sudo sed -r -i 's@\$status@$modstatus@' /opt/elasticbeanstalk/support/conf/webapp_healthd.conf
  modify_nginx_3:
    command: Sudo /etc/init.d/nginx restart
1
littleforest

J'ai récemment rencontré le même problème d'être bombardé d'erreurs 4xx que vous. J'ai essayé les suggestions énumérées ci-dessus, mais rien n'a fonctionné pour moi. J'ai contacté le support AWS et voici ce qu'ils ont suggéré, et cela a résolu mon problème. J'ai une application Elastic Beanstalk avec 2 instances en cours d'exécution.

  1. Créez un dossier appelé .ebextensions
  2. Dans ce dossier, créez un fichier appelé nginx.config (assurez-vous qu'il a l'extension .config. ".Conf" ne suffira pas!)
  3. Si vous déployez votre application avec un conteneur Docker, assurez-vous que ce dossier .ebextensions est inclus dans le bundle de déploiement. Pour moi, le bundle comprenait le dossier ainsi que le Dockerrun.aws.json

Voici l'intégralité du contenu du fichier nginix.config:

files:
  "/etc/nginx/nginx.conf":
    content: |
      # Elastic Beanstalk Nginx Configuration File
      user  nginx;
      worker_processes  auto;

      error_log  /var/log/nginx/error.log;

      pid        /var/run/nginx.pid;

      events {
          worker_connections  1024;
      }

      http {

          # Custom config
          # HTTP 4xx ignored.
          map $status $loggable {
            ~^[4]  0;
            default 1;
          }

          # Custom config
          # HTTP 4xx ignored.
          map $status $modstatus {
            ~^[4]  200;
            default $status;
          }

          include       /etc/nginx/mime.types;
          default_type  application/octet-stream;

          access_log    /var/log/nginx/access.log;

          log_format  healthd '$msec"$uri"$modstatus"$request_time"$upstream_response_time"$http_x_forwarded_for';

          include       /etc/nginx/conf.d/*.conf;
          include       /etc/nginx/sites-enabled/*;
      }
0
Qing Xia

Solution fournie par le support AWS à partir d'avril 2018:

 files:
  "/tmp/custom-site-nginx.conf":
    mode: "000664"
    owner: root
    group: root
    content: |
       map $http_upgrade $connection_upgrade {
           default        "upgrade";
           ""            "";
       }
       # Elastic Beanstalk Modification(EB_INCLUDE)
       # Custom config
       # HTTP 4xx ignored.
       map $status $loggable {
                ~^[4]  0;
                default 1;
       }


       server {
           listen 80;

         gzip on;
         gzip_comp_level 4;
         gzip_types text/html text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript;

           if ($time_iso8601 ~ "^(\d{4})-(\d{2})-(\d{2})T(\d{2})") {
               set $year $1;
               set $month $2;
               set $day $3;
               set $hour $4;
           }
           access_log /var/log/nginx/healthd/application.log.$year-$month-$day-$hour healthd if=$loggable;

           access_log    /var/log/nginx/access.log;

           location / {
               proxy_pass            http://docker;
               proxy_http_version    1.1;

               proxy_set_header    Connection            $connection_upgrade;
               proxy_set_header    Upgrade                $http_upgrade;
               proxy_set_header    Host                $Host;
               proxy_set_header    X-Real-IP            $remote_addr;
               proxy_set_header    X-Forwarded-For        $proxy_add_x_forwarded_for;
           }
       }

 container_commands:
   override_beanstalk_nginx:
     command: "mv -f /tmp/custom-site-nginx.conf /etc/nginx/sites-available/elasticbeanstalk-nginx-docker-proxy.conf"
0
Deepak Puthraya

Basé sur Elad Nava's Answer , je pense qu'il est préférable d'utiliser directement le script de contrôle d'Elasticbeanstalk healthd au lieu d'un kill:

container_commands:
    01-patch-healthd:
        command: "Sudo /bin/sed -i 's/\\# normalize units to seconds with millisecond resolution/if status \\&\\& status.index(\"4\") == 0 then next end/g' /opt/elasticbeanstalk/lib/Ruby/lib/Ruby/gems/2.2.0/gems/healthd-appstat-1.0.1/lib/healthd-appstat/plugin.rb"
    02-restart-healthd:
        command: "Sudo /opt/elasticbeanstalk/bin/healthd-restart"

Enfin, lors de l'examen de ce problème, j'ai remarqué que les codes d'état des journaux healthd et Apache diffèrent, le premier utilisant% s tandis que le dernier%> s entraînant des écarts entre eux. J'ai également corrigé cela en utilisant:

    03-healthd-logs:
        command: sed -i 's/^LogFormat.*/LogFormat "%{%s}t\\"%U\\"%>s\\"%D\\"%D\\"%{X-Forwarded-For}i" healthd/g' /etc/httpd/conf.d/healthd.conf
0
Vlassios