簡體   English   中英

在風暴中使用Apache的AsyncHttpClient

[英]using Apache's AsyncHttpClient in a storm bolt

我有一個螺栓,它為每個元組進行API調用(HTTP Get)。 為避免需要等待響應,我一直在尋找使用apache HttpAsyncClient的方法。

在螺栓的prepare方法中實例化客戶端之后,execute方法從元組構造URL並調用sendAsyncGetRequest(url):

private void sendAsyncGetRequest(String url){

    httpclient.execute(new HttpGet(url), new FutureCallback<HttpResponse>() {

        @Override
        public void completed(HttpResponse response) {
            LOG.info("Response Code : " + response.getStatusLine());
            LOG.debug(response.toString());
        }

        @Override
        public void failed(Exception ex) {
            LOG.warn("Async http request failed!", ex);
        }

        @Override
        public void cancelled() {
            LOG.warn("Async http request canceled!");
        }
    });
}

拓撲已部署,但Storm UI顯示錯誤:

java.lang.RuntimeException: java.lang.IllegalStateException: Request cannot be executed; I/O reactor status: STOPPED at backtype.storm.utils.DisruptorQueue.consumeBatchToCursor(DisruptorQueue.java:12

我沒有任何問題。 要注意的關鍵事項是:

  1. 在螺栓類作用域上聲明客戶

     public class MyRichBolt extends BaseRichBolt { private CloseableHttpAsyncClient httpclient; 
  2. 實例化並統計客戶的螺栓准備方法

     @Override public final void prepare(Map stormConf, TopologyContext context, OutputCollector collector) { try { // start the http client httpclient = HttpAsyncClients.createDefault(); httpclient.start(); // other initialization code ... } catch (Throwable exception) { // handle errors } } 
  3. 在螺栓的execute方法中進行調用

     @Override public final void execute(Tuple tuple) { // format the request url String url = ... sendAsyncGetRequest(url); } private void sendAsyncGetRequest(String url){ logger.debug("Async call to URL..."); HttpGet request = new HttpGet(url); HttpAsyncRequestProducer producer = HttpAsyncMethods.create(request); AsyncCharConsumer<HttpResponse> consumer = new AsyncCharConsumer<HttpResponse>() { HttpResponse response; @Override protected void onResponseReceived(final HttpResponse response) { this.response = response; } @Override protected void onCharReceived(final CharBuffer buf, final IOControl ioctrl) throws IOException { // Do something useful } @Override protected void releaseResources() { } @Override protected HttpResponse buildResult(final HttpContext context) { return this.response; } }; httpclient.execute(producer, consumer, new FutureCallback<HttpResponse>() { @Override public void completed(HttpResponse response) { // do something useful with the response logger.debug(response.toString()); } @Override public void failed(Exception ex) { logger.warn("!!! Async http request failed!", ex); } @Override public void cancelled() { logger.warn("Async http request canceled!"); } }); } 

您是否在執行回調之前在主流程中關閉了客戶端(client.close();)?

該錯誤表明IO路徑已關閉。 通常,異步客戶端的實例應重新用於重復的請求,並且僅在發出“ ALL”請求時(例如,在應用程序關閉時)才將其銷毀。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM