2017-01-24 1 views
2

こんにちは仲間Erlangers :)軽負荷でYAWSがエラーに応答します。 "未処理の応答fr。do_recv(){エラー、econnaborted}"

ここで言語を使用しているErlang愛好者。私は非常にシンプルなYAWSアプリケーションモジュールを持っています。これは、単一のクライアントがアクセスするとうまく動作します。しかし、光トラフィックをシミュレートするために複数のクライアントにまたがる場合、それらのクライアントはエラーを受信し始めます。どのようなアイデアを引き起こすことができますか?

クライアントを産卵コード:

-module(concurrent). 
-export([measure/0, get/0]). 

get() -> 
    Result = httpc:request("http://localhost:8080/blah"), 
    io:format("Result: ~p.\n", [Result]). 

get_spawner(0) -> io:format("Done.\n"); 
get_spawner(Times) -> 
    spawn(concurrent, get, []), 
    get_spawner(Times - 1). 

measure() -> 
    io:fwrite("Starting inets...\n"), 
    inets:start(), 
    io:fwrite("Done\n"), 

    io:fwrite("Creating blah...\n"), 
    httpc:request(put, { "http://localhost:8080/blah", [], "", "" }, [], []), 
    io:fwrite("Done\n"), 

    get_spawner(9), 

    io:fwrite("Stopping inets...\n"), 
    inets:stop(), 
    io:fwrite("Done\n"), 

    init:stop(). 

私はそれがすべて8つの同時クライアントのためにうまく動作しますが、私は9つの以上のクライアントにまたがるとき、彼らは戻って、サーバーから次のようなメッセージの受信を開始することが観察さ:

=ERROR REPORT==== 24-Jan-2017::12:28:55 === 
Unhandled reply fr. do_recv() {error,econnaborted} 

私は確信している:サーバー側で

=ERROR REPORT==== 24-Jan-2017::12:30:04 === 
** Generic server httpc_manager terminating 
** Last message in was {request, 
          {request,undefined,<0.74.0>,0,http, 
           {"localhost",8080}, 
           "/blah",[],get, 
           {http_request_h,undefined,"keep-alive", 
            undefined,undefined,undefined,undefined, 
            undefined,undefined,undefined,undefined, 
            undefined,undefined,undefined,undefined, 
            undefined,undefined,"localhost:8080", 
            undefined,undefined,undefined,undefined, 
            undefined,undefined,undefined,undefined, 
            undefined,[],undefined,undefined,undefined, 
            undefined,"0",undefined,undefined, 
            undefined,undefined,undefined,undefined,[]}, 
           {[],[]}, 
           {http_options,"HTTP/1.1",infinity,true, 
            {essl,[]}, 
            undefined,false,infinity,false}, 
           "http://localhost:8080/blah",[],none,[], 
           1485261004189,undefined,undefined,false}} 
** When Server state == {state,[],httpc_manager__handler_db, 
          {cookie_db,undefined,8209}, 
          httpc_manager__session_db,httpc_manager, 
          {options, 
           {undefined,[]}, 
           {undefined,[]}, 
           0,2,5,120000,2,disabled,false,inet,default, 
           default,[]}} 
** Reason for termination == 
** {'EXIT', 
     {shutdown, 
      {gen_server,call, 
       [httpc_handler_sup, 
       {start_child, 
        [<0.61.0>, 
        {request,#Ref<0.0.6.64>,<0.74.0>,0,http, 
         {"localhost",8080}, 
         "/blah",[],get, 
         {http_request_h,undefined,"keep-alive",undefined, 
          undefined,undefined,undefined,undefined, 
          undefined,undefined,undefined,undefined, 
          undefined,undefined,undefined,undefined, 
          undefined,"localhost:8080",undefined,undefined, 
          undefined,undefined,undefined,undefined, 
          undefined,undefined,undefined,[],undefined, 
          undefined,undefined,undefined,"0",undefined, 
          undefined,undefined,undefined,undefined, 
          undefined,[]}, 
         {[],[]}, 
         {http_options,"HTTP/1.1",infinity,true, 
          {essl,[]}, 
          undefined,false,infinity,false}, 
         "http://localhost:8080/blah",[],none,[], 
         1485261004189,undefined,undefined,false}, 
        {options, 
         {undefined,[]}, 
         {undefined,[]}, 
         0,2,5,120000,2,disabled,false,inet,default,default, 
         []}, 
        httpc_manager]}, 
       infinity]}}} 

