在karaf中使用驼峰路线的巨大性能问题

时间:2013-08-01 17:33:01

标签: java apache-camel apache-karaf

我对卡拉夫有一个棘手的问题,并且整天都在努力解决它,我需要你的见解。这是问题所在:

我有骆驼路线(纯java DSL)从两个来源获取数据,处理它们,然后将结果发送到redis - 当作为独立应用程序使用时(使用Main类和命令行" java -jar myjar.jar"),数据将在不到20分钟的时间内得到处理和保存 - 当将它们用作捆绑(实际上是另一个特征的一部分)时,在同一台机器上,它需要大约10小时

编辑:我忘了添加:我使用camel 2.1.0和karaf 2.3.2

现在,我们正在将我们的SI重构为karaf功能,遗憾的是,仅仅保留独立应用程序是不可能的。

我尝试使用karaf java内存选项,使用群集(我失败了:d)玩SEDA和线程池,用seda替换所有直接路由,但没有成功。一个dev:create-dump显示了很多

thread #38 - Split" Id=166 BLOCKED on java.lang.Class@56d1396f owned by "Camel (camelRedisProvisioning)

这可能是karaf中split和parallelProcessing的问题吗?独立应用程序确实显示了更多的CPU活动。

这是我的骆驼路线

//start with a quartz and a cron tab
from("quartz://provisioning/topOffersStart?cron=" + cronValue.replace(' ',  '+')).multicast()
        .parallelProcessing().to("direct:prodDAO", "direct:thesaurus");

//get from two sources and process
from("direct:prodDAO").bean(ProductsDAO.class)
.setHeader("_type", constant(TopExport.PRODUCT_TOP))
.setHeader("topOffer", constant("topOffer"))
.to("direct:topOffers");

from("direct:thesaurus")
.to(thesaurusUri).unmarshal(csv).bean(ThesaurusConverter.class, "convert")
.setHeader("_type", constant(TopExport.CATEGORY_TOP))
.setHeader("topOffer", constant("topOffer"))
.to("direct:topOffers");


//processing  
from("direct:topOffers").choice()
        .when(isCategory)
            .to("direct:topOffersThesaurus")
        .otherwise()
            .when(isProduct)
                .to("direct:topOffersProducts")
            .otherwise()
                .log(LoggingLevel.ERROR, "${header[_type]} is not valid !")
            .endChoice()
        .endChoice()
    .end();

from("direct:topOffersThesaurus")
//here is where I think the problem comes
        .split(body()).parallelProcessing().streaming()
        .bean(someprocessing)
        .to("direct:toRedis");

from("direct:topOffersProducts")
//here is where I think the problem comes
        .split(body()).parallelProcessing().streaming()
        .bean(someprocessing)
        .to("direct:toRedis");

//save into redis
from("direct:toRedis")
        .setHeader("CamelRedis.Key", simple("provisioning:${header[_topID]}"))
        .setHeader("CamelRedis.Command", constant("SETEX"))
        .setHeader("CamelRedis.Timeout", constant("90000"))//25h
        .setHeader("CamelRedis.Value", simple("${body}"))
.to("spring-redis://?redisTemplate=#provisioningRedisTemplateStringSerializer");
NB:身体发送到直接:topOffers [products | thesaurus]是一个pojo列表(同一个类)

感谢任何可以提供帮助的人

编辑: 我想我把它缩小到了jaxb的僵局。实际上,在我的路由中,我对调用Web服务的java客户端进行了大量调用。当使用karaf时,线程在那里阻塞: java.lang.Thread.State: BLOCKED (on object monitor) at com.sun.xml.bind.v2.runtime.reflect.opt.AccessorInjector.prepare(AccessorInjector.java:78)

在堆栈跟踪的下方,我们看到用于转换对象中的xml的解组方法,我们怀疑的那两行

final JAXBContext context = JAXBContext.newInstance(clazz.getPackage().getName());
final Unmarshaller um = context.createUnmarshaller();

我删除了最后的,没有任何改进。也许与karaf使用的jaxb有关?我没有使用bundle

安装任何jaxb impl

1 个答案:

答案 0 :(得分:0)

钉了它! 如上所示,它确实链接到我的webservice客户端中的jaxb上下文的死锁。 我做了什么 : - 通过删除Marshaller / Unmarshaller对象上的final关键字来重构该客户端的旧代码(我认为死锁来自那里,即使在独立运行时它是完全相同的代码) - 基于包实例化上下文,并且只进行一次。 我必须承认OSGI的Classloader问题让我在我的桌面上敲了几个小时,但感谢Why can't JAXB find my jaxb.index when running inside Apache Felix?,我设法解决了这个问题

当然,我的线程现在正在睡觉而不是被阻止,但现在我在不到30分钟内处理我的数据,这对我来说已经足够了