300接続後にApache Tomcatがチョークする


16

EC2でホストされているTomcatの前にApache Webサーバーがあり、インスタンスタイプは34GBのメモリを備えた非常に大きなものです。

私たちのアプリケーションは多くの外部Webサービスを扱っており、ピーク時間に要求に応答するのにほぼ300秒かかる非常にひどい外部Webサービスがあります。

ピーク時には、サーバーは約300のhttpdプロセスで停止します。ps -ef | grep httpd | wc -l = 300

私はグーグルで検索し、多くの提案を見つけましたが、何も機能していないようです。以下は、オンラインリソースから直接取得したいくつかの設定です。

ApacheとTomcatの両方で最大接続と最大クライアントの制限を増やしました。構成の詳細は次のとおりです。

// apache

   <IfModule prefork.c>
    StartServers 100
    MinSpareServers 10
    MaxSpareServers 10
    ServerLimit 50000
    MaxClients 50000
    MaxRequestsPerChild 2000
    </IfModule>

// tomcat

    <Connector port="8080" protocol="org.apache.coyote.http11.Http11NioProtocol"
           connectionTimeout="600000"
           redirectPort="8443"
           enableLookups="false" maxThreads="1500"
           compressableMimeType="text/html,text/xml,text/plain,text/css,application/x-javascript,text/vnd.wap.wml,text/vnd.wap.wmlscript,application/xhtml+xml,application/xml-dtd,application/xslt+xml"
           compression="on"/>

//Sysctl.conf

 net.ipv4.tcp_tw_reuse=1
 net.ipv4.tcp_tw_recycle=1
 fs.file-max = 5049800
 vm.min_free_kbytes = 204800
 vm.page-cluster = 20
 vm.swappiness = 90
 net.ipv4.tcp_rfc1337=1
 net.ipv4.tcp_max_orphans = 65536
 net.ipv4.ip_local_port_range = 5000 65000
 net.core.somaxconn = 1024

私は多くの提案を試みてきましたが、無駄に..これを修正する方法は?私はm2xlargeサーバーが300以上のリクエストを処理するはずだと確信しています。おそらく私の設定が間違っている可能性があります。

サーバーは、ピーク時と、[300秒遅延] Webサービスが応答するのを待機している300の同時要求があるときにのみチョークします。

netstatでtcp接続を監視していました

私はTIME_WAIT状態で約1000の接続を見つけましたが、パフォーマンスの面でそれが何を意味するのかわかりません。問題に追加する必要があると確信しています。

TOPの出力

 8902  root      25   0 19.6g 3.0g  12m S  3.3  8.8  13:35.77 java
 24907 membase   25   0  753m 634m 2528 S  2.7  1.8 285:18.88 beam.smp
 24999 membase   15   0  266m 121m 3160 S  0.7  0.3  51:30.37 memcached
 27578 apache    15   0  230m 6300 1536 S  0.7  0.0   0:00.03 httpd
 28551 root      15   0 11124 1492  892 R  0.3  0.0   0:00.25 top


 Output of free -m
 total       used       free     shared    buffers    cached
 35007       8470       26536    0          1         61
 8407        26599
 15999       15         15984

 output of iostat
 avg-cpu:  %user   %nice %system %iowait  %steal   %idle
      26.21    0.00    0.48    0.13    0.02   73.15

Device:            tps   Blk_read/s   Blk_wrtn/s   Blk_read   Blk_wrtn
sda1             14.36         4.77       329.37    9005402  622367592
sdb               0.00         0.00         0.00       1210         48

また、ピーク時には、membase server [local]への約10-15k tcp接続があります。

MODJKログにいくつかのエラーがあります。これにより、問題が明らかになることを願っています。

[Wed Jul 11 14:39:10.853 2012] [8365:46912560456400] [error]         ajp_send_request::jk_ajp_common.c (1630): (tom2) connecting to backend failed. Tomcat is probably not started or is listening on the wrong port (errno=110)
[Wed Jul 11 14:39:18.627 2012] [8322:46912560456400] [error] ajp_send_request::jk_ajp_common.c (1630): (tom2) connecting to backend failed. Tomcat is probably not started or is listening on the wrong port (errno=110)
[Wed Jul 11 14:39:21.358 2012] [8351:46912560456400] [error] ajp_get_reply::jk_ajp_common.c (2118): (tom1) Tomcat is down or refused connection. No response has been sent to the client (yet)
[Wed Jul 11 14:39:22.640 2012] [8348:46912560456400] [error] ajp_get_reply::jk_ajp_common.c (2118): (tom1) Tomcat is down or refused connection. No response has been sent to the client (yet)

