Настройте повторную загрузку Spring для нескольких вызовов API

У меня есть приложение api для весенней загрузки, которое имеет конечную точку POST, давайте назовем его / doSomething как метод. При получении запроса для конечной точки / doSomething мне нужно сохранить эти данные в нашем приложении, а затем нужно сделать запрос GET для другого api [A] с этим запросом нужно ПОЛУЧИТЬ из API [B], а затем снова отправить в API [B]. В этом случае, каков наилучший способ обработать повторную попытку Spring.

Пожалуйста, найдите приведенный ниже код

@RequestMapping(value = "/subpub", method = RequestMethod.POST, headers = {"content-type=application/x-www-form-urlencoded"})
    public String subPub(HttpServletRequest request, HttpServletResponse response, @RequestBody String rawBody) {
    //persists some data on this database

    //this method will invoke api[A] and api[B]
    integrationServiceBean.processCourseMetaData("_id");
    return "OK"
}; 

IntegrationServiceBean класс

package com.org.reader.integration;

@Service
public class IntegrationServiceBean {


    /**
     * This method will process meta data submission for  
     * section details by section id and update meta data
     *
     * @param sectionId
     */
    @Retryable(RuntimeException.class)
    public void processCourseMetaData(final String sectionId) {

        System.out.println("Invoking processCourseMetaData");

        ResponseEntity<String> responseEntity = registrarService.findOneSection(sectionId);
        String responseBody = responseEntity.getBody();

        LinkedHashMap requestObj = (LinkedHashMap) JsonUtils.jsonToObject(responseBody);
        LinkedHashMap metaDataObj = (LinkedHashMap) requestObj.get(Constant.Response.META_DATA);
        if (!contextConfig.getMetaDataCopyable().isEmpty()) {

            metaDataObj.put(Constant.MetaData.COPYABLE, contextConfig.getMetaDataCopyable());
        }
        if (!contextConfig.getMetaDataPending().isEmpty()) {

            metaDataObj.put(Constant.MetaData.PENDING, contextConfig.getMetaDataPending());
        }
        metaDataObj.put(Constant.MetaData.LAUNCH_URL, getLaunchUrlByEnvironment(requestObj, sectionId));

        String updatedSectionPayload = JsonUtils.toJsonString(requestObj);

        registrarService.updateSection(sectionId, updatedSectionPayload);
    }

    @Recover
    public void recover(RuntimeException e){
        System.out.println("Recovering - returning safe value"+e.getMessage());

    }



}

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

И что было бы лучше всего


person Seth De    schedule 21.11.2016    source источник
comment
Пожалуйста, уменьшите размер второй части кода. Вы должны предоставить минимальный пример.   -  person George Sovetov    schedule 21.11.2016


Ответы (1)


Метод с тегом @Retryable вызывается в отдельном потоке, блокируя текущий выполняющийся поток.

С точки зрения перспективы вашего кода,

Сохранение происходит в потоке (например, поток A), а служба интеграции обрабатывается в другом потоке (например, поток B). Таким образом, поток A блокируется до тех пор, пока B. Таким образом, следующая строка integrationServiceBean.processCourseMetaData("_id"); блокируется до тех пор, пока не будет завершена успехом или исчерпанием лимита повторных попыток.

Переходя к вашему вопросу.

Сохранение данных не затронуто. Так что я не думаю, что есть какое-то снижение производительности.

Говоря о передовой практике

использование Retry всякий раз, когда есть раздел сети между службами, является хорошей практикой. Это делает приложение надежным.

person The Mighty Programmer    schedule 21.11.2016
comment
У меня есть проблема в потоке A, нам нужно отправить ответ обратно вызывающей стороне, например, статус успеха, если повторная попытка происходит в потоке B, поток A ждет, пока поток B не завершится, поэтому тайм-ауты для потока A могут произойти, есть ли способ сделать поток B асинхронным будет это проблема - person Seth De; 21.11.2016
comment
Если вы делаете вызов службы интеграции асинхронным. A ожидает, что B что-то вернет, другими словами, A зависит от вывода B. Поскольку B работает асинхронно, A вернулся, не дожидаясь B. Это повредит вам исключение. Если Служба интеграции ничего не возвращает. Отношения похожи на А, просто попросите службу интеграции и двигайтесь вперед. Другими словами, имеет значение только вызов службы, чем ожидание чего-либо от службы взамен. В этом случае вы можете подумать об асинхронном. - person The Mighty Programmer; 21.11.2016