2016-03-25 16 views
1

私は竜巻で非同期処理をテストしようとしており、再帰的なHTTP呼び出しに対してフィボナッチ数を計算するためのHTTPサーバーを作成しました。 これは6のような小さい数字では動作しますが、8でハングします。 それ以外の場合はn = 3に固定されるため、非同期で動作することが確信しています。 なぜそれが8に固まったのか説明できません。排気口や開いているファイルハンドラにはかなり深い。多くの再帰的要求に対する竜巻のタイムアウト

ここで障害とは何ですか?

のpython 2.7および4.3

import tornado.ioloop 
import tornado.web 
from tornado import gen 
from tornado.httpclient import AsyncHTTPClient 

class MainHandler(tornado.web.RequestHandler): 
    http_client = AsyncHTTPClient() 
    @gen.coroutine 
    def get(self): 
     n = int(self.get_argument('n', 1)) 
     print 'n = ', n 
     if n <= 2: 
      self.write("1") 
     else: 
      npUrl = 'http://localhost:8888/?n=%s' % (n - 1) 
      nppUrl = 'http://localhost:8888/?n=%s' % (n - 2) 
      print " get np %s an npp %s " % (npUrl, nppUrl) 
      np, npp = yield [ self.http_client.fetch(npUrl), 
           self.http_client.fetch(nppUrl) ] 
      npAndNpp = int(np.body) + int(npp.body) 
      print 'np + npp = %s + %s = %s' % (np.body, npp.body, npAndNpp) 
      self.write("%s" % npAndNpp) 
#  raise tornado.gen.Return(None) 

def make_app(): 
    return tornado.web.Application([ 
     (r"/", MainHandler), 
    ]) 

app = make_app() 
app.listen(8888) 
tornado.ioloop.IOLoop.current().start() 

ログ出力

[email protected]:~/demo/tornado$ python async-fibonacci.py 
n = 7 
get np http://localhost:8888/?n=6 an npp http://localhost:8888/?n=5 
n = 6 
get np http://localhost:8888/?n=5 an npp http://localhost:8888/?n=4 
n = 5 
get np http://localhost:8888/?n=4 an npp http://localhost:8888/?n=3 
n = 5 
get np http://localhost:8888/?n=4 an npp http://localhost:8888/?n=3 
n = 4 
get np http://localhost:8888/?n=3 an npp http://localhost:8888/?n=2 
n = 4 
get np http://localhost:8888/?n=3 an npp http://localhost:8888/?n=2 
n = 3 
get np http://localhost:8888/?n=2 an npp http://localhost:8888/?n=1 
n = 4 
get np http://localhost:8888/?n=3 an npp http://localhost:8888/?n=2 
n = 3 
get np http://localhost:8888/?n=2 an npp http://localhost:8888/?n=1 
n = 3 
get np http://localhost:8888/?n=2 an npp http://localhost:8888/?n=1 
n = 2 
n = 3 
get np http://localhost:8888/?n=2 an npp http://localhost:8888/?n=1 
n = 7 
get np http://localhost:8888/?n=6 an npp http://localhost:8888/?n=5 
ERROR:tornado.application:Multiple exceptions in yield list 
Traceback (most recent call last): 
    File "/usr/local/lib/python2.7/dist-packages/tornado/gen.py", line 789, in callback 
    result_list.append(f.result()) 
    File "/usr/local/lib/python2.7/dist-packages/tornado/concurrent.py", line 232, in result 
    raise_exc_info(self._exc_info) 
    File "<string>", line 3, in raise_exc_info 
HTTPError: HTTP 599: Timeout 
ERROR:tornado.application:Multiple exceptions in yield list 
Traceback (most recent call last): 
    File "/usr/local/lib/python2.7/dist-packages/tornado/gen.py", line 789, in callback 
    result_list.append(f.result()) 
    File "/usr/local/lib/python2.7/dist-packages/tornado/concurrent.py", line 232, in result 
    raise_exc_info(self._exc_info) 
    File "<string>", line 3, in raise_exc_info 
HTTPError: HTTP 599: Timeout 
ERROR:tornado.application:Multiple exceptions in yield list 
+2

をあなたはAsyncHTTPClientのために '' 'max_clients'''(10がデフォルトです)を変更しようとしましたか? –

+0

max_clientsはn = 14に達するのを助けました。私のulimit 1000.このような低いデフォルト値は私にはlibに問題があると思うようになります。 –

+0

'' 'max_clients'''を作業者ごとに1000に変更しました。この制限は、10個の同時発信接続のキューを作成しています。そして、それらが長い時間がかかる場合、それらのキューにすでに入っているときに接続はタイムアウトしています。 –

答えて

2

はあなたのプログラムの再帰が同時に進行中の以上10件のHTTPリクエストを保つためにトルネードが必要ですが、デフォルトでAsyncHTTPClientのmax_clientsは10

で竜巻

11回目のリクエストを開始すると、プログラムのデッドロックが発生します。フィボナッチ計算を完了するには、新しいHTTPリクエストを開始する必要があります現在の要求の1つが終了するまで、新しい要求を開始することはできません。

import tornado.options 
tornado.options.parse_command_line() 

をそして--logging=debugを使用してプログラムを起動します。あなたはこれらの行を追加する場合

あなたはこの動作を確認することができます。最終的には、プログラムのログ:

[D 160326 12:03:16 simple_httpclient:137] max_clients limit reached, request queued. 10 active, 11 queued requests. 

...デッドロック。 20秒後、AsyncHTTPClientのデフォルトタイムアウトが例外をスローします。

あなたはあなたのプログラムの先頭でこれを実行することにより、再帰のより高いレベルをサポートすることができます。

AsyncHTTPClient.configure(None, max_clients=100) 
関連する問題