Что следует учитывать при подключении стороннего сервисного интерфейса? (один)

задняя часть

стандарт связи

  1. Определяем протокол Http/Https
  2. Определяем формат передачи параметра json/x-www-form-urlencoded/...
  3. Тип данных определенного параметра интерфейса (легко наступить на яму, когда слабый тип подключен к сильно напечатанному языку)
  4. Способ определения верификации личности
    • token
    • Подпись параметра: один ключ, открытый ключ обмена
    • Проверка сертификата
  5. Определите структуру ответа (унифицированный код успешного ответа и т. д.)

Обработка исключений

В целом структуры исключений следует разделить на три категории:

  1. RpcException: исключение вызова
  2. BusinessException: Бизнес Исключение
  3. Исключение: другие программные исключения

Для разных сторонних сервисов могут быть разные стандарты классификации того, каким аномалиям соответствуют те или иные обстоятельства.Как правило, существуют следующие правила:

  1. RpcException, когда Http StatusCode == 500
  2. Код бизнес-ответа! = BusinessException, когда унифицированный код ответа об успехе
  3. Другие исключения не классифицируются

последовательность

Поскольку дело доходит до оплаты, возвраты имеютразместить заказконцептуальный интерфейс или когда дело доходит до вопросов состояния, нужно учитыватьпоследовательностьПроблема. Как правило, существуют следующие требования (сторонние сервисы также называются upstream):

  1. Исходящие данные должны быть доступны локально
  2. Состояние восходящего потока совпадает с локальным состоянием каждого фрагмента данных (или состояние может быть относительно сопоставлено один к одному)

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

инициирование транзакции

  1. Определите, какое поле является уникальным идентификатором в интерфейсе, обычно requestNo. Значение этого поля соответствует восходящим данным и локальным данным один к одному. RequestNo, существующий в восходящем направлении, должен существовать локально.

  2. Статус отдела:

  • PENDING: Локальные данные созданы, запрос интерфейса не инициирован
  • UNCONFIRMED: Локальные данные созданы, я не знаю, был ли инициирован запрос интерфейса или нет, жду ответной проверки
  • PROCESSING: запрос интерфейса был инициирован, и восходящий поток ответил, ожидая проверки, чтобы подтвердить окончательный статус.
  • SUCCESS: Заключительное государство, бизнес был успешным
  • FAIL: Конечное состояние, бизнес не удался
  • DEAD: конечное состояние, локальные данные созданы, интерфейс не может быть запрошен на жизнь и смерть, и соответствующие данные не могут быть найдены в апстриме, не более того, это также может быть классифицировано как FAIL в соответствии с реальной ситуацией

Здесь процесс можно описать так:

  1. Перед инициированием вышестоящего интерфейса сгенерируйте глобально уникальныйrequestNo, статус этого фрагмента данных — ОЖИДАНИЕ, и он отправлен в хранилище.
  2. Когда вышестоящий интерфейс запрашивается без исключения:
    1. Если разрешено, состояние обрабатывается синхронно, а обновленное состояние сохраняется в репозитории.
    2. В противном случае он напрямую обновляется до PROCESSING, указывая на то, что восходящий запрос был успешным и ожидает дальнейшего подтверждения.
  3. Восходящий интерфейс запроса встречает исключение RpcException, которое обновляется до PROCESSING, указывая на то, что восходящий запрос выполнен успешно и ожидает дальнейшего подтверждения состояния.
  4. Восходящий интерфейс запроса сталкивается с BusinessException и обновляется до FAIL, указывая на то, что восходящий запрос выполнен успешно и ожидает дальнейшего подтверждения состояния. (Здесь может быть обработано как ОБРАБОТКА в соответствии с различными кодами возврата бизнеса, ожидая дальнейшего подтверждения)
  5. Другое Исключение, обнаруженное во время обработки, обновлено до UNCONFIRMED, не уверен, был ли запрошен восходящий поток, ожидание дальнейшего статуса подтверждения, который можно резюмировать как сбой обработки локальной транзакции, то есть сбой при сохранении в локальную базу данных.

Если у вас низкая степень доверия к восходящему потоку, вы можете напрямую объединить состояние PROCESSING с состоянием UNCONFIRMED, которое обрабатывается при просмотре транзакции.

Следующий раздел Pseudo Code будет описан с использованием вызова интерфейса процесса:

// 开启本地事务
startTrans();
Order order = new Order();
// 唯一请求号
String requestNo = UUID();
order.setRequestNo(requestNo);
order.setState(OrderState.PENDING);
order.save();
 // 提交本地事务
commit();

try {
    startTrans();
    RpcResponse rpcRes = rpcService.requestToRpcCreateOrder(...);
    order.setState(OrderState.PROCESSING); 
    
    // 如果你的接口可以同步返回业务状态
    if(rpcRes.getState() == 'SUCCESS') {
        order.setState(OrderState.SUCCESS); 
    }
    if(rpcRes.getState() == 'FAIL') {
        order.setState(OrderState.FAIL); 
    }
    
    order.save();
    commit();
} catch(RpcException e) {
    startTrans();
    // 认为是处理中,等待后续回查
    order.setState(OrderState.PROCESSING);
    order.save();
    commit();
} catch(BusinessException e) {
    startTrans();
    // 认为是失败
    order.setState(OrderState.FAIL);
    // 失败时,建议记录rpc响应参数
    order.setRpcResponseCode(e.getCode());
    order.setRpcResponseMsg(e.getMsg());
    order.save();
    commit();
} catch(Exception e) {
    startTrans();
    // 认为是待确认,等待后续回查
    order.setState(OrderState.UNCONFIRMED);
    order.save();
    commit();
}

Ретроспективный анализ транзакции (повторная попытка)

После описанного выше процесса данные останутся в двух состояниях: UNCONFIRMED и PROCESSING, поэтому эти два состояния дополнительно подтверждаются, чтобы гарантировать, что данные достигнут конечного состояния.

Существует несколько способов реализации обзора транзакций:

  1. Используйте таймер для проверки данных, статус базы данных которых НЕ ПОДТВЕРЖДЕН или В ОБРАБОТКЕ.
    • Убедитесь, что в базе данных есть индекс
    • Если поле requestNo также имеет индекс, можно использовать механизм покрывающего индекса, чтобы сократить время запроса.Как правило, для запроса статуса исходящих данных требуется только requestNo.
  2. Сохраните requestNo данных UNCONFIRMED или PROCESSING в Redis, а затем используйте таймер для обработки.
  3. Используйте очередь для заполнения UNCONFIRMED и PROCESSING в очереди просмотра.

На самом деле, если ваш RPC-запрос не нужно возвращать синхронно, рекомендуется использовать очередь сообщений с механизмом транзакций, в противном случае при использовании схемы очереди необходимо учитывать увеличение сложности.

Так что же делать с UNCONFIRMED и PROCESSING соответственно?

  • В соответствии с PROCESSING идея обработки очень проста, потому что восходящий поток этого состояния может определенно вернуть соответствующее состояние (фактически, некоторые восходящие потоки не обязательно), если соответствующее состояние запрашивается и обновляется до SUCCESS или FAIL.

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

    • Повторно инициируйте этот запрос (убедитесь, что восходящий интерфейс является идемпотентным, иначе вам придется обрабатывать его самостоятельно)
    • Обновите до DEAD, отклоните этот запрос

    Если запись существует выше по течению, она будет рассматриваться как ОБРАБОТКА.

Если ваш вышестоящий сервер предоставляет уведомления об асинхронной обработке, вы можете пройти этап проверки транзакции таким же образом.

Резюме и размышления

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