我有一个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;
}
已经在这个问题上花费了很多时间 非常感谢您的帮助
答案 0 :(得分:0)
handleChunk
期望ChunkRequest
,而不是byte[]
,因此入站通道适配器中的反序列化似乎出了点问题。它应该有一个SimpleMessageConverter
(默认值)来处理java.io.Serializable
(ChunkRequest
实现)。
如果没有内容类型的消息属性,则可能发生这种情况(如果转换器不了解内容类型,则该转换器仅返回byte[]
。
出站适配器使用相同的转换器,因此应将其设置为正确。
在Rabbit Management UI上查看一条消息,以确保标题正确。它应该具有此值application/x-java-serialized-object
。
您还可以通过启用调试日志记录来检查消息和标头。