В КУРСЕ?

Разбираемся в теме

Клиент-серверные приложения на Java: контракт, ожидание и повтор запроса

В клиент-серверной системе действие проходит через несколько границ: клиент формирует запрос, сеть передает его, сервер проверяет и выполняет операцию, затем возвращается ответ. Сбой на любом участке меняет то, что известно каждой стороне. Поэтому надежность строится не только на успешном обмене, но и на заранее определенном поведении при неопределенности.

Контракт описывает смысл обмена

Запрос должен иметь понятный адрес, метод, структуру данных и правила проверки. Ответ сообщает не только данные, но и исход операции. Клиентская проверка удобна для пользователя, однако сервер все равно проверяет поступившие значения самостоятельно. Данные могли прийти от другой версии клиента или быть изменены до отправки. Полезно отдельно описывать ошибки формата, отсутствие нужного объекта и временную недоступность. Если все случаи превращаются в одно сообщение ошибка, клиенту трудно выбрать корректное действие. Контракт также задает, какие поля обязательны и что означает отсутствие значения, чтобы стороны не делали разные предположения.

Ожидание должно иметь границы

Стандартный HttpClient в Java поддерживает синхронную отправку через send и асинхронную через sendAsync. Во втором случае дальнейшая работа связывается с CompletableFuture. Асинхронность не отменяет обработку ошибок и ограничение числа одновременных запросов. Важно различать ожидание соединения и ожидание результата операции: это не одна и та же стадия. Для сетевого взаимодействия задают подходящие ограничения времени и понятное поведение после их истечения. Бесконечное ожидание оставляет пользователя и ресурсы в неопределенном состоянии. Но истекшее время клиента еще не доказывает, что сервер не успел выполнить действие.

Повтор может создать лишний результат

Представим создание вымышленной заявки. Сервер сохранил ее, но ответ потерялся по пути. Если клиент просто повторит создание, появятся две заявки. Для таких операций заранее проектируют защиту от повторного выполнения, например идентификатор логического действия и серверный учет его результата. Повтор тогда связывается с тем же намерением, а не выглядит как новая независимая команда. Это отличается от слепого повтора любой ошибки. Также полезно отделять ошибку выполнения от неизвестного исхода и предусматривать проверку состояния. Журналы помогают сопоставить события по идентификатору, но в них не следует сохранять секреты или избыточные личные данные.

Попробуйте на практике

Смоделируйте обмен клиента и сервера на бумаге без подключения к сети и изменения реальных данных.

  1. Опишите вымышленную операцию создания заявки с двумя обязательными полями и идентификатором логического действия.
  2. Нарисуйте обычный путь запроса и ответа, указав момент, когда сервер сохраняет результат.
  3. Добавьте потерю ответа после сохранения и повтор клиента, определив, как сервер распознает прежнее действие.
  4. Составьте три разных итоговых состояния для клиента: подтвержденный успех, подтвержденный отказ и неизвестный результат с необходимостью проверки.

Как проверить результат. Повтор не создает вторую заявку, истечение ожидания не объявлено доказанным отказом сервера, а каждое состояние имеет определенный следующий шаг.

Частые вопросы

Асинхронная отправка автоматически делает приложение надежным?

Нет. Она меняет организацию ожидания, но не решает вопросы проверки данных, ограничения нагрузки, повторов и неизвестного исхода. Эти правила проектируют отдельно.

Можно ли повторять любой запрос после сетевой ошибки?

Нет. Нужно понимать, меняет ли операция состояние и может ли повтор выполнить ее второй раз. Без такого анализа автоматический повтор способен создать дубли или другие нежелательные последствия.

Самостоятельный разбор темы. Содержание конкретной обучающей программы здесь не представлено.

Зарегистрируйтесь, чтобы уточнить возможность доступа к этому материалу

Зарегистрироваться
← К списку материалов