java:如何处理可能需要10秒左右的api调用

w51jfk4q  于 2021-06-07  发布在  Kafka
关注(0)|答案(2)|浏览(500)

我有一个要求,我对它的设计有点困惑。
要求:ios调用backend(java),backend调用cloudapi,后者为将来的调用返回令牌。cloudapi可能需要大约6到10秒来返回实际结果,因此它不会等待6到10秒,而是返回一个令牌,并让调用者(在我的例子中是后端java服务器)提取结果。
当前的方法是:ios调用后端(java服务器),后端调用cloud api并获取token,然后它休眠线程1秒,一旦线程被调用,它就会点击cloud api获取状态,如果状态是not completed thread.sleep被再次调用,这会一直持续到cloud api调用给出完整的结果。一旦cloudapi返回结果,后端就会将结果返回给ios。
这种方法是不可伸缩的,是为了测试云api而做的,但是现在我们需要一种更具伸缩性的方法。
这就是我所想的ios调用backend,backend调用api并将结果发送回ios(它显示一些静态屏幕只是为了让用户参与),同时它将对象放入spring线程池executor。执行器每隔一秒钟点击一次api,并通过push通知更新ios,直到我们从cloudapi得到最终结果。
这比现有的方法更好,但即使这样看起来也不可伸缩,线程池执行器也会在一段时间后耗尽(使其变慢),thread.sleep也不是一个好的选择。
我考虑过使用awssqs,但它不提供实时处理,每1秒运行一次后台作业似乎不是一个好的选择。
我也在探索apachekafka,并试图了解它是否适合我的用例。
如果有人处理过类似的用例,请告诉我。

bq9c1y66

bq9c1y661#

在这里 @EventListener 配合 @Scheduled 如果使用Spring4.2(或更新的)版本,则可以使用。
首先创建一个事件对象 APIResult 它将保存api结果

public class APIResult extends ApplicationEvent {   
    public APIResult(Object result) { 
        super(source);      
    } 
}

接下来为发布为的事件注册一个侦听器 APIResult ```
@Component
public class MyListener {

@EventListener
public void handleResult(APIResult result) {
   // do something ... 
}

}

接下来创建一个计划进程,该进程将保存尚未检索其结果的令牌

@Component
public class MyScheduled {

private final ApplicationEventPublisher publisher;

private List<String> tokens = new ArrayList<>();    

@Autowired
public MyScheduled (ApplicationEventPublisher publisher) { 
    this.publisher = publisher;
}

@Scheduled(initialDelay=1000, fixedRate=5000) // modify it as per requirement
public void callAPIForResult() {
    // call the API and get result for each token(s) ....
    this.publisher.publishEvent(new APIResult(result)); 
}

// method to add & remove tokens

}

整个流程应该是
应用程序向api提交请求并收集相应的令牌。
令牌被传递给调度服务以获取结果。
在下一次运行中,定时服务迭代可用的令牌并调用api来获取结果(如果结果可用,则发布事件,否则继续)
已注册的侦听器截获已发布的事件;自行处理结果或委托(如适用)
这种方法将透明地获取结果,而不干扰业务逻辑,同时利用标准框架特性,即。调度和异步事件发布与处理。
虽然我还没有测试这个,但它应该工作,至少给一个如何实施的想法。使用spring-boot-ver对设置进行了测试。 `1.5.1.RELEASE` 它的背后是Spring的阳光 `4.3.6.RELEASE` 如果需要任何进一步的信息,请在评论中告知。
引用-spring中的应用程序事件(链接)
vnjpjtjt

vnjpjtjt2#

我正在考虑使用SpringConcurrentTaskExecutor(我们称之为cloudapicall),一旦我从CloudAPI收到令牌,我将向executor提交一个未来的作业,并将令牌返回到移动客户端。与concurrenttaskexecutor关联的线程将选择作业,调用云api并将响应提交给另一个concurrenttaskexecutor(我们称之为pushnotification),后者将负责将静默通知推送到移动客户端。与concurrenttaskexecutor(cloudapicall)关联的线程还将检查调用的状态,如果将来需要调用,它将把作业提交回concurrenttaskexecutor(cloudapicall)。直到我们得到完整的答复。

相关问题