Elastic Beanstalkで実行しているREST APIがありますが、これは非常に効果的です。アプリケーションのすべてが正常に動作し、期待どおりに動作しています。
アプリケーションは、さまざまなユーザーを検索するために使用されるREST APIです。
example url: http://service.com/user?uid=xxxx&anotherid=xxxx
いずれかのIDを持つユーザーが見つかった場合、APIは200 OK
で応答し、そうでない場合は404 Not Found
で応答します。 HTTP/1.1
ステータスコードの定義。
私たちのapiが多くのリクエストで404 Not Found
に応答することは珍しくなく、エラスティックBeantalkは環境をOK
からWarning
またはDegraded
に転送します。 。また、この状態が悪化したため、nginx
がアプリケーションへの接続を拒否したようです。 (warning
への30%+およびdegraded
状態への50%+のしきい値があるように見えます。これは問題です。アプリケーションは実際に期待どおりに動作していますが、Elastic Beanstalksのデフォルト設定考えるそれは本当にそうでないとき、それは問題です。
誰でも4xx警告のしきい値とEBの状態遷移を編集する方法、またはそれらを完全に無効にする方法を知っていますか?
または、実際に症状の治療を行い、このような呼び出しで404 Not Found
の使用を停止する必要がありますか? (私は本当にこのオプションが好きではありません)
更新:AWS EBには、このための組み込み設定が最終的に含まれています: https://stackoverflow.com/a/51556599/1123355
旧ソリューション: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常に/var/log/nginx/access.log
を監視し、ステータスコードをEBにレポートするEBチームによって開発されたスクリプト次のパス:
/opt/elasticbeanstalk/lib/Ruby/lib/Ruby/gems/2.2.0/gems/healthd-appstat-1.0.1/lib/healthd-appstat/plugin.rb
次の.ebextensions
ファイルは、これにパッチを適用しますRubyスクリプトは4xx
応答コードのEBへの報告を回避します。これは、EBが4xx
エラーは、それらが発生していることを知らないだけであるため、EB環境の[Health]ページには、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
幸運を祈ります。これが助けになったら教えてください!
あなたの答えをありがとう Elad Nava 、私は同じ問題を抱えていて、あなたの解決策は私にとって完璧に働いた!
ただし、AWSサポートセンターでチケットを開いた後、Rubyスクリプトを変更する代わりに、ヘルスチェックで4xxを無視するようにnginx
構成を変更することを推奨しました。 、デフォルトの.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独自のスクリプトに依存しない限り、実装する方が安全であると個人的に考えています。つまり、何らかの理由でAWSがRubyスクリプト(信じられないかもしれませんが、予告なしにスクリプトを変更するのが大好きです)を削除または変更することに決めた場合、 sed
を使用した回避策はもう機能しません。
Adriano Valenteの答え に基づいたソリューションがあります。 $loggable
ビットを動作させることができませんでしたが、404のロギングをスキップすることは良い解決策のようです。 .conf
変数を定義した新しい$modstatus
ファイルを作成し、healthd
ログ形式を上書きして、$modstatus
の代わりに$status
を使用しました。この変更では、nginxを再起動する必要がありました。これは、Ruby 2.3(Puma))を実行しているElastic Beanstalkの64ビットAmazon Linux 2016.09 v2.3.1で動作しています。
# .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
私は最近、あなたと同じように4xxエラーで攻撃されたという同じ問題に遭遇しました。上記の提案を試しましたが、うまくいきませんでした。私はAWSサポートに連絡しましたが、ここに彼らが提案したものがあり、それが私の問題を解決しました。 2つのインスタンスが実行されているElastic Beanstalkアプリケーションがあります。
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/*;
}
2018年4月の時点でAWSサポートによって提供されているソリューション:
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"
Elad Nava's Answer に基づいて、killの代わりにelasticbeanstalk healthdの制御スクリプトを直接使用する方が良いと思います:
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"
最後に、この問題を調査するときに、healthとApacheがステータスコードを変更することに気付きました。私もこれをパッチしました:
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