【问题标题】:Configure spring boot retry for multiple API calls为多个 API 调用配置 Spring Boot 重试
【发布时间】:2016-11-21 10:39:38
【问题描述】:

我有一个 Spring Boot api 应用程序,它有一个 POST 端点,让我们把它称为 /doSomething 作为方法。当接收到 /doSomething 端点的请求时 我需要将该数据保存在我们的应用程序中,然后需要对另一个 api[A] 发出 GET 请求,该请求必须从 API[B] 获取,然后再次必须发布到 API[B]。在这种情况下是什么处理弹簧重试的最佳方式。

请找到下面的代码

@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());

    }



}

我的问题是,如果对集成服务 bean 应用重试,是否会对应用程序的主要部分产生性能影响,例如在主端点上保存数据。

最好的做法是什么

【问题讨论】:

  • 请减小第二段代码的大小。您应该提供 minimal 示例。

标签: java spring performance spring-boot spring-retry


【解决方案1】:

标记为@Retryable的方法通过阻塞当前正在执行的线程在单独的线程中被调用。

就您的代码预期而言,

正在线程(例如线程 A)中进行保存,并且正在其他线程(例如线程 B)中处理集成服务。因此,线程 A 被阻塞,直到 B 完成。所以integrationServiceBean.processCourseMetaData("_id"); 的下一行被阻塞,直到成功或重试限制耗尽。

来回答你的问题。

保存数据不变。所以我认为不会对性能造成任何影响。

谈论最佳实践

当服务之间存在网络分区时,使用重试是一种很好的做法。 它使应用程序变得健壮。

【讨论】:

  • 我在线程 A 中有一个问题,如果在线程 B 上发生重试,我们需要将响应发送回调用者,例如成功状态,线程 A 等待线程 B 完成,因此线程 A 可能发生超时任何使线程 B 异步的方法都会是一个问题
  • 如果您正在使集成服务调用异步。 A 期望 B 返回一些东西,换句话说,A 取决于 B 的输出。由于 B 正在运行是异步的,A 没有等待 B 就返回了。它会伤害你的异常。如果集成服务没有返回任何内容。关系就像 A 只是要求集成服务并继续前进。换句话说,唯一重要的是,调用服务而不是期望从服务中得到回报。在这种情况下,您可能会想到异步。
猜你喜欢
  • 2018-02-26
  • 2020-09-20
  • 1970-01-01
  • 2021-02-16
  • 2018-08-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多