Использую Spring AMQP для обмена сообщениями и постановки в очередь обработку изображений и видеозаписей.
@Transactional
@RabbitListener(queues = "test")
public void processImage(Message message, @Header("image_id") long imageId,
@Header("account_id") long accountId) throws Exception {
Image image = imageService.getImage(imageId);
byte[] renderedImageBuffer = null;
String format = ImageUtils.getImageFormat(message.getBody());
switch (format.toLowerCase()) {
case "jpeg":
renderedImageBuffer = message.getBody();
break;
case "png":
renderedImageBuffer = ImageUtils.convertPNGtoJPEG(message.getBody());
break;
}
image.setWidth(image.getBufferedImage().getWidth());
image.setHeight(image.getBufferedImage().getHeight());
image.setData(renderedImageBuffer);
imageService.updateImage(image);
Image avatar = ImageUtils.scaleImage(image, 35, 35);
avatar.setFileName("fss_avatar" + accountId);
imageService.saveImage(avatar);
Account account = accountService.getAccount(accountId);
account.setAvatar(avatar);
accountService.updateAccount(account);
}
Этот слушатель использует 20-30 параллельных потоков для обработки данных.
@Bean
public SimpleRabbitListenerContainerFactory container() {
SimpleRabbitListenerContainerFactory container = new SimpleRabbitListenerContainerFactory();
container.setConnectionFactory(connectionFactory);
container.setConcurrentConsumers(20);
container.setMaxConcurrentConsumers(30);
container.setChannelTransacted(true);
container.setTransactionManager(transactionManager());
return container;
}
И все вроде бы хорошо, но тут встал вопрос о безопасности потоков в утилитарном классе
(ImageUtils)
. Стоит ли засунуть все методы в обработчик сообщения или сделать методы утилитарного класса синхронизированными? С одной стороны, с первым методом меньше гемора, но с другой стороны, код станет нечитабельным. В каком случае производительность будет больше?