如何使用 Spring Boot 构建非阻塞异步 Web 服务
Posted
技术标签:
【中文标题】如何使用 Spring Boot 构建非阻塞异步 Web 服务【英文标题】:How to build a Non Blocking Asynchronous Web service Using Spring boot 【发布时间】:2017-11-12 14:23:28 【问题描述】:我有一个使用 Spring Boot 设计的 RestFul Web 服务。
Web 服务非常繁重,因为它必须在启动时进行大量数据库调用,并且在其余端还需要进行大量 IO 操作以提供结果。
我想让 Restful Api 成为异步的,这样它就可以更具可扩展性,而且它也不需要时间来提供它的结果。
我查看了 Spring async https://spring.io/guides/gs/async-method/
我什至实现了这个,但我无法测试这是否是异步的。
如果我想要类似的东西怎么办
如果向 url /all 发出请求
它显示网络服务正在立即处理结果,然后在所有过程完成后显示实际结果。
这怎么可能?
我也调查了这个http://callistaenterprise.se/blogg/teknik/2014/04/22/c10k-developing-non-blocking-rest-services-with-spring-mvc/。
此问题中没有代码,因为这是我面临的设计问题,如何解决请多多包涵。谢谢
【问题讨论】:
【参考方案1】:Spring Boot 自动支持Servlet spec 3+ async handling of http 请求。
最简单的利用方式如下:
public Callable<ResponseEntity<?>> myProcessingMethod ()
return () -> ResponseEntity.ok (myHeavyService.doTheWork ());
上面的重点是尽快释放你的HTTP请求处理线程,以便为下一个请求做好准备。 服务调用完成后,控制权将返回到 http 处理线程,以便将结果发送给调用者。
现在,如果您希望服务方法异步执行,您可以使用 @Async
注释该方法。
但是,您不能在上面的休息处理程序中使用该方法。
上面的代码需要改成这样的:
public ResponseEntity<?> myProcessingMethod ()
myHeavyService.doTheWorkAsync ()
return ResponseEntity.ok ();
【讨论】:
【参考方案2】:你在那里问了两个不同的问题。
-
如何在 Java 中构建异步服务器
如何测试其性能
在我看来,您对第一个问题的解决方案是有效的。当然你可以使用Vertx from within SpringBoot,或Quazar,或Akka。但这取决于您的用例。
对于第二个问题,我建议使用wrk tool。由于您的代码不应该阻塞太多,您将能够处理更多的并发请求。您只应注意,最好从单独的机器上运行 wrk
,而不是从运行 Java 的服务器上运行。
【讨论】:
【参考方案3】:Public interface Callback<T>
public void callWhenDone(T result);
//process the result in you implemenation
启动处理数据库查询的线程
public class MyThread implements Runnable
Callback callback;
//create thread by passing implemenation of callback
public MyThread(Object parameter,Callback c)
// store parameter for later user
this.callback=c;
public void run()
//call db queries and when you get the results call the callbak
callback.callWhenDone(result);
启动线程 new MyThread(params,CallBackImplemntation).start()
【讨论】:
以上是关于如何使用 Spring Boot 构建非阻塞异步 Web 服务的主要内容,如果未能解决你的问题,请参考以下文章
使用 Kotlin 协程的 Spring Boot Rest 服务
spring cloud微服务快速教程之 gateway 服务网关