ネットワークロードバランサーと、EC2インスタンスでヘルスチェックを行うように構成された関連ターゲットグループがあります。問題は、非常に多くのヘルスチェックリクエストが表示されることです。毎秒複数。
チェック間の デフォルトの間隔 は30秒であると想定されていますが、通常よりも約100倍頻繁に来ています。
私のスタックはCloudFormationで構築されており、HealthCheckIntervalSeconds
をオーバーライドしようとしましたが、効果はありません。興味深いことに、コンソールで間隔を手動で変更しようとすると、これらの値がグレーアウトされていることがわかりました。
ここにテンプレートの関連部分がありますが、間隔を変更する試みはコメント化されています。
NLB:
Type: "AWS::ElasticLoadBalancingV2::LoadBalancer"
Properties:
Type: network
Name: api-load-balancer
Scheme: internal
Subnets:
- Fn::ImportValue: PrivateSubnetA
- Fn::ImportValue: PrivateSubnetB
- Fn::ImportValue: PrivateSubnetC
NLBListener:
Type : AWS::ElasticLoadBalancingV2::Listener
Properties:
DefaultActions:
- Type: forward
TargetGroupArn: !Ref NLBTargetGroup
LoadBalancerArn: !Ref NLB
Port: 80
Protocol: TCP
NLBTargetGroup:
Type: AWS::ElasticLoadBalancingV2::TargetGroup
Properties:
# HealthCheckIntervalSeconds: 30
HealthCheckPath: /healthcheck
HealthCheckProtocol: HTTP
# HealthyThresholdCount: 2
# UnhealthyThresholdCount: 5
# Matcher:
# HttpCode: 200-399
Name: api-nlb-http-target-group
Port: 80
Protocol: TCP
VpcId: !ImportValue PublicVPC
私のEC2インスタンスはプライベートサブネットにあり、外部からアクセスできません。 NLBは内部にあるため、API Gatewayを経由せずにNLBにアクセスする方法はありません。 API Gatewayには/healthcheck
エンドポイントが設定されていないため、エンドポイントに手動でpingを実行するなど、AWSネットワークの外部からのアクティビティは除外されます。
これは、CloudWatchから取得したアプリのログのサンプルですが、アプリはアイドル状態である必要があります。
07:45:33 {"label":"Received request URL","value":"/healthcheck","type":"trace"}
07:45:33 {"label":"Received request URL","value":"/healthcheck","type":"trace"}
07:45:33 {"label":"Received request URL","value":"/healthcheck","type":"trace"}
07:45:33 {"label":"Received request URL","value":"/healthcheck","type":"trace"}
07:45:34 {"label":"Received request URL","value":"/healthcheck","type":"trace"}
07:45:34 {"label":"Received request URL","value":"/healthcheck","type":"trace"}
07:45:34 {"label":"Received request URL","value":"/healthcheck","type":"trace"}
07:45:35 {"label":"Received request URL","value":"/healthcheck","type":"trace"}
07:45:35 {"label":"Received request URL","value":"/healthcheck","type":"trace"}
07:45:35 {"label":"Received request URL","value":"/healthcheck","type":"trace"}
私は通常毎秒3から6のリクエストを受け取っているので、これがNetwork Load Balancerの動作方法なのか疑問に思っています。この問題を修正する可能性があります。
更新:これは、関連する awsフォーラムの投稿 で回答されています。これは、ネットワークロードバランサーの正常な動作を確認し、その分散された性質を理由として挙げています。カスタム間隔を構成する方法はありません。現時点では、ドキュメントはまだ古く、別の方法で指定しています。
これは、NLBターゲットグループのバグか、誤った ドキュメント の通常の動作です。私はこの結論に達しました:
この場合、間違って文書化されているのは正常な動作かもしれませんが、AWSの誰かができない限りそれを検証する方法はなく、 このような問題 awsフォーラム。
設定を構成できるか、少なくともドキュメントを更新できると便利です。
AWSの従業員はこちら。受け入れられた答えを少し詳しく説明すると、ヘルスチェック要求のバーストが表示される理由は、NLBが複数の分散ヘルスチェッカーを使用してターゲットのヘルスを評価するためです。これらの各ヘルスチェッカーは、指定した間隔でターゲットにリクエストを送信しますが、それらはすべて、そのインターバルでリクエストを送信するため、各分散プローブから1つのリクエストが表示されます。その後、ターゲットの健全性は、成功したプローブの数に基づいて評価されます。
ここで別のAWS従業員が書いた非常に詳細な説明は、「A Route 53ヘルスチェックを見て」で読むことができます。 https://medium.com/@adhorn/patterns-for-resilient-architecture-part- 3-16e8601c488e
ヘルスチェックに関する私の推奨事項は、ヘルスチェックを非常に軽量にコーディングすることです。多くの人は、ヘルスチェックをオーバーロードして、バックエンドデータベースのチェックや他のチェックの実行などの過ちを犯します。ロードバランサーのヘルスチェックは、「OK」などの短い文字列を返すだけであることが理想です。この場合、コードがヘルスチェックリクエストを処理するのに1ミリ秒未満かかります。このパターンに従えば、6〜8個のヘルスチェックリクエストがときどきバーストしても、プロセスが過負荷になることはありません。
これに関するパーティーに少し遅れました。しかし、私にとってうまくいくのは、ELBからのヘルスチェック専用のスレッドを(C++)サービスにスピンアップさせることです。スレッドはソケット接続を待機してから、ソケットからの読み取りを待機します。またはエラーが発生します。次に、ソケットを閉じて、次のヘルスチェックpingの待機に戻ります。これは、ELBが常にトラフィックポートを使用するよりもずっと安価です。それは私のコードに攻撃されていると思わせるだけでなく、実際のクライアントにサービスを提供するために必要なすべてのロジスティクスなどをスピンアップします。