【Apache】【Tomcat】(70007)The timeout specified has expired: ajp_ilink_receive() can't receive header

Web サーバーで通信断が発生しました。

「/var/log/httpd/error_log」を確認したところ、以下のメッセージが出力されていました。

[error] (70007)The timeout specified has expired: ajp_ilink_receive() can't receive header
[error] ajp_read_header: ajp_ilink_receive failed
[error] (70007)The timeout specified has expired: proxy: read response failed from [::1]:8009 (localhost)

 

原因と対策を調査します。

 

 

 

調査個所&方法

ログを調査します。

調査するログ

 

 

調査するポート

ApacheとTomcatの連携なので「8009番ポート」を確認します。

[root@cent07 ~]# netstat -t | egrep "^tcp.*:8009"

 

Tomcat は「8009番ポート」で AJP の通信を受け付けています。

AJP とは「Apache JServ Protocol」の略です。

 

 

ab(ApacheBench)コマンドを実行してみる

httpd をインストールすると ab コマンドもインストールされます。

[root@cent07 ~]# ab
ab: wrong number of arguments
Usage: ab [options] [http[s]://]hostname[:port]/path
Options are:
    -n requests     Number of requests to perform
    -c concurrency  Number of multiple requests to make at a time
    -t timelimit    Seconds to max. to spend on benchmarking
                    This implies -n 50000
    -s timeout      Seconds to max. wait for each response
                    Default is 30 seconds
    -b windowsize   Size of TCP send/receive buffer, in bytes
    -B address      Address to bind to when making outgoing connections
    -p postfile     File containing data to POST. Remember also to set -T
    -u putfile      File containing data to PUT. Remember also to set -T
    -T content-type Content-type header to use for POST/PUT data, eg.
                    'application/x-www-form-urlencoded'
                    Default is 'text/plain'
    -v verbosity    How much troubleshooting info to print
    -w              Print out results in HTML tables
    -i              Use HEAD instead of GET
    -x attributes   String to insert as table attributes
    -y attributes   String to insert as tr attributes
    -z attributes   String to insert as td or th attributes
    -C attribute    Add cookie, eg. 'Apache=1234'. (repeatable)
    -H attribute    Add Arbitrary header line, eg. 'Accept-Encoding: gzip'
                    Inserted after all normal header lines. (repeatable)
    -A attribute    Add Basic WWW Authentication, the attributes
                    are a colon separated username and password.
    -P attribute    Add Basic Proxy Authentication, the attributes
                    are a colon separated username and password.
    -X proxy:port   Proxyserver and port number to use
    -V              Print version number and exit
    -k              Use HTTP KeepAlive feature
    -d              Do not show percentiles served table.
    -S              Do not show confidence estimators and warnings.
    -q              Do not show progress when doing more than 150 requests
    -g filename     Output collected data to gnuplot format file.
    -e filename     Output CSV file with percentages served
    -r              Don't exit on socket receive errors.
    -h              Display usage information (this message)
    -Z ciphersuite  Specify SSL/TLS cipher suite (See openssl ciphers)
    -f protocol     Specify SSL/TLS protocol
                    (SSL3, TLS1, TLS1.1, TLS1.2 or ALL)
[root@cent07 ~]#

 

 

tcpdump でパケットキャプチャする

パケットの中身を見ることが出来ればほとんど原因を特定することができます。

 

tcpdumpのインストールと使い方 パケット解析をする

 

 

FWでコネクションを切断していないか確認する

FWでコネクションを切断していても Tomcat 側では「ESTABLISHED」だと勘違いするらしいです。(切断されたことが通知されないらしいです)

http://d.hatena.ne.jp/mercystage/20090105/1314536504

 

 

 

timeout が発生した原因

timeoutが発生した原因については以下の可能性があります。

 

リクエストを処理するのに時間が掛かりすぎている

リクエストがノード側で処理されるのに時間がかかっている可能性があります。

アプリケーションの処理を確認し、タイムアウト時間を延ばす場合は、ノードのタイムアウト値を追加します。

タイムアウト値は各ノードごとに設定することができます。

 

また、ノード上のバランサーの設定が適切でない可能性があります。元々どの値で、どのように設定を変更したのかを調べます。

 

 

 

Tomcatの「server.xml」の値を調べてみます。

<Connector executor="tomcatThreadPool"
               port="8080" protocol="HTTP/1.1"
               connectionTimeout="600000" ← ミリ秒単位なので注意(600000ミリ秒 ← 600秒)
               redirectPort="8443" />

 

 

【Apache】httpd.conf の変更

コンフィグファイルのここを修正 or 設定すれば確実に復旧できるというものはありません。

そのためいくつかの値を総合的に調整していきます。

 

Apacheの httpd.conf の

の値を調べてみます。

 

TimeOut

クライアントとの間でデータのパケットをやりとりするときに待機する最長の時間を設定します。

Apache は、指定されている時間に達してもパケットを受け取れないと接続を切断します。

時間は秒単位でデフォルトは300秒です。

接続しているネットワークが遅く、頻繁に接続が中断するようなことがない限り、この設定を変える必要はありません。

接続が頻繁に中断するようなら、値を増やして、切断の回数を減らすようにします。

TimeOut 600 ← 単位は「秒」。600は10分(600秒)になります。

 

 

KeepAlive

Webブラウザとの間で持統的な接続を維持するかどうかを指定できます。

持続的な接続では、1つの要求が完了するたびに接続を閉じて次の要求に対して新しく接続を開く代わりに、複数の要求で同じ接統を繰り返し使うことができます。

持統的接続を使うと、サーパーのオーバーヘッドが減り、パフオーマンスが向上するので、この設定は「on」のままにしておきます。

KeepAliveを「ON」にすると復旧することもあります。

 

MaxKeepAliveRequests

一回の接続で処理できるリクエストの数を指定します。

もしタイムアウトやエラーが発生する場合は、なるべく大きい値に設定します。

値が大きければ大きいほど、1回の接続で処理できるリクエストの数も多くなります。

※ただし、同時に KeepAlive の値を「on」に設定しておく必要があります。

 

 

KeepAliveTimeout

1つのリクエストが完了してから、接続を中断せずに次の新しいリクエストを待つ時間(秒)です。

 

ProxyPass

ProxyPass を利用しプロキシサーパーを設定して、リモートサイトのコンテンツがあたかもローカルにあるように見せることができます。

この ProxyPass でリモートにある Web サーバーのドキュメントツリーを、あたかもプロキシサーパーのドキュメントツリーの下にあるように見せかけることができます。

この値に紐付いている「keepalive」の値を「on」に設定します。←「keepalive=on」

 

 

 

コンフィグを設定変更したらサービスの再起動を忘れずに

httpd.conf の値を変更したらサービスの再起動を実施します。

# systemctl restart httpd.service

 

 

【Tomcat】server.xmlの変更

Tomcatの「server.xml」の値を調べてみます。

connectionTimeoutの値を調べて調節します。

<Connector executor="tomcatThreadPool"
               port="8080" protocol="HTTP/1.1"
               connectionTimeout="60000" ← ミリ秒単位なので注意(60000ミリ秒 ← 60秒)
               redirectPort="8443" />

 

「Tomcat」connectionTimeout について

http://a4dosanddos.hatenablog.com/entry/2013/07/18/233208

 

 

http://tomcat.apache.org/tomcat-7.0-doc/config/http.html

 

connectiontimeoutについて

The number of milliseconds this Connector will wait, after accepting a connection, for the request URI line to be presented. Use a value of -1 to indicate no (i.e. infinite) timeout. The default value is 60000 (i.e. 60 seconds) but note that the standard server.xml that ships with Tomcat sets this to 20000 (i.e. 20 seconds). Unless disableUploadTimeout is set to false, this timeout will also be used when reading the request body (if any).

リクエストURI行が表示されるために、このコネクタが接続を受け入れた後に待機する時間をミリ秒数で設定します。 無限(つまり無限)のタイムアウトを示すには、-1の値を使用します。 デフォルト値は60000(60秒)ですが、Tomcatに同梱されている標準のserver.xmlは20000(つまり20秒)に設定されています。 disableUploadTimeoutがfalseに設定されていない限り、このタイムアウトは要求本体(存在する場合)を読み取るときにも使用されます。

 

まだ試していませんが、このコネクションタイムアウトの時間が経過すると FIN パケットを送信されるようです。

 

tcpdumpのインストールと使い方 パケット解析をする

 

 

 

その他対応方法

その他の対応方法です。

 

OSを再起動する

一度 OS を再起動してみます。

 

AJPを利用せずにhttpを使う

AJP のバグを疑い、AJP を利用するのではなく、tomcat の http server と連携します。

mod_proxyのバグ

https://bz.apache.org/bugzilla/show_bug.cgi?id=38227

 

 

 

参考サイト

http://blog.hiroaki.home.group.jp/2009/05/ajpreadheader-ajpilinkreceive-failed.html

 

 

Posted by 100%レンタルサーバーを使いこなすサイト管理人