Camel支持一种更复杂的异步的处理模型,异步处理器实现一个继承自Processor接口的AsyncProcessor接口,使用异步Processor的长处:

a.异步Processor不会因等待堵塞调用而耗尽线程。这样在处理相同工作量的情况下,通过降低线程的数量能够添加系统的伸缩性

b.使用异步Processor,能够将路由分阶段处理。不同的线程池处理其对应的路由阶段。这就意味着路由能够并行处理。

缺点:实现异步的Processor要比同步的Processor复杂得多。

异步Processor与同步Processor的差别:

a.必须提供一个AsyncCallback对象,该对象在exchange处理完毕后被通知

b.在异步Processor处理exchange的时候不能抛出不论什么异常,而应该将异常存储在exchange的Exception属性中

c.异步Processor必须知道它将以什么方式完毕处理,异步或同步,假设process方法返回true。则是同步完毕。假设process方法返回false,则是异步完毕。

d.当处理器处理完exchange时,它必须调用callback.done(boolean sync)方法。sync參数必须与process方法的返回值一致。



对于一个路由来说,全然使用异步模式能够减少线程的使用量,这要求从Consumer開始就必须使用异步的处理API(即调用异步的

process方法),假设Consumer调用的是同步process()方法,那么消费者线程在处理Exchange时将被强制堵塞。

有一点必须注意的是当你调用了异步的API。这并不意味着处理过程就是异步的,这不过为不捆绑在调用者线程提供了可能。

至于是否是进行异步处理依赖于Camel路由的配置.

以上是Camel官方对异步Processor的解释,以下是本人用于測试的一个样例:

