我有一个要求,我对它的设计感到有点困惑。
要求:iOS调用后端(java),后端调用云API,返回令牌以供将来调用。云API可能需要大约6到10秒来返回实际结果,因此它不会等待6到10秒,而是返回一个令牌并让调用者(在我的情况下是后端java服务器)来提取结果。
当前方法:iOS调用后端(java服务器),后端调用云API并获取令牌,然后它将线程休眠1秒钟并调用线程它命中云API以获取状态,如果状态未完成,则再次调用thread.sleep并继续,直到云API调用给出完整的结果。一旦云API返回结果,后端就会将结果返回给iOS。
该方法不具有可扩展性,是为了测试云API,但现在我们需要一种更具可扩展性的方法。
这就是我在考虑的问题 iOS调用后端,后端调用API并将结果发送回iOS(它显示一些静态屏幕只是为了让用户保持参与),同时它将对象放在Spring Thread pool Executor中。执行者每秒钟点击一次API并通过推送通知更新iOS,这一直持续到我们从云API获得最终结果。
这比现有的方法更好,但即使这看起来不可扩展,并且线程池执行器在一段时间后会变得疲惫(使其变慢)并且thread.sleep也不是一个好的选择。
我考虑过使用AWS SQS,但它没有提供实时处理,并且每1秒运行后台作业似乎不是一个好选择。
我也正在探索Apache Kafka并尝试了解它是否适合我的用例。
如果有人提到类似的用例,请告诉我。
答案 0 :(得分:1)
如果使用Spring 4.2(或更新)版本,可以使用@EventListener
与@Scheduled
同时使用。
首先创建一个事件对象,说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
}
整个流程应该像
这种方法将透明地获取结果,而不会弄乱业务逻辑,同时利用标准框架功能即。调度和异步事件发布&amp;处理
虽然我没有对此进行测试,但它应该可以工作,至少可以了解如何实现。使用Spring boot ver测试设置。由1.5.1.RELEASE
4.3.6.RELEASE
如果需要进一步的信息,请在评论中告知。
参考 - Spring中的应用程序事件(link)
答案 1 :(得分:0)
我正在考虑使用Spring ConcurrentTaskExecutor(让我们称之为cloudApiCall),一旦我从Cloud API收到令牌,我就会将未来的工作提交给执行者并将令牌返回给移动客户端。与ConcurrentTaskExecutor关联的线程将选择作业,调用Cloud API并将响应提交给另一个ConcurrentTaskExecutor(让它称之为pushNotification),该响应将负责将静默通知推送到Mobile客户端。与ConcurrentTaskExecutor(cloudApiCall)相关联的线程也会检查调用的状态,如果将来调用是必需的,它会将作业提交回ConcurrentTaskExecutor(cloudApiCall)。这将持续到我们得到完整的回复为止。