java - spring boot - 将正确的响应映射到请求,用于多异步调用
问题描述
我编写了一个 spring-boot 应用程序,它从用户那里接收一个名为 Calc 的对象,该对象包含两个参数,并返回一个包含复杂计算的答案(计算本身与问题无关)。因为系统可能很忙,所以每个对象都进入队列,队列上有一个按顺序传递的调度器,执行计算。
我的问题是如何将项目的计算结果返回到正确的请求。
我已经包含了我编写的代码:
控制器:
@RestController
public class CalcController {
@Autowired
private CalculateService calculateService;
@RequestMapping("/")
public int calculate(@RequestBody Calc calc) {
return calculateService.calculate(calc);
}
}
计算对象:
@Data
public class Calc {
private int paramA;
private int paramB;
}
计算服务:
@Service
public class CalculateService {
private BlockingQueue<Calc> calcQueue;
@PostConstruct
private void init() {
calcQueue = new LinkedBlockingDeque<>();
}
public int calculate(Calc calc) {
calcQueue.add(calc);
// TODO: Return calculation result.
return 0;
}
@Scheduled(fixedRate = 2000)
public void calculateQueue() throws InterruptedException {
while (!calcQueue.isEmpty()) {
Calc calc = calcQueue.take();
int result = Calculator.calculate(calc);
// TODO: Return calculation result to the right request.
}
}
}
谢谢
解决方案
您可以使用 Spring 的 @Async 功能
- 创建线程池
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.scheduling.annotation.EnableAsync; import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; import java.util.concurrent.Executor; @EnableAsync @Configuration public class ThreadConfig { @Bean(name = "threadPoolTaskExecutor") public Executor threadPoolTaskExecutor() { return new ThreadPoolTaskExecutor(); } }
- 更新calculateService,你不需要在Queue中存储对象,它将由Spring的async工具处理
import org.springframework.stereotype.Service; import java.util.concurrent.CompletableFuture; @Service public class CalculateService { @Async("threadPoolTaskExecutor") public CompletableFuture<Integer> calculate(Calc calc) { int result = Calculator.calculate(calc); return CompletableFuture.completedFuture(result); } }
- 将控制器方法更新为
import com.example.service.CalculateService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutionException; @RestController public class CalcController { @Autowired private CalculateService calculateService; @RequestMapping("/") public int calculate(@RequestBody Calc calc) throws ExecutionException, InterruptedException { CompletableFuture<Integer> resultFut = calculateService.calculate(calc); // some other calls/logic return resultFut.get(); } }
如果您想按请求存储会话,请参阅此SO 帖子
推荐阅读
- homekit - ESP HomeKit - 无法在某些路由器上添加附件
- zip - WinRar 通过 cli 压缩多个文件夹
- excel - 如何根据动态变化的数据从 Excel 中的一系列单元格返回地址?
- php - 从python脚本获取变量到php页面
- python - 从视频帧中采样并将它们保存为图像 - python openCV
- r - 如何在 R 中创建打印功能?
- java - 如何在不删除现有对象的情况下将新对象存储在arraylist中
- macos - 将自签名证书作为受信任的根证书添加到 Apple 钥匙串
- java - 依赖项的Maven依赖
- ruby-on-rails - Rails api POST 测试不允许我访问 json 对象