Подтвердить что ты не робот

Эластичный бобслей отключает изменение состояния здоровья на основе 4xx ответов

У меня есть rest api, работающий на Elastic Beanstalk, который отлично работает. Все приложения работают хорошо и работают как ожидалось.

Приложение - это api для отдыха, используемое для поиска разных пользователей.

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

Если пользователь с любым идентификатором найден, api отвечает 200 OK, если нет, отвечает 404 Not Found в соответствии с. HTTP/1.1 Сбой кода состояния.

Нередко наш api отвечает на 404 Not Found на множество запросов, и из-за этого эластичный beanstalk переносит нашу среду с OK на Warning или даже на Degraded. И похоже, что nginx отказался от подключения к приложению из-за этого ухудшенного состояния. (похоже, что он имеет пороговое значение 30% + в Warning и 50% + в Degraded). Это проблема, потому что приложение работает нормально, но настройки по умолчанию для эластичных beanstalks считают, что это проблема, когда это действительно не так.

Кто-нибудь знает, как отредактировать порог предупреждений 4xx и переходов состояний в EB или полностью отключить их?

Или я действительно должен сделать лечение симптомов и перестать использовать 404 Not Found при вызове вроде этого? (мне действительно не нравится этот вариант)

4b9b3361

Ответ 1

После погружения в экземпляр EB и проведя несколько часов в поисках того, где демон по проверке работоспособности EB действительно сообщает коды статуса обратно в EB для оценки, я, наконец, нашел его и придумал патч, который может служить прекрасным обходным решением для предотвращения 4xx кода ответа от превращения среды в состояние состояния среды Degraded, а также без уведомления об этом электронном письме:

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

Логика представления кода состояния находится в healthd-appstat, Ruby script, разработанном командой EB, которая постоянно контролирует /var/log/nginx/access.log и сообщает коды статуса EB, в частности, по следующему пути:

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

В следующем файле .ebextensions будет исправлен этот Ruby script, чтобы избежать сообщения кодов ответов 4xx обратно в EB. Это означает, что EB никогда не ухудшит состояние окружающей среды из-за ошибок 4xx, потому что просто не будет знать, что они происходят. Это также означает, что на странице "Здоровье" в вашей среде EB всегда будет отображаться 0 для кода ответа 4xx.

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

Да, это немного уродливо, но он выполняет свою работу, по крайней мере, до тех пор, пока команда EB не предоставит возможность игнорировать ошибки 4xx через некоторый параметр конфигурации. Включите его с вашим приложением при развертывании в следующем пути относительно корневого каталога вашего проекта:

.ebextensions/ignore_4xx.config

Удачи, и дайте мне знать, помогли ли это!

Ответ 2

Спасибо за ваш ответ Elad Nava, у меня была такая же проблема, и ваше решение отлично сработало для меня!

Однако после открытия билета в Центре поддержки AWS они рекомендовали мне изменить конфигурацию nginx, чтобы игнорировать 4xx в Health Check вместо изменения ruby ​​script. Для этого мне также пришлось добавить файл конфигурации в каталог .ebextensions, чтобы перезаписать файл nginx.conf по умолчанию:

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

Хотя это решение довольно многословно, я лично считаю, что это безопаснее реализовать, если оно не зависит от каких-либо проприетарных устройств AWS script. Я имею в виду, что если по какой-то причине AWS решает удалить или изменить свой ruby ​​script (поверьте мне или нет, они любят менять сценарии без предварительного уведомления), есть большая вероятность, что обходной путь с sed будет не работает больше.

Ответ 3

Вот решение, основанное на ответе Адриано Валенте. Я не мог получить бит $loggable, хотя пропустить регистрацию для 404-х кажется, что это будет хорошим решением. Я просто создал новый .conf файл, который определил переменную $modstatus, а затем перезаписал формат журнала healthd, чтобы использовать $modstatus вместо $status. Это изменение также потребовало перезагрузки nginx. Это работает на Elastic Beanstalk 64bit Amazon Linux 2016.09 v2.3.1 с 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 '[email protected]\[email protected][email protected]' /opt/elasticbeanstalk/support/conf/webapp_healthd.conf
  modify_nginx_3:
    command: sudo /etc/init.d/nginx restart

Ответ 4

Основываясь на Elad Nava Answer, я считаю, что лучше использовать свойство healthbeanstalk healthd control script непосредственно вместо 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"

Наконец, при изучении этой проблемы я заметил, что коды состояния журнала healthd и apache по-разному относятся к первому, используя% s, а последние% > s приводят к расхождениям между ними. Я также исправил это, используя:

    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