=ERROR REPORT==== 24-Jan-2017::12:30:04 === 
Error in process <0.74.0> with exit value: 
{{case_clause, 
    {undefined, 
     {error, 
      {'EXIT', 
       {shutdown, 
        {gen_server,call, 
         [httpc_handler_sup, 
          {start_child, 
           [<0.61.0>, 
           {request,#Ref<0.0.6.64>,<0.74.0>,0,http, 
            {"localhost",8080}, 
            "/blah",[],get, 
            {http_request_h,undefined,"keep-alive", 
             undefined,undefined,undefined, 
             undefined,undefined,undefined, 
             undefined,undefined,undefined, 
             undefined,undefined,undefined, 
             undefined,undefined,"localhost:8080", 
             undefined,undefined,undefined, 
             undefined,undefined,undefined, 
             undefined,undefined,undefined,[], 
             undefined,undefined,undefined, 
             undefined,"0",undefined,undefined, 
             undefined,undefined,undefined, 
             undefined,[]}, 
            {[],[]}, 
            {http_options,"HTTP/1.1",infinity,true, 
             {essl,[]}, 
             undefined,false,infinity,false}, 
            "http://localhost:8080/blah",[],none,[], 
            1485261004189,undefined,undefined,false}, 
           {options, 
            {undefined,[]}, 
            {undefined,[]}, 
            0,2,5,120000,2,disabled,false,inet,default, 
            default,[]}, 
           httpc_manager]}, 
          infinity]}}}}}}, 
[{httpc,handle_request,9,[{file,"httpc.erl"},{line,574}]}, 
    {concurrent,get,0, 
     [{file, 
      "c:/Users/piotr_justyna/Documents/rets/performance_tests/concurrent.erl"}, 
     {line,5}]}]} 

は、私はこれを取得していますそれは何か簡単ですが、それが何であるか把握できません。それを引き起こす同時接続数ですか?あなたはこれについてもっと光を当てることができますか?

よろしく、 ピョートル

答えて

5

あなたのコードはhttpc:request/1コール数を生成しますが、その後すぐに、その後、それはinetsを停止します

... 
get_spawner(9), 
io:fwrite("Stopping inets...\n"), 
inets:stop(), 
... 

inetsがシャットダウンされているので、まだ進行中である要求がきていますエラーレポートに表示されるように、時期尚早にシャットダウンしてください。

** Reason for termination == 
** {'EXIT', 
     {shutdown, 
      {gen_server,call, 
       [httpc_handler_sup, 

inets:stop/0を呼び出す前に、生成されたすべてのリクエストの親が完了するのを待つ必要があります。それを行う1つの方法は、親のpidを各子孫に渡すことです。httpc:request/1が返されると、子に親にメッセージを送信させます。親はすべてNの子を生成し、子からの完了メッセージであるNを受け取るのを待っているループに座り、すべての完了メッセージを受信した後で初めてinets:stop/0を呼び出します。

これは8つの要求で動作するが、9では動作しない理由は、inets:stop/0を呼び出す前に待機していないという競合状態が原因です。要求処理アクセッサプロセスのYawsプールのデフォルトサイズは8になります。コードが8リクエストを送信すると、プールはコードの呼び出しをinets:stop/0に打ち負かすのに十分速く処理しますが、9ではアクセプタの1つが処理される2つの要求とわずかなタイミングの変更は、inets:stop/0コールが1つ以上のクライアントプロセスをクローバーするのに十分です。 Yawsアクセプタ・プール・サイズは、acceptor_pool_size構成変数を使用して変更できます。

負荷テストを真剣に検討している場合は、自分でテストするのではなく、tsungのような工業用のソリューションを使用することを検討してください。

+0

素晴らしい。品質アドバイス、ありがとうございます。私はそれを試してみましょうと私はスレッドを更新します。 –

+0

それはまさにそれでした、親切にありがとう。そして、私はすぐにそれを使用し始めるつもりのようにtsungを推薦してくれてありがとう。 –

関連する問題