Worker.properties
workers.tomcat_home=/usr/local/tomcat/
worker.list=loadbalancer
worker.tom1.port=8009
worker.tom1.host=localhost
worker.tom1.type=ajp13
worker.tom1.socket_keepalive=True
worker.tom1.connection_pool_timeout=600
worker.tom2.port=8109
worker.tom2.host=localhost
worker.tom2.type=ajp13
worker.tom2.socket_keepalive=True
worker.tom2.connection_pool_timeout=600
worker.loadbalancer.type=lb
worker.loadbalancer.balanced_workers=tom1,tom2
worker.loadbalancer.sticky_session=True
worker.tom1.lbfactor=1
worker.tom1.socket_timeout=600
worker.tom2.lbfactor=1
worker.tom2.socket_timeout=600

//解決済み

すべての貴重な提案に感謝します。AJP1.3コネクタのmaxThreads設定を見逃しました。今ではすべてが制御されているようです。

また、nginxのようなベースのサーバーも調べ始めます。


キープアライブの設定はどのようなものですか?
トム・オコナー

ページを読み込もうとすると、クライアントはどのようなエラーを返しますか?
シェーンマッデン

1
apache / httpdユーザーの最大許容オープンファイル記述を増やしましたか?
-golja

@Tom私のhttpd.confでのKeepAliveTimeout 10をアライブの設定を保持している
ジョン・タイタス

3
topこれらの時間の出力はどのように見えますか?どうfree -m?そして最後にiostat
ザイファー

回答:


13

ポート8009のAJP 1.3コネクタのmaxThreadsを増やしましたか?


1500は、Tomcatインスタンスごとに私が持っているものです
ジョンティタス

@john、すべてのコネクタに対してmaxThreads = "1500"を指定したと言っていますか?AJP 1.3コネクタ(ポート8009)のスタンザを投稿できますか?
HTTP500

これを指摘してくれてありがとう.. AJP1.3にはmaxThreads設定がまったくありません。
ジョンティタス

1
はい、maxThreadsをそのコネクターのスタンザに追加します。デフォルトは200です。
HTTP50012

6

Apacheのような、nginxまたはlighttpdApacheの前に非同期プロキシWebサーバーをセットアップすることを検討してください。Apacheはコンテンツを同期的に提供するため、クライアントが生成されたコンテンツを完全にダウンロードするまでワーカーはブロックされます(詳細はこちら)。非同期(非ブロッキング)プロキシを設定すると、通常状況が劇的に改善されます(nginxフロントエンドプロキシとして使用する同時実行Apacheワーカーの数を30から3-5に減らしていました)。


5

とにかくあなたが示したログから、あなたの問題はApacheではなくTomcatにあると思われます。Tomcatに接続しようとすると「エラー110」が発生した場合、Tomcatのリスニングソケットのリスニングバックログの設定に収まらない接続待ち行列があることを示しています。

From the listen manpage:
   The  backlog  parameter defines the maximum length the queue of pending 
   connections may grow to.  If a connection request arrives with
   the queue full the client may receive an error with an indication
   of ECONNREFUSED or, if the underlying protocol supports  
   retransmission, the request may be ignored so that retries succeed.

推測しなければならない場合、サーバーが「チョーク」しているときのHTTPリクエストの大部分は、Tomcatから何かが返ってくるのを待ってブロックされていると思われます。(tomcatにプロキシされるのではなく)apacheによって直接提供されるいくつかの静的コンテンツを取得しようとした場合、これは通常「チョーク」しているときでも動作するでしょう。

残念ながらTomcatには慣れていませんが、代わりにこれの並行性設定を操作する方法はありますか?

ああ、あなたはまた、外部のネットワークサービスのthatsがあることの接続数制限という可能性を検討する必要があるかもしれません、それはやっているあなたに、それはあなたが前面にやっているどのくらいの同時実行の操作も違いはありませんので、300までを実際に行うすべての接続が外部Webサービスの応答に依存している場合。

コメントの1つで、2分後にデータが古くなったと述べました。このサービスから取得した応答を2分間キャッシュして、外部Webサービスへの同時接続の量を減らすことをお勧めします。


