← Назад к вопросам
Какие решения использовал из категории message-driven
2.0 Middle🔥 141 комментариев
#Основы Java
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Ответ
Message-Driven архитектура в Java
Message-Driven архитектура — это асинхронное взаимодействие между компонентами через сообщения. Это критически важно для микросервисов, распределённых систем и высоконагруженных приложений.
1. RabbitMQ (самая популярная)
// Spring AMQP - работа с RabbitMQ
@Configuration
public class RabbitMQConfig {
public static final String EXCHANGE_NAME = "orders_exchange";
public static final String QUEUE_NAME = "orders_queue";
public static final String ROUTING_KEY = "order.*";
@Bean
public DirectExchange exchange() {
return new DirectExchange(EXCHANGE_NAME, true, false);
}
@Bean
public Queue queue() {
return new Queue(QUEUE_NAME, true);
}
}
// Producer (отправитель сообщений)
@Service
public class OrderProducer {
@Autowired
private RabbitTemplate rabbitTemplate;
public void sendOrder(Order order) {
rabbitTemplate.convertAndSend(
RabbitMQConfig.EXCHANGE_NAME,
"order.created",
order
);
}
}
// Consumer (получатель сообщений)
@Service
public class OrderConsumer {
@RabbitListener(queues = RabbitMQConfig.QUEUE_NAME)
public void processOrder(Order order) {
System.out.println("Processing order: " + order.getId());
}
}
2. Apache Kafka (для больших объёмов)
// Spring Kafka configuration
@Configuration
public class KafkaConfig {
public static final String TOPIC = "orders-topic";
}
// Producer (отправитель)
@Service
public class KafkaOrderProducer {
@Autowired
private KafkaTemplate<String, Order> kafkaTemplate;
public void sendOrder(Order order) {
kafkaTemplate.send(KafkaConfig.TOPIC, order.getId(), order);
}
}
// Consumer (получатель)
@Service
public class KafkaOrderConsumer {
@KafkaListener(topics = KafkaConfig.TOPIC, groupId = "order-service")
public void consume(Order order) {
System.out.println("Received order: " + order.getId());
}
}
3. JMS (Java Message Service)
// Для ActiveMQ, HornetQ
@Configuration
public class JmsConfig {
@Bean
public Queue orderQueue() {
return new ActiveMQQueue("order-queue");
}
}
// Producer
@Service
public class JmsOrderProducer {
@Autowired
private JmsTemplate jmsTemplate;
public void sendOrder(Order order) {
jmsTemplate.convertAndSend("order-queue", order);
}
}
// Consumer
@Service
public class JmsOrderConsumer {
@JmsListener(destination = "order-queue")
public void processOrder(Order order) {
System.out.println("JMS Order processed: " + order.getId());
}
}
4. Spring Cloud Stream (абстракция над сообщающими системами)
// Интерфейс для binding
public interface OrderBinding {
String ORDER_OUTPUT = "order-output";
String ORDER_INPUT = "order-input";
@Output(ORDER_OUTPUT)
MessageChannel orderOutput();
@Input(ORDER_INPUT)
SubscribableChannel orderInput();
}
// Producer
@Service
@EnableBinding(OrderBinding.class)
public class StreamOrderProducer {
@Autowired
private OrderBinding binding;
public void sendOrder(Order order) {
binding.orderOutput().send(
MessageBuilder.withPayload(order).build()
);
}
}
// Consumer
@Service
@EnableBinding(OrderBinding.class)
public class StreamOrderConsumer {
@StreamListener(OrderBinding.ORDER_INPUT)
public void handleOrder(Order order) {
System.out.println("Stream order: " + order.getId());
}
}
5. WebSockets (для real-time коммуникации)
// Spring WebSocket Configuration
@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {
@Override
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
registry.addHandler(new OrderWebSocketHandler(), "/ws/orders")
.setAllowedOrigins("*");
}
}
// WebSocket Handler
@Component
public class OrderWebSocketHandler extends TextWebSocketHandler {
private static final Set<WebSocketSession> sessions = new CopyOnWriteArraySet<>();
@Override
public void afterConnectionEstablished(WebSocketSession session) {
sessions.add(session);
}
public void notifyOrderUpdate(Order order) {
for (WebSocketSession session : sessions) {
try {
session.sendMessage(
new TextMessage(objectMapper.writeValueAsString(order))
);
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
Сравнение решений
| Решение | Зна́я о РТ | Масштаб | Использование |
|---|---|---|---|
| RabbitMQ | ~100ms | Средний | Микросервисы, задачи |
| Kafka | Высокая пропускная способность | Большой | Streaming, big data |
| JMS | Универсальный | Средний | Legacy системы |
| Spring Cloud Stream | Абстракция | Любой | Framework-agnostic |
| WebSockets | Real-time | Средний | Клиент-сервер |
Практический сценарий
// Event-driven микросервис архитектура
public class OrderService {
@Autowired
private OrderProducer orderProducer;
@Transactional
public void createOrder(Order order) {
// 1. Сохраняем в БД
orderRepository.save(order);
// 2. Отправляем событие асинхронно
orderProducer.sendOrderCreatedEvent(order);
// Не ждём обработки - сразу возвращаемся
}
}
// Отдельный микросервис обработает событие
@Service
public class NotificationService {
@RabbitListener(queues = "order-created-queue")
public void onOrderCreated(Order order) {
emailService.sendOrderConfirmation(order);
}
}
// Ещё один микросервис
@Service
public class AnalyticsService {
@RabbitListener(queues = "order-created-queue")
public void onOrderCreated(Order order) {
analyticsRepository.logOrderEvent(order);
}
}
Типичная ошибка
// ❌ ПЛОХО: синхронное взаимодействие (blocking)
public void createOrder(Order order) {
orderRepository.save(order);
notificationService.sendEmail(order); // Ждём ответа!
analyticsService.logEvent(order); // Ждём ответа!
}
// ✅ ПРАВИЛЬНО: асинхронное (message-driven)
public void createOrder(Order order) {
orderRepository.save(order);
messageProducer.send(new OrderCreatedEvent(order));
// Не ждём - сразу вернулись
}
Что спрашивают на собеседовании
- RabbitMQ vs Kafka: когда что использовать
- Producer-Consumer паттерн: как отправлять и получать сообщения
- Message ordering: гарантии доставки
- Dead letter queue: обработка ошибок
- Event sourcing: сохранение всех событий
- Spring AMQP vs Spring Kafka: различия в API
- Масштабирование: как масштабировать потребителей