Camel的异步处理

Camel支持复杂的异步处理机制。

异步Processor实现AsyncProcessor接口,该接口派生自syncProcessor接口。

使用异步处理机制的好处是:

1.执行中的路由,如果都是由异步processor组成的话,不需要线程等待。

2.执行中的路由,可以分解成SEDA处理阶段,不同的线程池处理不同的阶段,这意味着路由可以并行执行。

?何时使用异步处理

我们的本意是建议你使用同步processor,除非你觉得系统的性能可扩展性是最重要的因素。

接口描述:

public interface AsyncProcessor extends Processor {
   boolean process(Exchange exchange, AsyncCallback callback);
}

说明:

1.callback对象必须被提供,该对象将在process方法执行完后被回调。

2.在执行过程中,不能抛出错误,而是应该把错误存在exchange的错误属性里。

3.必须知道是同步执行完Process方法还是异步,如果是同步执行完,返回true,否则返回false。

4.当Processor执行完process方法后,他必然要调用callback.done(boolean sync)方法,该参数必须与process方法的返回参数值一致。

?如何进行异步处理编程

所有的processor,即使是没有实现异步接口的同步processor,都可以强制转换成实现异步接口。通常的场景是:消息的消费者生成一个processor,通过下面代码转换成异步处理方式:

Processor processor = ...
AsyncProcessor asyncProcessor = AsyncProcessorTypeConverter.convert(processor);

对于一个路由来说,要达到全异步,并获得低线程使用率的益处,那么这个路由必须开始于一个异步处理的消息消费者的processor。如果调用了同步处理的方法,消费者线程将被阻塞,在他处理完消息后才能够结束阻塞。

值得注意的是,你仅仅是调用了异步API,并不代表整个处理进程都异步了。这里仅仅是意味着,处理器线程没有和调用者线程绑定。如果处理异步发生,实际上依赖于router的配置(不解)。

final Exchange exchange = ...
AsyncProcessor asyncProcessor = ...
asyncProcessor.process(exchange, new AsyncCallback() {
    public void done(boolean sync) {

        if (exchange.isFailed()) {
            ... // do failure processing.. perhaps rollback etc.         } else {
            ... // processing completed successfully, finish up                 // perhaps commit etc.         }
    }
});

上面的代码告诉你,如何来写一个process方法。

?异步处理的场景

我们理解了异步的接口定义后,下面来看看在调用processor时,如何使用异步处理。

 jetty组件消费者支持使用延续性来处理异步情况:该组件获得一个http request后,将它传递给一个router,由该路由进行异步处理。如果处理真的是异步的话,那么请求被暂留而consumer的线程被释放。一旦router完成了处理,jetty组件使用AsyncCallback,告诉jetty放行request,response生成,将结果返回给请求端。

注意:jetty的延续性特性,是依赖在进程真的是异步的前提下的。这就是为什么前面说过的,AsyncCallback.process方法必须准确反映请求是否真的是异步处理的。

jhc组件的producer允许你生成http Request并且实现AsyncProcessor接口,一个路由可以使用jetty的异步consumer和jhc的异步producer,这样就是一个完整的异步路由了。如果我们看一下处理路由的序列图,就可以看出它有很多好处了。

from("jetty:http://localhost:8080/service").to("jhc:http://localhost/service-impl");

上面的序列图,简化了router的处理流程,它假设processor实现了异步回调接口。但是它也充分说明了处理流程:两个独立的线程如何如何来处理源请求。

第一个线程,调用是同步的,直到进程触发了jhc producer,将request发出。发出后,该线程报告数据交换进程异步结束(使用NIO完成获取返回response的工作)。

一旦jhc组件接收到response,他将使用AsyncCallback.done()方法来通知调用者,回调通知送达jetty consumer组件后,该组件放行request并反馈response。

?同步异步混合场景

将同步和异步组件/处理器混合使用,是完全有可能和合理的。pipeline是处理路由的脊梁,它将不同的组件粘合在一起。它是作为异步处理器实现的,支持同步异步处理器交错。

例子如下:有两个自定义处理器,MyValidator 和MyTransformation他们都是同步处理器,我们打算从data/in目录装在文件并使用MyValidator方法去验证他们,将他们转换成java对象插入数据库中。由于transformation进程要花一些时间,所以分配20个线程并行处理,该解决方案还用到了线程processor,该线程processor是异步处理器,他生成子处理,子处理是由来自线程池的线程来执行的。

from("file:data/in").process(new MyValidator()).threads(20).process(new MyTransformation()).to("jpa:PurchaseOrder")

上图就不用详细说明了吧。

你可能感兴趣的:(职场,camel,休闲,Camel异步处理)