繁体   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