2016-07-15 3 views
0

私は以前、このような問題をいくつかのHTTPトランザクション(百回程度の投稿など)に掛けました。今日私は7k HTTPリクエストをしようとしています。これは愚かなように見えますが、ターゲットシステムとやり取りする唯一の方法です。私ができる最善のことは、行われた要求の約96%で失速します。それはちょうど停止し、最後のいくつかの要求を完了することはありません。エラーが発生したときに何千ものHTTPリクエストを確実に処理できますか?

おそらく私は誤ってOiBackoffを使用しています。それは正常に動作しているようだが、GETの最後の3%は終了しません。ログの再試行間隔が最大40秒のときにリクエストが戻ってこないように5分間設定しました。

OiBackoffを使って一度に100個のリクエストを行う必要があるかどうか、それらがすべて完了していることを確認するのは難しいです。

ここでの目標は、最後にCFD1234、CFD1236、CFD1238などの番号を持つURLをヒットし、結果(xmlの小さなチャンク)を配列にプッシュすることです。ここでコードは、私が働いている最も近いです。多分私は別のライブラリを試してみる必要がありますか?私は約束のキューでこれを試して、それを実行することができませんでした。私が関数クロージャの配列を作成し、それらを連続して起動すると、になりますが、それよりもはるかに長い時間がかかります。

var cnum, cnums, complete, ld, logger, oibackoff, opt, processHttpGet, request, responses, total, yamljs, _fn, _i, _len; 

    yamljs = require('yamljs'); 

    request = require('request'); 

    oibackoff = require('oibackoff').backoff({ 
    maxTries: 10, 
    delayRatio: 10 
    }); 

    cnums = yamljs.load('./etc/cnumbers.yaml'); 

    responses = []; 

    logger = { 
    debug: console.log, 
    error: console.log 
    }; 

    ld = require('lodash'); 

    cnums = ld.uniq(cnums); 

    logger.debug("cnums len: " + cnums.length); 

    processHttpGet = function(url, opt, cb) { 
    return request.get(url, opt, function(error, resp, body) { 
     if (error != null) { 
     return cb(error, null); 
     } else if (resp.statusCode >= 400) { 
     return cb(resp.statusCode, null); 
     } else { 
     return cb(null, body); 
     } 
    }); 
    }; 

    opt = null; 

    total = cnums.length; 

    complete = 0; 

    _fn = function(CNumber) { 
    var intermediate, url; 
    url = "http://abc:[email protected]/xyz/def/abc.asmx/GetValueByID?ID=" + CNumber; 
    logger.debug("getting " + url); 
    intermediate = (function(_this) { 
     return function(err, tries, delay) { 
     if (err != null) { 
      logger.debug("GET failed for " + url + ":", err); 
      logger.debug("tries: %d, delay: %d", tries, delay); 
     } 
     if (tries > 10) { 
      logger.debug("/n/n Failed max tries."); 
      process.exit(0); 
      return false; 
     } 
     }; 
    })(this); 
    return oibackoff(processHttpGet, url, opt, intermediate, function(error, response) { 
     if (error) { 
     return false; 
     } else { 
     ++complete; 
     responses.push(response); 
     if (complete % 100 === 0) { 
      console.dir({ 
      url: url, 
      response: response 
      }); 
     } 
     logger.debug("success; responses complete: " + complete + ", total: " + total + ", percentage: " + (ld.round(complete/total, 2) * 100) + "%"); 
     if (complete >= total) { 
      logger.debug(responses); 
      return process.exit(0); 
     } 
     } 
    }); 
    }; 
    for (_i = 0, _len = cnums.length; _i < _len; _i++) { 
    cnum = cnums[_i]; 
    _fn(cnum); 
    } 
+0

Whoa、downvotesとは何ですか? – jcollum

+1

おそらく人々はあなたが何かいたずらにしようとしていると思うでしょう。私はbtwに投票しました。 –

+0

@AdamGentの回答が掲載されて、それは非常にシンプルであることが判明しました。これは常に良い感じです – jcollum

答えて

0

これに対する答えは、Bluebird、Promise.mapと並行処理をバックオフライブラリとともに使用することでした。

# coffee 
# exports is an array of buffers 
retry = (require 'u-promised').retry 
Promise = require("bluebird") 

# build array of buffers to post 

Promise.map(exports, (buffer) -> 
    f = -> postToEndpoint(buffer) 
    retry(5, f) # post with up to 5 retries 
, {concurrency: config.export.concurrency}) # 40 for my app 
.then (result) -> 
    c = 0 
    ld.map(result, (x) -> c += x) 
    msg = "Complete. #{c} posts completed." 
    logger.info msg 
.catch (reason) -> 
    logger.error reason 
関連する問題