camel EIP 之Aggregator


EIP就是企业整合模式,全记录在一本书里,http://www.enterpriseintegrationpatterns.com/。不过camel in action 列举了5个重要整合模式,学一学应该差不多了吧

第一个是AGGREGATOR,就是将多个消息处理为一个消息,有三点需要配置:

1,用一个表达式Expression配置哪些消息是关联的

2,用一个逻辑表达式Predicate或者是时间相关的条件配置何时产生合并的消息

3,用一个AggregationStrategy来描述如何合并为一条

例子:合并不同消息里的字符,A,B,C,合并为ABC

public void configure() throws Exception {
from("direct:start")
.log("Sending ${body} with correlation key ${header.myId}")
.aggregate(header("myId"),new MyAggregationStrategy())
.completionSize(3)
.log("Sending out ${body}")
.to("mock:result");
}

header("myId"),是一个表达式,表示拥有相同值的消息是关联的,需要被放在一块处理
new MyAggregationStrategy 是一个类,表示合并策略
完成条件为3,表示聚集了3条同类消息,就会输出一条合并消息
camel每得到一个新的identify的Id,就会创建一个aggregator,用来保存消息,当相同identifyId的消息积累到3条时就输出一条
相同功能的spring 配置为

<route>
<from uri="direct:start"/>
<log message="Sending ${body} with key ${header.myId}"/>
<aggregate strategyRef="myAggregationStrategy" completionSize="3">
<correlationExpression>
<header>myId</header>
</correlationExpression>
<log message="Sending out ${body}"/>
<to uri="mock:result"/>
</aggregate>
</route>

单元测试方法。template模拟地发送了4条消息:

public void testABC() throws Exception {
MockEndpoint mock = getMockEndpoint("mock:result");
mock.expectedBodiesReceived("ABC");
template.sendBodyAndHeader("direct:start", "A", "myId", 1);
template.sendBodyAndHeader("direct:start", "B", "myId", 1);
template.sendBodyAndHeader("direct:start", "F", "myId", 2);
template.sendBodyAndHeader("direct:start", "C", "myId", 1);
assertMockEndpointsSatisfied();
}

结果

INFO route1 - Sending A with correlation key 1
INFO route1 - Sending B with correlation key 1
INFO route1 - Sending F with correlation key 2
INFO route1 - Sending C with correlation key 1
INFO route1 - Sending out ABC

来看最重要的部分,如何实现ABC的合并策略

import org.apache.camel.Exchange;
import org.apache.camel.processor.aggregate.AggregationStrategy;
public class MyAggregationStrategy implements AggregationStrategy {
public Exchange aggregate(Exchange oldExchange, Exchange newExchange) {
if (oldExchange == null) {
return newExchange;
}
String oldBody = oldExchange.getIn()
.getBody(String.class);
String newBody = newExchange.getIn()
.getBody(String.class);
String body = oldBody + newBody;
oldExchange.getIn().setBody(body);
return oldExchange;
}
}


每当有新的消息到来时,aggregate方法都会被触发,这个例子中,被触发了四次
Arrived oldExchange newExchange    Description
  A              null                    A                   The first message arrives for the first group
  B              A                       B                   The second messages arrives for the first group
  F              null                    F                   The first message arrives for the second group
  C             AB                    C                   The third message arrives for the first group
简单解释一下:当有新的identifyId到来时,oldExchange未被创建,所以为null,此时简单返回newExchange即可。
当新旧exchange陡不为空时,将旧的exchange更新一下。
注意:aggregate方法是线程安全的,任何时候只能有一个线程执行此方法。
 
如果触发条件始终未达到,那么可以组合一些其他的条件来触发。
其他触发条件如下:
completionTimeout ,completionInterval ,completionPredicate ,completionFromBatchConsumer
详情请见:http://camel.apache.org/aggregator2

camel还提供了一些属性来查看触发执行情况:

 

Property                                                                                                    Type                                          Description

 

Exchange.AGGREGATEDSIZE                                                             Integer              The total number of arrived messages aggregated.

 

Exchange.AGGREGATEDCOMPLETED BY                                       String               The condition that triggered the completion. Possiblevalues are"size","timeout","interval","predicate"

Exchange.AGGREGATEDCORRELATION KEY                                 String               The correlation identifier as aString.

 

这样就可以用来了解运行的情况,比如记录log:

.log("Completed by ${property.CamelAggregatedCompletedBy}")

 

由于在触发之前Aggregator里面存放了消息,它们都是存储在内存里的,所以服务器断了就无法恢复了。有2种方式可以用来存储消息:

AggregationRepository接口定义了增加和删除数据的方式,camel默认使用MemoryAggregationRepository,将消息存在内存里。

RecoverableAggregationRepository接口定义了恢复数据的方式,camel默认使用camel-hawtdb component来支持恢复。

HawtDB是一种轻量级的key/value文件数据库,它给camel的一些特性提供了存储,比如Aggregator。

使用HawtDB的方式如下:

AggregationRepository myRepo = new

HawtDBAggregationRepository("myrepo", "data/myrepo.dat");

第一个参数是实例名称,必须独一无二,因为一个文件里可能有多个实例。

第二个参数是存储的文件名称。

可以参考:http://camel.apache.org/hawtdb来配置

应用方式如下:

AggregationRepository myRepo = new
HawtDBAggregationRepository("myrepo", "data/myrepo.dat");
from("file://target/inbox")
.log("Consuming ${file:name}")
.aggregate(constant(true), new MyAggregationStrategy())
.aggregationRepository(myRepo)
.completionSize(3)
.log("Sending out ${body}")
.to("mock:result");


 

 

 

 

 

 

 

 

 


 
 
 
 
 
 
 
 


 
 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值