public static void main(String[] args) throws Exception {
RouteBuilder builder = new RouteBuilder() { @Override
public void configure() throws Exception {
RouteDefinition definition1 = this.from("file:H:/temp/in");
RouteDefinition definition2 = definition1.process(new Processor() { @Override
public void process(Exchange exchange) throws Exception {
System.out.println(Thread.currentThread().getName());
System.out.println("process1");
}
}).process(new AsyncProcessor() { @Override
public void process(Exchange exchange) throws Exception {
System.out.println("process");
}
@Override
public boolean process(Exchange exchange, AsyncCallback callback) {
System.out.println(Thread.currentThread().getName());
System.out.println("async process");
try {
Thread.sleep(10 * 1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
callback.done(false);
return false;
}
}).process(new Processor() { @Override
public void process(Exchange exchange) throws Exception {
System.out.println(Thread.currentThread().getName());
System.out.println("process2");
}
});
definition2.to("file:H:/temp/out");
}
}; DefaultCamelContext camelContext = new DefaultCamelContext();
camelContext.addRoutes(builder);
camelContext.start(); Object object = new Object();
synchronized (object) {
object.wait();
} }

当我看到异步两个字时,直觉就是使用异步Processor时会启用新的线程进行处理,但在上面的样例中,三个线程名称是一样的,

而且在堵塞了10秒后process2才打印出来,这说明上面的三个processor是在同一个线程中运行的,这也是堵塞10秒的原因。

我个人觉得是对Camel异步Processor的"异步"两字理解出现了偏差。这里的异步仅仅为processor的processor方法。提供一个

回调函数,而不是另启线程。

并且我们自己写Processor处理器对这个异步的使用也非常有限,由于我们写的处理器是被调用者。AsyncCallback是由上层提供的,我们仅仅是能调用其done方法通知上层本次处理完毕。而我们很多其它的需求应该是自己去注冊回调函数,并且我们可以控制这个回调函数的回调时机。而如今我们无法提供回调函数的注冊。那我们不禁要问,这个AsyncCallback对象那究竟是谁提供的呢?AsyncCallback对象的源头当然是在消费者类提供的,对上面的样例来说是在FileConsumer类中。例如以下是GenericFileConsumer的processExchange方法的一个片段(FileConsumer继承自GenericFileConsumer)

getAsyncProcessor().process(exchange, new AsyncCallback() {
public void done(boolean doneSync) {
// noop
if (log.isTraceEnabled()) {
log.trace("Done processing file: {} {}", target, doneSync ? "synchronously" : "asynchronously");
}
}
});

这时创建的AsyncCallback对象就是源始的回调对象。当然在路由运行的兴许过程中,该回调对象能够被包装。当中CamelInternalProcessor的process(Exchange exchange, AsyncCallback callback)方法就是一个样例:

callback = new InternalCallback(states, exchange, callback);

这里我们不禁又会问。既然CamelInternalProcessor可以对源始AsyncCallback对象进行包装增加自己的回调逻辑,为什么我们自己不行呢。其原来还是我们写的Processor是被调用者。是被包装者,详细过程可參看Camel路由启动过程



假设非要加入自己的回调逻辑也不是不可能。就仅仅能自己写消费者。自己写消费者就能控制源AsyncCallback对象,其兴许仅仅是对

源AsyncCallback对象的一个包装的过程。仅仅要保证最外层的AsyncCallback对象被调用,那么源AsyncCallback对象也一定会被调用。所以在上例中,假设在第二个Processor中假设不运行callback.done(false);的话路由过程将永远不会结束,由于上层一直觉得下层处理还未结束。

当然假设我们不写异常Processor,路由过程还是会正常结束的,Camel内部会自行处理,可是假设我们写了异步Processor就一定要调用callback.done方法。



所以这么一通下来。并没有感受到官方提及的不堵塞调用、降价线程使用、路由分阶段处理等,个人的感觉就是多了一个回调方法,并且这个回调功能还非常有限,当然这也有可能是自己什么地方理解错了,如若如此。尽请指正......

Camel之AsyncProcessor的更多相关文章

  1. Camel运行原理分析

    Camel运行原理分析 以一个简单的例子说明一下camel的运行原理,例子本身很简单,目的就是将一个目录下的文件搬运到另一个文件夹,处理器只是将文件(限于文本文件)的内容打印到控制台,首先代码如下: ...

  2. Apache Camel

    Apache Camel 1 import org.apache.camel.CamelContext; import org.apache.camel.builder.RouteBuilder; i ...

  3. [Camel Basics]

    Define routes: Either using Spring xml or Java DSL. Spring xml: <camelContext> <routeBuilde ...

  4. Reason we use Camel

    Camel is mainly for integration purpose, in our project we also use it inside the single component t ...

  5. Camel routes in Spring config file

    The normal spring bean definition configuration file, the xsi:schemaLocation only has two: beans and ...

  6. Camel、Pastal、匈牙利标记法

    原来我一直用的是Camel标记法……收藏学习了. */       Camel标记法采用首字母小写,接下来的单词都以大写字母开头的方法,如myName.       Pastal标记法采用首字母大写, ...

  7. 在 Java EE 组件中使用 Camel Routes

    摘要:你可以通过集成 Camel 和 WildFly 应用服务器(使用 WildFly-Camel 子系统)在 Java EE 组件中开始使用 Apache Camel Routes. [编者按]作者 ...

  8. Camel In Action 阅读笔记 第一章 认识Camel 1.1 Camel 介绍

    1.1 Camel 介绍 Camel 是一个为了您的项目集成变得高效有趣的集成框架,Camel 项目在2007年初开始的,相对来说它还比较年轻,但它已然是一个非常成熟的开源项目,它所使用的是Apach ...

  9. Camel In Action 阅读笔记 第一部分概述 + 第一章概述 认识Camel

    第一部分: 最开始的一小步 Apache Camel 是一个开源集成框架,其目的是让系统集成变得更加简便,在本书的第一章中,我们会为您介绍它并向您展示它是如何在大型企业应用中做好集成工作.您也会了解到 ...

随机推荐

  1. [Visual Studio] 重置默认设置 还原默认设置

    恢复默认设置的2种方法 如果VS出现问题或设置变乱,可以通过恢复默认设置使之回到安装成功时的状态,从而解决出现的问题.VS恢复默认设置的方法有2种,分别是:通过“导入和导出设置”实现和通过命令实现. ...

  2. .net正则提取手机号码,并替换带有手机号码的a标签

    //用正则查找字符串中的手机号码,最后替换成带a标签的可打电话的字符串 var str = "收件人:江苏省苏州市工业园区屌丝大叔收,电话:18688888888"; var re ...

  3. mysql内核 innodb存储引警(卷1)配书 用VS 2003 编绎 mysql-3.23.49 源代码

    作者网址:http://www.innomysql.net/ 1.旧版 mysql-3.23.49-win-src.zip 下载 (***络下载配书源代码)   或者  作者网盘  http://pa ...

  4. 解决Arcgis10.2.2中dbf文件用EXCEL打开乱码问题

    1.开始 -- 运行,输入”Regedit“,打开 注册表 . 2.如是用的是 10.x 版本 ArcGIS Desktop,定位到 ‘计算机\HKEY_CURRENT_USER\Software\E ...

  5. window与linux文件传输工具

    window与linux文件传输工具 [一般用于SecureCRT ssh中使用] 法一:直接用yum安装lrzsz(推荐) yum install lrzsz -y 注意:rhel安装完系统后 直接 ...

  6. 使用 NSPropertyListSerialization 持久化字典与数组

    NSPropertyListSerialization The NSPropertyListSerialization class provides methods that convert prop ...

  7. Java-JDBC调用批处理、存储过程、事务

    一.使用Batch批量处理数据库  当需要向数据库发送一批SQL语句执行时,应避免向数据库一条条的发送执行,而应采用JDBC的批处理机制,以提升执行效率.; 1.实现批处理有两种方式,第一种方式: S ...

  8. 阿里春招Android面经

    作者:淘萄桃 链接: https://www.jianshu.com/p/a07ccaad832d 本文由作者授权发布. 笔者参加18年阿里春招,有幸最终拿到阿里offer,base杭州,岗位客户端开 ...

  9. JQuery文件上传及以Base64字符串形式呈现图片

    一:上传之 首先,你必然得有一个 file input,如下: <td>     <img id="imgGif" style="display: no ...

  10. strchr实现

    char* strchr(char*s,charc) { while(*s!='\0'&&*s!=c) { ++s; } return*s==c?s:NULL; } // strchr ...