在ChunkProcessorChunkHandler上找不到SpringBatch SpelEvaluationException方法

时间:2019-02-20 15:04:06

标签: spring-boot spring-integration spring-batch amqp

我有一个SpringBatch作业,该作业通过RabbitMQ执行远程分块 基本上,有两个应用程序master和worker都是一个春季启动应用程序。 遵循主配置:

function endQuiz() {
    $('#explanation').empty();
    $('#question-image').remove();
    $('#choice-block').empty();
    $('#pager').empty();
    $('#submitbutton').remove();
    $('#question').text("You got " + score + " out of " + quiz.length + " correct. Make sure you have a grip!");
    $(document.createElement('h2')).css({
        'text-align': 'center',
        'font-size': '4em'
    }).text(Math.round(score / quiz.length * 100) + 
'%').insertAfter('#question');
//button would go here

}

和适当的工作程序配置:

@Bean
public DirectChannel requestsToWorkers() {
    return new DirectChannel();
}

@Bean
public IntegrationFlow outboundFlow() {
    return IntegrationFlows
            .from(requestsToWorkers())
            .handle(Amqp.outboundAdapter(configurableRabbitTemplate).routingKey("master-route"))
            .get();
}

@Bean
public QueueChannel repliesFromWorkers() {
    return new QueueChannel();
}

@Bean
public IntegrationFlow inboundFlow() {
    return IntegrationFlows
            .from(Amqp.inboundAdapter(configurableRabbitMqConnectionFactory, messageBrokerProperties.getMessageQueue().getQueueName()))
            .channel(repliesFromWorkers())
            .get();
}

@Bean
public ItemReader<Integer> testIntegerItemReader() {
    return () -> new Random().nextInt();
}

@Bean
public ItemWriter<Integer> testAqmpItemWriter() {
    final MessagingTemplate messagingTemplate = new MessagingTemplate();
    messagingTemplate.setDefaultChannel(requestsToWorkers());
    messagingTemplate.setReceiveTimeout(3000);
    final ChunkMessageChannelItemWriter<Integer> chunkMessageChannelItemWriter = new ChunkMessageChannelItemWriter<>();
    chunkMessageChannelItemWriter.setMessagingOperations(messagingTemplate);
    chunkMessageChannelItemWriter.setReplyChannel(repliesFromWorkers());
    return chunkMessageChannelItemWriter;
}

@Bean
public Job testJob(final ItemReader<Integer> testIntegerItemReader,
                   final ItemWriter<Integer> testAqmpItemWriter) {
    return jobBuilderFactory.get("testJob")
            .incrementer(new RunIdIncrementer())
            .start(
                    stepBuilderFactory.get("masterStep")
                            .<Integer, Integer>chunk(1)
                            .reader(testIntegerItemReader)
                            .writer(testAqmpItemWriter)
                            .build()
            )
            .build();
}

每个模块使用SpringBoot 2.1.2。 总体而言,一切正常,并且大块数据已通过RabbitMQ成功从主机发送到工作者,但是当工作者尝试实际读取消息时,我收到以下异常

@Bean
public DirectChannel requestsChannel() {
    return new DirectChannel();
}

@Bean
public DirectChannel repliesChannel() {
    return new DirectChannel();
}

@Bean
public IntegrationFlow inboundFlow() {
    return IntegrationFlows
            .from(Amqp.inboundAdapter(configurableRabbitMqConnectionFactory, messageBrokerProperties.getMessageQueue().getQueueName()))
            .channel(requestsChannel())
            .get();
}

@Bean
public IntegrationFlow outboundFlow() {
    return IntegrationFlows
            .from(repliesChannel())
            .handle(Amqp.outboundAdapter(configurableRabbitTemplate).routingKey("worker-route"))
            .get();
}

@Bean
public ItemProcessor<Integer, Integer> processor() {
    return account -> {
        System.out.println("Processed random int " + account);
        return account;
    };
}

@Bean
public ItemWriter<Integer> writer() {
    return response -> System.out.println("Value written to AMQP " + response);
}

@Bean
@ServiceActivator(inputChannel = "requestsChannel", outputChannel = "repliesChannel")
public ChunkProcessorChunkHandler<Integer> chunkProcessorChunkHandler(final ItemProcessor<Integer, Integer> processor,
                                                                      final ItemWriter<Integer> writer) {
    final SimpleChunkProcessor<Integer, Integer> chunkProcessor = new SimpleChunkProcessor<>(processor, writer);
    final ChunkProcessorChunkHandler<Integer> chunkProcessorChunkHandler = new ChunkProcessorChunkHandler<>();
    chunkProcessorChunkHandler.setChunkProcessor(chunkProcessor);
    return chunkProcessorChunkHandler;
}

已经在这个问题上花费了很多时间 非常感谢您的帮助

1 个答案:

答案 0 :(得分:0)

handleChunk期望ChunkRequest,而不是byte[],因此入站通道适配器中的反序列化似乎出了点问题。它应该有一个SimpleMessageConverter(默认值)来处理java.io.SerializableChunkRequest实现)。

如果没有内容类型的消息属性,则可能发生这种情况(如果转换器不了解内容类型,则该转换器仅返回byte[]

出站适配器使用相同的转换器,因此应将其设置为正确。

在Rabbit Management UI上查看一条消息,以确保标题正确。它应该具有此值application/x-java-serialized-object

您还可以通过启用调试日志记录来检查消息和标头。