Kotlin 驼峰:当项目数量小于批次大小时,如何拆分然后聚合
我有一个骆驼路由,它从S3读取文件,并按如下方式处理输入文件:Kotlin 驼峰:当项目数量小于批次大小时,如何拆分然后聚合,kotlin,apache-camel,spring-camel,Kotlin,Apache Camel,Spring Camel,我有一个骆驼路由,它从S3读取文件,并按如下方式处理输入文件: 使用 按body()拆分输出 按主体属性(.sement)和批大小2进行聚合 调用持久性服务以在给定的批中上载到DB 问题是,当批大小为2且记录数为奇数时,总有一条记录无法保存 提供的代码与等价的Java代码(除了“\${simple expression}”前面的斜杠或没有分号来终止语句)没有太大区别 如果我将批大小设置为1,则会保存每条记录,否则最后一条记录将永远不会保存 我已经检查了几次文档,但它似乎没有涵盖这个特定场景 除了
.sement
)和批大小2进行聚合completionSize
之外,我还设置了[completionTimeout
|completionInterval
],但没有任何区别
以前有人遇到过这个问题吗
val csvDataFormat = BindyCsvDataFormat(Student::class.java)
from("aws-s3://$student-12-bucket?amazonS3Client=#amazonS3&delay=5000")
.log("A new Student input file has been received in S3: '\${header.CamelAwsS3BucketName}/\${header.CamelAwsS3Key}'")
.to("direct:move-input-s3-object-to-in-progress")
.to("direct:process-s3-file")
.to("direct:move-input-s3-object-to-completed")
.end()
from("direct:process-s3-file")
.unmarshal(csvDataFormat)
.split(body())
.streaming()
.parallelProcessing()
.aggregate(simple("\${body.semester}"), GroupedBodyAggregationStrategy())
.completionSize(2)
.bean(persistenceService)
.end()
对于包含七(7)条记录的输入CSV文件,这是生成的输出(添加了一些调试日志):
WARN 19540---[student-12-move]c.a.s.s.internal.S3AbortableInputStream:没有从S3ObjectInputStream读取所有字节,正在中止HTTP连接。这可能是一个错误,可能会导致次优行为。使用后,仅通过范围GET请求所需的字节,或排空输入流。
信息19540---[student-12-move]学生工作流程主:在S3中收到一个新的学生输入文件:“student-12-bucket/inbox/foo.csv”
信息19540---[student-12-move]move-input-s3-object-to-in-progress:将s3文件“inbox/foo.csv”移动到“Ingress”文件夹。。。
信息19540---[student-12-move]学生工作流程主:将输入S3文件'in progress/foo.csv'移动到'in progress'文件夹。。。
信息19540---[student-12-move]预处理-s3-file-records:开始保存到数据库。。。
DEBUG 19540---[read#7-Split]c.b.i.d.s.StudentPersistenceServiceImpl:将记录保存到数据库:Student(id=7,name=Student 7,学期=2,javaMarks=25)
DEBUG 19540---[read#7-Split]c.b.i.d.s.StudentPersistenceServiceImpl:将记录保存到数据库:Student(id=5,name=Student 5,Semmer=2nd,javaMarks=81)
DEBUG 19540---[read#3-Split]c.b.i.d.s.StudentPersistenceServiceImpl:将记录保存到数据库:Student(id=6,name=Student 6,学期=1,javaMarks=15)
DEBUG 19540---[read#3-Split]c.b.i.d.s.StudentPersistenceServiceImpl:将记录保存到数据库:Student(id=2,name=Student 2,学期=1,javaMarks=62)
DEBUG 19540---[read#2-Split]c.b.i.d.s.StudentPersistenceServiceImpl:将记录保存到数据库:Student(id=3,name=Student 3,学期=2,javaMarks=72)
DEBUG 19540---[read#2-Split]c.b.i.d.s.StudentPersistenceServiceImpl:将记录保存到数据库:Student(id=1,name=Student 1,学期=2,javaMarks=87)
信息19540---[student-12-move]设备组工作流主:结束预处理S3 CSV文件记录。。。
信息19540---[student-12-move]move-input-s3-object-to-completed:将s3文件'in progress/foo.csv'移动到'completed'文件夹。。。
信息19540---[student-12-move]设备组工作流主:将S3文件“进行中/foo.csv”移动到“完成”文件夹。。。
如果需要立即完成消息,则可以指定一个基于拆分器设置的exchange属性的完成谓词
.completionPredicate( simple( "${exchangeProperty.CamelSplitComplete}" ) )
将处理最后一条消息
我的另一个担忧是,您在拆分器中设置了
parallelProcessing
,这可能意味着消息没有按顺序进行处理。这真的是您希望并行处理应用到的拆分器,还是实际上是聚合器?您似乎没有对拆分记录执行任何操作,只是对它们进行聚合,然后再对它们进行处理o最好将并行处理
指令移动到聚合器。completionTimeout应该在超时时触发最后一行。如果这不起作用,那会很奇怪。如果我将simple(${body.sement})替换为常量(true),它确实表现出正确的行为。这可能是一个错误…您使用的是什么版本的Camel?组键body.sement或constant不应影响超时。我使用的是以下组件:+Camel.version=2.23.0+spring-boot.version=2.1.1.RELEASE+kotlin.version=1.3.10+aws-java-sdk.version=1.11.461并且您确定y中没有任何错误我们的bean不能只处理1条记录。您是否尝试过在聚合后添加日志,以查看它在触发完成超时时是否记录了一些内容等。如果仍然存在问题,您可以尝试在github上构建一个项目,以便其他人更容易查看。并且可以在没有AWS帐户的情况下轻松运行等。但事实并非如此但它帮助我理解了问题的原因。问题似乎是,当按主体的某个属性分组时,可能会有一些结转交换,这些交换的完成条件都不会为真:*交换完成大小==2*exchangeProperty.CamelSplitComplete==真不确定如何这样做lve还没有..可能关闭并行处理,因为您可以启用无序处理。我确实按照建议在拆分期间关闭了并行处理。不过最终结果是一样的。。
.completionPredicate( simple( "${exchangeProperty.CamelSplitComplete}" ) )