このトピックでは、Classic Load Balancer (CLB) のヘルスチェックに関する問題を特定し、解決する方法について説明します。
このトピックでは、次の質問に回答します:
|
カテゴリ |
一般的な質問 |
|
仕組みと設定 |
|
|
トラブルシューティング |
|
|
ロギング |
ヘルスチェックの仕組み
ヘルスチェックは、定期的にリクエストを送信してサーバーのステータスを確認します。
CLB はクラスターにデプロイされます。このクラスター内のノードは、データ転送とヘルスチェックの両方を実行します。バックエンドサーバーがヘルスチェックに失敗した場合、CLB はその異常なサーバーへの新しいクライアントリクエストの転送を停止します。
CLB はヘルスチェックに 100.64.0.0/10 の CIDR ブロックを使用します。ご利用のバックエンドサーバーは、このアドレス範囲からのトラフィックをブロックしてはいけません。ご利用の ECS セキュリティグループに許可ルールを追加する必要はありませんが、iptables などの他のセキュリティポリシーを設定している場合は、この CIDR ブロックからのトラフィックを許可する必要があります。100.64.0.0/10 の範囲は Alibaba Cloud の予約済みアドレス空間であり、セキュリティリスクはありません。
詳細については、「CLB のヘルスチェック」をご参照ください。
推奨されるヘルスチェック設定
以下のヘルスチェック設定を推奨します。
|
パラメーター |
TCP/HTTP/HTTPS リスナー |
UDP リスナー |
|
ヘルスチェック応答タイムアウト |
5秒 |
10秒 |
|
ヘルスチェック間隔 |
2秒 |
5秒 |
|
正常しきい値 |
3 |
3 |
|
異常しきい値 |
3 |
3 |
頻繁なステータス変更がシステムの可用性に影響を与えるのを防ぐため、ヘルスチェックは、タイムウィンドウ内で複数回連続して成功または失敗した場合にのみステータスを変更します。詳細については、「CLB ヘルスチェックの設定と管理」をご参照ください。
障害をより迅速に検出するために、応答タイムアウトを短くすることができます。ただし、ご利用のサービスがこの期間内に応答できることを確認する必要があります。
ヘルスチェックは無効にできますか?
はい。詳細については、「ヘルスチェックの無効化」をご参照ください。
-
ヘルスチェックを無効にすると、CLB は異常なインスタンスを含むすべてのバックエンド Elastic Compute Service (ECS) インスタンスにリクエストを転送するため、サービスが中断される可能性があります。
-
ご利用のサービスが負荷に敏感な場合、高頻度のヘルスチェックが通常のサービスアクセスに影響を与える可能性があります。ヘルスチェックの頻度を減らす、間隔を長くする、またはレイヤー 4 のヘルスチェックに切り替えることで、影響を軽減できます。ただし、継続的なサービスの可用性を確保するため、ヘルスチェックを無効にすることは推奨しません。
TCP リスナーのヘルスチェックメソッドの選択方法
TCP リスナーは、HTTP と TCP のヘルスチェックメソッドをサポートしています:
-
TCP メソッドは、SYN パケットを送信して基本的な 3 ウェイハンドシェイクを実行し、サーバーポートがアクティブであることを確認します。
-
HTTP メソッドは、HEAD または GET リクエストを送信してブラウザのアクセスをシミュレートし、サーバーアプリケーションが正常であるかを確認します。
TCP ヘルスチェックは、サーバーリソースの消費が少なくなります。バックエンドサーバーが負荷に非常に敏感で、ポートの可用性を確認するだけでよい場合は、TCP メソッドを選択してください。アプリケーションのヘルスチェックステータスをより正確に確認する必要がある場合は、HTTP メソッドを選択してください。
ECS インスタンスの重みをゼロに設定した場合の影響
バックエンド ECS インスタンスの重みを 0 に設定すると、CLB はそのインスタンスへのトラフィック転送を停止しますが、ヘルスチェックは引き続き成功します。この方法は、再起動や設定変更などの計画的なメンテナンス中によく使用されます。
HTTP ヘルスチェックのデフォルトメソッド
HEAD メソッドです。
ECS インスタンス上で、プライベート IP アドレスに HEAD リクエストを送信してローカルでテストすることを推奨します:
curl -v -0 -I -H "Host:" -X HEAD http://IP:port
ヘルスチェックの送信元 IP アドレス
CLB のヘルスチェックは 100.64.0.0/10 の CIDR ブロックを使用します。バックエンドサーバーがこの CIDR ブロックをブロックしていないことを確認する必要があります。ご利用の ECS セキュリティグループに特定の許可ルールを追加する必要はありませんが、iptables などの他のセキュリティポリシーを使用している場合は、このブロックからのトラフィックを許可する必要があります。100.64.0.0/10 の CIDR ブロックは Alibaba Cloud が使用する予約済みアドレス空間であり、セキュリティリスクはありません。
CLB のヘルスチェックはいつ開始されますか?
CLB のヘルスチェックは、リスナーに設定するとすぐに開始され、指定されたヘルスチェック間隔で定期的にリクエストを送信します。
データベースの障害によるヘルスチェックの失敗
-
症状
ある ECS インスタンスが 2 つの Web サイト、
www.example.com(静的 Web サイト) とaliyundoc.com(動的 Web サイト) をホストしており、両方に負荷分散が設定されています。バックエンドのデータベースサービスに問題が発生したため、www.example.comにアクセスすると 502 エラーが発生します。 -
原因
ヘルスチェックドメインとして
aliyundoc.comが設定されています。バックエンドの ApsaraDB RDS インスタンスまたは自己管理データベースに障害が発生すると、aliyundoc.comにアクセスできなくなり、バックエンドサーバー全体のヘルスチェックが失敗します。 -
ソリューション
CLB リスナー設定のヘルスチェックドメインを、
www.example.comのようにデータベースに依存しない静的なドメインに変更します。
TCP ヘルスチェックが成功しているにもかかわらず発生する接続エラー
-
症状
CLB で TCP リスナーを設定した後、バックエンドアプリケーションのログにネットワーク接続エラーが頻繁に表示されます。パケットキャプチャ分析によると、リクエストは CLB サーバーから発信されており、CLB サーバーが接続を終了するために RST パケットを積極的に送信していることがわかります。
java.io.IOException Connection reset by peer at sun.nio.ch.FileDispatcherImpl.read0(Native Method) at sun.nio.ch.SocketDispatcher.read(SocketDispatcher.java:39) at sun.nio.ch.IOUtil.readIntoNativeBuffer(IOUtil.java:223) at sun.nio.ch.IOUtil.read(IOUtil.java:192) at sun.nio.ch.SocketChannelImpl.read(SocketChannelImpl.java:379) at io.netty.buffer.UnpooledUnsafeDirectByteBuf.setBytes(UnpooledUnsafeDirectByteBuf.java:446) at io.netty.buffer.AbstractByteBuf.writeBytes(AbstractByteBuf.java:871) at io.netty.channel.socket.nio.NioSocketChannel.doReadBytes(NioSocketChannel.java:225) at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:115) at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:507) at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:464) at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:378) at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:350) at io.netty.util.concurrent.SingleThreadEventExecutor$2.run(SingleThreadEventExecutor.java:116) at java.lang.Thread.run(Thread.java:745) -
原因
この問題は、TCP ヘルスチェックの仕組みが原因で発生します。CLB は、3 ウェイハンドシェイクを完了し、すぐに RST パケットを送信して接続を閉じることで、TCP リスナーのポートの状態を確認します。プロセスは次のとおりです:
-
CLB サーバーがバックエンドサーバーに SYN パケットを送信します。
-
バックエンドサーバーが SYN+ACK パケットで応答します。
-
応答を受信した後、CLB サーバーはポートが正常であると判断し、ヘルスチェックを成功としてマークします。
-
CLB サーバーは、アプリケーションデータを送信せずに接続を終了するために RST パケットを送信します。
ヘルスチェックが成功した直後に接続が終了するため、一部のアプリケーションフレームワーク (Java の接続プールなど) はこれを異常な接続と解釈し、
Connection reset by peerなどのエラーが発生する可能性があります。 -
-
ソリューション
-
リスナーのヘルスチェックプロトコルを TCP から HTTP に変更します。
-
アプリケーションレベルで、CLB ヘルスチェックの CIDR ブロック (100.64.0.0/10) からのログエントリをフィルタリングして、これらの予期されるエラーを無視します。
-
正常なサーバーでのヘルスチェック失敗
-
症状
CLB リスナーの HTTP ヘルスチェックは一貫して失敗しますが、バックエンドサーバーを
curlコマンドで直接テストすると、正常なステータスコードが返されます。 -
原因
サーバーの HTTP 応答コードがリスナー設定で期待されるステータスコードと一致しない場合、ヘルスチェックは失敗します。たとえば、期待されるステータスコードとして
http_2xxを設定した場合、バックエンドサーバーからの 2xx 以外の応答はヘルスチェックの失敗と見なされます。Tengine/Nginx の設定では、
curlコマンドは問題なく実行されますが、echoコマンドはデフォルトサイトにマッチするため、テストファイル test.html は 404 エラーを返します。[root@iZ28sxxxZ home]# echo -e "HEAD /test.html HTTP/1.0\r\n\r\n" | nc -t 10.161.93.136 80 HTTP/1.1 404 Not Found Server: Tengine/2.1.0 Date: Mon, 16 Feb 2015 07:29:32 GMT Content-Type: text/html Content-Length: 585 Connection: close [root@iZ28sxxxZ home]# curl -I http://10.161.93.136/test.html HTTP/1.1 200 OK Server: Tengine/2.1.0 Date: Mon, 16 Feb 2015 07:29:41 GMT Content-Type: text/html Content-Length: 5 Last-Modified: Mon, 16 Feb 2015 07:27:00 GMT Connection: keep-alive ETag: "54e19bc4-5" Accept-Ranges: bytes -
ソリューション
-
Web サーバーのメイン設定ファイルで、デフォルトのバーチャルホストをコメントアウトするか、正しく設定します。
-
CLB リスナーのヘルスチェック設定でヘルスチェックドメインを指定し、リクエストが正しいバーチャルホストにルーティングされるようにします。
-
ログにおけるヘルスチェック頻度の不一致
CLB のヘルスチェックサービスは、単一障害点を防ぐためにノードのクラスター上で実行されます。クラスター内の各ノードは独立してヘルスチェックを実行します。このアーキテクチャにより、バックエンドサーバーに送信されるヘルスチェックリクエストの総数が増加します。その結果、ご利用の Web サーバーのログにおけるヘルスチェックエントリの頻度は、コンソールで設定した頻度よりも高くなります。これは予期された動作です。
ヘルスチェックログとアプリケーションログの分離方法
-
症状
ヘルスチェックのリクエストログが通常のアプリケーショントラフィックのログと混在し、ログファイルが大きくなり分析が困難になります。
-
原因
ヘルスチェックは、HTTP、TCP、または UDP リクエストを送信してバックエンドサーバーの可用性をテストします。これらのリクエストは、他のトラフィックと同様にバックエンドサービスによってログに記録され、アプリケーションログと混在します。
-
ソリューション
-
ヘルスチェックの頻度を減らす: [ヘルスチェック間隔] を長くして、生成されるヘルスチェックログのエントリを減らします。
-
専用のヘルスチェックパスを使用する (HTTP ヘルスチェックの場合): [ヘルスチェックパス] を
/healthのような専用の非ビジネスパスに設定します。これにより、リクエストパスでログをフィルタリングして、ヘルスチェックのトラフィックを分離できます。 -
ヘルスチェックを無効にする (非推奨): ユースケースでヘルスチェックが不要であることが確実な場合は、ヘルスチェックを無効にしてログの生成を停止できます。
-
ヘルスチェック失敗のトラブルシューティング方法
ヘルスチェックは、バックエンドサーバーが正常に動作しているかどうかを判断します。ヘルスチェックが失敗した場合、多くはバックエンドサーバーの問題を示しますが、不適切なヘルスチェック設定が原因で失敗することもあります。次の手順に従って問題をトラブルシューティングしてください。
-
ステップ 1:
100.64.0.0/10CIDR ブロックがブロックされていないことを確認します。バックエンドサーバーが iptables や他のサードパーティ製のファイアウォールまたはセキュリティソフトウェアを使用して
100.64.0.0/10CIDR ブロックをブロックしていないことを確認してください。CLB は100.64.0.0/10の内部予約済み CIDR ブロックの IP アドレスを使用してバックエンドサーバーと通信します。この CIDR ブロックがブロックされていると、ヘルスチェックの異常が発生します。 -
ステップ 2: リスナープロトコルに基づいてバックエンドサービスをプローブする
リスナーのタイプに基づいて適切なプロービング方法を選択してください:
レイヤー 4 (TCP/UDP)
CLB コンソールでリスナー詳細ページに移動し、ヘルスチェック設定と、デフォルトでバックエンドサーバーポートになるヘルスチェックのポート番号を確認します。次に、サーバーにアクセスできるマシンから
telnetコマンドを実行し、ヘルスチェックポートへの接続を試みます:telnet 172.17.58.131 80172.17.58.131をバックエンドサーバーのプライベート IP アドレスに、80を実際のヘルスチェックポートに置き換えてください。-
正常な場合:
Connected to xxx.xxx.xxx.xxxが返され、バックエンドサーバーの指定されたポートが正常に動作しており、ヘルスチェックが正常であることを示します。 -
予期しない結果: コマンドが「Connection refused」または「Unable to connect」というメッセージで失敗します。これは、そのポートでリッスンしているプロセスがないことを示します。バックエンドサービスが実行中であり、ヘルスチェック設定で指定されたポートでリッスンしていることを確認してください。
レイヤー 4 リスナーがヘルスチェックに HTTP メソッドを使用している場合は、「レイヤー 7 (HTTP/HTTPS)」タブのトラブルシューティング手順をご参照ください。
レイヤー 7 (HTTP/HTTPS)
CLB コンソールでリスナー詳細ページに移動し、レイヤー 7 ヘルスチェック設定の ヘルスチェックのポート番号、ヘルスチェックドメイン名、および ヘルスチェックへのパス を確認します。 次に、バックエンドサーバー (例えば、Linux システム) から
ncまたはcurlコマンドを実行し、バックエンド HTTP サービスをプローブします。 ヘルスチェックのパス、ポート、およびドメインは、バックエンドサーバー上の実際の構成と一致している必要があります。 一致していない場合、ヘルスチェックは失敗します。nc コマンドを使用した例:
echo -e "HEAD /test.html HTTP/1.0\r\nHost: www.slb-test.com\r\n\r\n" | nc -t 172.17.58.131 80パス、ドメイン、IP、およびポートを、ご利用の環境の値に置き換えてください。
-
正常な場合: ステータスコード
200または別の2xx/3xxが返され、バックエンドの HTTP サービスが正常であり、ヘルスチェックが成功したことを示します。 -
異常な状況:
404などのエラーコードが返され、CLB リスナーに設定された2xx/3xxステータスコードと一致しません。ヘルスチェックパスのリソースが存在するか、ヘルスチェックドメインがバックエンドサーバーに設定されているか、ヘルスチェックポートが正しいかを確認してください。
-
コンソールで CLB ヘルスチェックの失敗レコードが見つからない理由
ヘルスチェックログは 1 時間に 1 回生成され、デフォルトでは 3 日間しか保持されません。CLB リスナーのヘルスチェックステータスが 3 日以内に変更されない場合、ヘルスチェックログは生成されません。ヘルスチェックログを OSS に保存して、より長期間保持することができます。