2

これをトラブルシューティングする最初のステップは、Apacheのmod_statusを有効にして、そのレポートを調査することです。これを行うまで、実際には盲目的に歩いています。それは正しいことではありません。;-)

2番目に言及すること(私は自分が尋ねていなかった質問の答えを聞かれるのは嫌いですが...)は、より効率的で特別なフロントエンドサーバーを使用していますnginx

また、あなたは正確にやったrestartのapache、または単にgracefulLY 再読み込み、それを?:)


Apacheが再起動しました。グレースフルリロードではありません
ジョンティタス

とにかく、@ johntitus mod_statusはあなたの友達です。:)
poige

1

企業向けのあらゆる展開において、prefork MPMは選択できる最悪の選択です。他のMPMと比較して、スレッドの再起動は永遠にかかります。

少なくともワーカー MPM(apache 2.2以降)に切り替えるか、さらに良いことに、デフォルトのイベント MPM で現在の安定バージョン2.4.2にアップグレードします。

これらの両方は、非常に少ないオーバーヘッドで数千の同時接続を簡単に処理します。


ありがとう。TIME_WAIT接続は増加し続けます。サーバーが350接続で応答を停止する
ジョンティタス

1
私はそれが最悪の選択であることには同意しません-このコンテキストでは不適切な選択であり、スレッド化されたサーバーを使用することで問題が緩和される可能性がありますが、イベントベースのサーバー(nginxまたはlighttpd)を使用する方が良いでしょう。イベントベースのApacheは、エンタープライズ展開のIMHOから検討できるほど成熟していない。
symcbean

1

私はそれが古い話であることを知っていますが、私は2つの発言があります。

あり、ハードコードされた制限のためのServerLimitの指令が。 http://httpd.apache.org/docs/2.2/mod/mpm_common.html#serverlimitでは、最大20000 / 200Kであることがわかります。

サーバーにコンパイルされたServerLimit 20000のハード制限があります(prefork MPM 200000の場合)。これは、タイプミスによる不快な影響を避けるためのものです。

2番目のようにnodyboは、これらの2を1に設定することは非常に悪い考えだと述べました:

net.ipv4.tcp_tw_reuse=1
net.ipv4.tcp_tw_recycle=1

タイムウェイトを早期に再利用するということです。サーバーは、高負荷の下で間違ったクライアントと通信する場合があります。

私はそれを説明する非常に良い記事を見つけましたが、それはフランス語です;-) http://vincent.bernat.im/fr/blog/2014-tcp-time-wait-state-linux.html


0

34GBのメモリを備えた特大。

ビッグアイロンは、単にボトルネックを動かしているだけのウェブサービングをスケーリングする方法ではありません。しかし、これだけのメモリがある場合でも、特に次の場合、50000接続がシステムの能力を押し上げていると思います。

ピーク時には、サーバーは約300のhttpdプロセスで停止します

「サーバーチョーク」という意味を説明しておくと役に立ちます。

また、接続にこのような高い制限を設定することは非常に奇妙ですが、ヒステリシス(最小/最大スペアサーバー)には非常に低い制限を設定します。

あなたが提供したエラーの抽出では、「開いているファイルが多すぎる」という明確な情報は表示されませんが、開いているファイル記述子の数とulimit設定を調べることから始めます。


サーバーは通常のhtmlファイルにも応答しないように
チョークし

私は今、3000に...まだ同じ問題にMaxClientsを変更
ジョン・タイタス

0

おそらく、Apacheユーザーは許可されたファイルハンドルを使い果たしていますか?あなたはあなたの投稿でそれらにまったく言及しませんでした。現在、Apacheに許可されているファイルハンドルの数はいくつですか?


128192ファイルハンドル
ジョンティタス

0

これはコメントのようなものですが、私にはあまり評判がありません。@john titusとまったく同じ問題に遭遇しました。

このMaxThreads問題を解決するために、AJPコネクタをApacheスレッドの制限に近づけました。

これを監視するために、AJPポートでnetstatコマンドを使用してSYN_SENT netstatポートステータスのヘルプを探しました。

netstat -an | grep :8102 | grep SYN_SENT | wc -l

これは0になりました。これは、AJPコネクタで設定されたMaxThread制限の前に常に大きな数字でした。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.