← Назад к вопросам
Приведи пример синхронной коммуникации
1.0 Junior🔥 131 комментариев
#Docker, Kubernetes и DevOps
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI23 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Приведи пример синхронной коммуникации
Что такое синхронная коммуникация?
Синхронная коммуникация — это когда отправитель ждёт ответ перед тем, как продолжить работу:
Отправитель Получатель
| |
|--- Отправляю запрос -------> |
| |
| <---- Ожидаю ответ ------- | Обрабатываю
| |
| <---- Возвращаю ответ ------|
| |
|--- Продолжаю работу -------> |
Это как позвонить в поддержку — ты ждёшь, пока тебе ответят.
Пример 1: HTTP Request-Response (REST API)
Самый распространённый пример синхронной коммуникации в веб-приложениях:
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
public class SyncHttpExample {
public static void main(String[] args) throws Exception {
HttpClient client = HttpClient.newHttpClient();
// Создаём запрос
HttpRequest request = HttpRequest.newBuilder()
.uri(new URI("https://api.github.com/users/torvalds"))
.GET()
.build();
// ✅ Синхронное ожидание ответа
HttpResponse<String> response = client.send(request,
HttpResponse.BodyHandlers.ofString());
// Продолжаем работу только когда пришёл ответ
System.out.println("Status: " + response.statusCode());
System.out.println("Body: " + response.body());
}
}
Поток выполнения:
1. Создаём запрос
2. Отправляем (блокируется здесь)
3. Ждём ответа от сервера
4. Получили ответ
5. Продолжаем (только здесь!)
Пример 2: Вызов метода в Spring
@RestController
@RequestMapping("/api")
public class UserController {
private final UserService userService;
@GetMapping("/users/{id}")
public ResponseEntity<UserDTO> getUser(@PathVariable Long id) {
// Синхронный вызов сервиса
User user = userService.findById(id); // ✅ Блокирует, ждёт результата
// Только когда вернулся результат, продолжаем
return ResponseEntity.ok(new UserDTO(user));
}
}
@Service
public class UserService {
private final UserRepository userRepository;
public User findById(Long id) {
return userRepository.findById(id) // Запрос в БД
.orElseThrow(() -> new NotFoundException("User not found"));
}
}
Временная шкала:
HTTP запрос
|
v
getUser() вызывает userService.findById()
|
v
запрос в БД (SELECT)
|
v
Текущий поток БЛОКИРУЕТСЯ, ждёт ответа
|
v
Вернулись данные
|
v
Возвращаем HTTP 200 с данными
Пример 3: Синхронный вызов внешнего API
@Service
public class PaymentService {
private final RestTemplate restTemplate;
public void processPayment(Order order) {
// Синхронный вызов платёжного API
PaymentResponse response = restTemplate.postForObject(
"https://payment.api/charge",
new PaymentRequest(order.getAmount(), order.getCard()),
PaymentResponse.class
);
// Здесь код выполняется ТОЛЬКО если пришёл ответ
if (response.isSuccess()) {
order.setStatus("PAID");
logger.info("Payment processed for order " + order.getId());
} else {
throw new PaymentException("Payment failed: " + response.getError());
}
}
}
Проблема синхронности:
Обработка заказа
|
v
Вызов платёжного API (может быть медленно!)
|
v
Поток ЖДЁТ 1-5 секунд
|
v
Поток используется впустую (не обрабатывает другие запросы)
|
v
Ответ от API
|
v
Продолжаем обработку
Пример 4: JDBC и базы данных
public class UserDAO {
// Синхронное получение данных из БД
public User getUserById(Long id) {
String sql = "SELECT * FROM users WHERE id = ?";
try (Connection conn = dataSource.getConnection();
PreparedStatement stmt = conn.prepareStatement(sql)) {
stmt.setLong(1, id);
// ✅ Синхронный запрос — блокируем поток
ResultSet rs = stmt.executeQuery();
if (rs.next()) {
return new User(
rs.getLong("id"),
rs.getString("name"),
rs.getString("email")
);
}
} catch (SQLException e) {
throw new RuntimeException(e);
}
return null;
}
}
Пример 5: Блокирующее чтение файла
public class FileExample {
// Синхронное чтение файла
public String readFile(String path) {
try {
// ✅ Поток блокируется, пока файл не прочитается
byte[] data = Files.readAllBytes(Paths.get(path));
return new String(data);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
public static void main(String[] args) {
FileExample example = new FileExample();
// Поток ждёт завершения чтения
String content = example.readFile("large_file.txt");
// Только после этого продолжаем
System.out.println("File size: " + content.length());
}
}
Пример 6: Синхронный вызов микросервиса в Spring Boot
@Service
public class OrderService {
private final RestTemplate restTemplate;
private final UserServiceClient userClient;
public Order createOrder(CreateOrderRequest request) {
// Синхронный вызов микросервиса User Service
UserDTO user = userClient.getUserById(request.getUserId());
// Поток ждёт ответа от User Service
if (user == null) {
throw new UserNotFoundException("User not found");
}
// Синхронный вызов микросервиса Inventory Service
InventoryDTO inventory = inventoryClient.checkStock(request.getProductId());
// Снова ждём
if (!inventory.isAvailable()) {
throw new OutOfStockException("Product out of stock");
}
// Создаём заказ
Order order = new Order();
order.setUser(user);
order.setProduct(request.getProductId());
order.setStatus("CREATED");
return orderRepository.save(order);
}
}
@Component
public class UserServiceClient {
private final RestTemplate restTemplate;
public UserDTO getUserById(Long userId) {
// Синхронный вызов с таймаутом 5 секунд
return restTemplate.getForObject(
"http://user-service/api/users/" + userId,
UserDTO.class
);
}
}
Временная шкала создания заказа:
Поступил HTTP запрос
|
v
creatOrder() вызывает getUserById()
|
v
Отправляем запрос к User Service, БЛОКИРУЕМСЯ
|
v
Ожидание 100-500ms
|
v
Ответ от User Service
|
v
Вызываем inventoryClient.checkStock()
|
v
Отправляем запрос к Inventory Service, БЛОКИРУЕМСЯ
|
v
Ожидание 100-500ms
|
v
Ответ от Inventory Service
|
v
Сохраняем в БД
|
v
Возвращаем ответ (200-1000ms позже)
Проблемы синхронной коммуникации
// ❌ Проблема: один медленный сервис блокирует весь поток
public Order createOrder(CreateOrderRequest request) {
// User Service: 100ms
UserDTO user = userClient.getUserById(request.getUserId());
// Inventory Service: 200ms
InventoryDTO inventory = inventoryClient.checkStock(request.getProductId());
// Payment Service: 2000ms (медленно!)
PaymentDTO payment = paymentClient.charge(request.getPaymentInfo());
// Итого: 2300ms на обработку одного заказа
// За это время поток не может обрабатывать другие запросы!
}
Преимущества синхронной коммуникации
- Простота — легко писать и понимать код
- Надёжность — сразу видим результат или ошибку
- Транзакции — можно использовать ACID гарантии
- Отладка — просто ставим breakpoint и отлаживаем
Недостатки синхронной коммуникации
- Низкая масштабируемость — один медленный API блокирует весь поток
- Трудности в микросервисах — цепочка вызовов может быть медленной
- Зависимости — если целевой сервис упал, твой сервис тоже не работает
- Неэффективное использование ресурсов — потоки ждят вместо того, чтобы обрабатывать
Вывод
Синхронная коммуникация — это стандартный паттерн в веб-приложениях, который используется когда:
- Нужен результат прямо сейчас
- Нужны ACID гарантии
- Простота важнее производительности
Для высоконагруженных систем используют асинхронную коммуникацию (message queues, event streaming).