| Тип взаимодействия | Плюсы | Минусы |
|---|---|---|
| Синхронное взаимодействие | • простота реализации; • предсказуемость времени отклика; • лёгкость отладки и мониторинга запросов. | • высокая задержка в случае медленного ответа; • увеличение зависимости между сервисами; • ограниченная масштабируемость из-за блокирующих вызовов. |
| Асинхронное взаимодействие | • высокая масштабируемость за счёт немедленного освобождения ресурсов; • устойчивость к сбоям благодаря очередям и повторной обработке сообщений; • снижение зависимости между сервисами. | • сложность реализации и отладки; • временная несогласованность данных; • потребность в дополнительных компонентах для обеспечения доставки и хранения сообщений. |
| концепция | описание | плюсы | минусы |
|---|---|---|---|
| Запрос-Ответ (Request-Response) | В синхронном взаимодействии клиент отправляет запрос серверу и ожидает получения ответа. Сервер обрабатывает запрос и возвращает результат клиенту. | простой и понятный подход, обеспечивает чёткую последовательность операций | клиент блокируется, пока сервер не завершит обработку запроса, что может привести к задержкам и снижению производительности |
| Таймауты (Timeouts) | Таймауты используются для ограничения времени ожидания ответа от сервера. Если сервер не отвечает в установленное время, клиент получает ошибку таймаута. | помогает избежать бесконечного ожидания и позволяет клиенту обработать ошибки | таймауты могут быть сложны в настройке и управлении, особенно при высоких нагрузках и изменяющихся условиях сети |
| Блокировка (Blocking) | В синхронном взаимодействии клиентский поток блокируется до получения ответа от сервера. В этот период клиент не может выполнять другие операции. | простота реализации и отладки | может привести к снижению производительности и отзывчивости системы, особенно при высоких нагрузках |
| Зависимости (Dependencies) | При синхронном взаимодействии операции часто зависят друг от друга. Если одна операция не завершена, последующие операции не могут быть выполнены. | позволяет легко отслеживать порядок выполнения операций и управлять им | могут возникать узкие места и блокировки, особенно при сбоях или перегрузках в системе |
| Управление состоянием (State Management) | В синхронных системах управление состоянием может быть сложным, поскольку состояние может изменяться в зависимости от результата каждого запроса. | лёгкость в управлении состоянием при небольших масштабах и простой архитектуре | может стать сложным при увеличении масштабов системы и увеличении числа взаимодействующих компонентов |
| Изоляция ошибок (Error Isolation) | в синхронных системах ошибки, возникающие в одном компоненте, могут передаваться и влиять на другие компоненты, поскольку клиент ожидает завершения всей цепочки операций. | простота обработки ошибок при небольших системах | ошибки могут распространяться по всей системе, что усложняет управление и отладку |
| Параллелизм (Parallelism) | Синхронное взаимодействие ограничивает возможности параллельного выполнения операций, поскольку клиент блокируется до получения ответа. | упрощает поток выполнения операций в определённом порядке | ограничивает возможности масштабирования и параллельного выполнения задач |
YAML
openapi: '3.0.0'
info:
title: WeatherNow API
version: '1.0.0'
paths:
/weather:
get:
summary: Get current weather
responses:
'200':
description: Successful response
content:
application/json:
schema:
type: object
properties:
temperature:
type: number
humidity:
type: number
timestamp:
type: string
format: date-time YAML
asyncapi: '2.0.0'
info:
title: WeatherNow Async API
version: '1.0.0'
servers:
production:
url: api.weathernow.com
protocol: kafka
channels:
weather-updates:
description: Channel for publishing weather updates
publish:
summary: Publish weather data
operationId: publishWeatherData
message:
contentType: application/json
payload:
type: object
properties:
temperature:
type: number
humidity:
type: number
timestamp:
type: string
format: date-time
Сергей
BASH
tar -xzf kafka_2.13-2.8.0.tgz
cd kafka_2.13-2.8.0
config/zookeeper.properties.BASH
# Start ZooKeeper
bin/zookeeper-server-start.sh config/zookeeper.properties
config/server.properties. Убедитесь, что все необходимые параметры настроены, включая ID брокера, директорию хранения логов и адрес ZooKeeper.BASH
# Start Kafka Broker
bin/kafka-server-start.sh config/server.properties
BASH
bin/zookeeper-server-start.sh config/zookeeper.properties
bin/kafka-server-start.sh config/server.properties
kafka-topics.sh для создания нового топика. Укажите параметры — имя топика, количество разделов и фактор репликации (англ. replication factor).BASH
bin/kafka-topics.sh --create --topic weather-data --bootstrap-server localhost:9092 --partitions 3 --replication-factor 1
BASH
bin/kafka-topics.sh --list --bootstrap-server localhost:9092
--describe позволяет получить подробную информацию о топике, включая количество разделов, фактор репликации и статус разделов.BASH
bin/kafka-topics.sh --describe --topic my-topic --bootstrap-server localhost:9092
BASH
bin/kafka-topics.sh --alter --topic my-topic --config retention.ms=604800000 --bootstrap-server localhost:9092
BASH
bin/kafka-topics.sh --alter --topic my-topic --config cleanup.policy=delete --bootstrap-server localhost:9092
BASH
bin/kafka-topics.sh --alter --topic my-topic --config min.insync.replicas=2 --bootstrap-server localhost:9092
--alter.BASH
bin/kafka-topics.sh --alter --topic my-topic --partitions 5 --bootstrap-server localhost:9092
kafka-reassign-partitions.sh помогает в балансировке разделов.BASH
bin/kafka-reassign-partitions.sh --generate --zookeeper localhost:2181 --topics-to-move-json-file topics-to-move.json --broker-list "0,1,2"
JAVA
Properties props = new Properties();
props.put("bootstrap.servers", "localhost:9092");
props.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer");
props.put("value.serializer", "org.apache.kafka.common.serialization.StringSerializer");
Producer<String, String> producer = new KafkaProducer<>(props);
producer.send(new ProducerRecord<>("weather-data", "key", "value"));
producer.close();
JAVA
Properties props = new Properties();
props.put("bootstrap.servers", "localhost:9092");
props.put("group.id", "weather-consumers");
props.put("enable.auto.commit", "true");
props.put("key.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");
props.put("value.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");
Consumer<String, String> consumer = new KafkaConsumer<>(props);
consumer.subscribe(Arrays.asList("weather-data"));
while (true) {
ConsumerRecords<String, String> records = consumer.poll(Duration.ofMillis(100));
for (ConsumerRecord<String, String> record : records)
System.out.printf("offset = %d, key = %s, value = %s%n", record.offset(), record.key(), record.value());
}
pom.xml:XML
<dependency>
<groupId>org.apache.kafka</groupId>
<artifactId>kafka-clients</artifactId>
<version>2.8.0</version>
</dependency> JAVA
Properties props = new Properties();
props.put("bootstrap.servers", "localhost:9092");
props.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer");
props.put("value.serializer", "org.apache.kafka.common.serialization.StringSerializer");
Producer<String, String> producer = new KafkaProducer<>(props); pom.xml:XML
<dependency>
<groupId>org.apache.kafka</groupId>
<artifactId>kafka-clients</artifactId>
<version>2.8.0</version>
</dependency> JAVA
Properties props = new Properties();
props.put("bootstrap.servers", "localhost:9092");
props.put("group.id", "weather-consumers");
props.put("key.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");
props.put("value.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");
Consumer<String, String> consumer = new KafkaConsumer<>(props);
consumer.subscribe(Arrays.asList("weather-data")); JAVA
ProducerRecord<String, String> record = new ProducerRecord<>("weather-data", "sensor1", "temperature=25,humidity=60");
producer.send(record);
producer.close(); JAVA
// Консьюмер для обработки данных
Consumer<String, String> dataConsumer = new KafkaConsumer<>(props);
dataConsumer.subscribe(Arrays.asList("weather-data"));
while (true) {
ConsumerRecords<String, String> records = dataConsumer.poll(Duration.ofMillis(100));
for (ConsumerRecord<String, String> record : records) {
// Обработка данных
String processedData = processData(record.value());
// Публикация обработанных данных
ProducerRecord<String, String> processedRecord = new ProducerRecord<>("processed-weather-data", record.key(), processedData);
producer.send(processedRecord);
}
}
// Консьюмер для уведомлений
Consumer<String, String> notificationConsumer = new KafkaConsumer<>(props);
notificationConsumer.subscribe(Arrays.asList("processed-weather-data"));
while (true) {
ConsumerRecords<String, String> records = notificationConsumer.poll(Duration.ofMillis(100));
for (ConsumerRecord<String, String> record : records) {
// Отправка уведомлений
sendNotification(record.value());
}
} JAVA
// Консьюмер для аналитики
Consumer<String, String> analyticsConsumer = new KafkaConsumer<>(props);
analyticsConsumer.subscribe(Arrays.asList("processed-weather-data"));
while (true) {
ConsumerRecords<String, String> records = analyticsConsumer.poll(Duration.ofMillis(100));
for (ConsumerRecord<String, String> record : records) {
// Анализ данных
analyzeData(record.value());
// Сохранение результатов анализа
saveAnalysisResults(record.value());
}
} BASH
bin/kafka-topics.sh --create --topic weather-data --bootstrap-server localhost:9092 --partitions 3 --replication-factor 1
BASH
bin/kafka-topics.sh --list --bootstrap-server localhost:9092
BASH
bin/kafka-console-producer.sh --topic weather-data --bootstrap-server localhost:9092
BASH
bin/kafka-console-consumer.sh --topic weather-data --bootstrap-server localhost:9092 --from-beginning
config/log4j.properties.server.properties) для каждого брокера, включая указание параметров — id брокера, пути к логам, параметры репликации и данные о ZooKeeper.