前言
最近在研究Spring Boot的异步处理,准备写一篇文章。在收集数据的时候,我发现了一篇《SpringBoot中异步请求和异步调用》及其很多衍生文章。文章确实不错,但是文章中提到的“异步请求和异步调用”这两个概念一直让人费解,在衍生文章中也有掺杂。
最后,我忍不住想去探索一下,发现除了文章和衍生文章之外,没有其他证据可以区分这两个概念。直到我在Stack Overflow上找到了一篇七年前的文章,这个疑问才被解开。
今天,我们将探讨“异步请求和异步调用”这两个概念。
异步请求和异步调用的区别
在上面提到的文章中,有两段关于异步请求和异步调用的区别:
首先,异步请求用于解决并发请求对服务器造成的压力,从而提高请求的吞吐量;异步调用用于做一些不是主线流程,不需要实时计算和响应的任务,比如将日志同步到kafka进行日志分析。
区别2:异步请求会一直等待响应,结果需要返回给客户端;异步调用通常会立即返回到客户端,以响应并完成整个请求。至于异步调用的任务,在后台运行就够了,客户端不会在意。
仔细阅读和分析后,文章中提到的异步请求应该是指通过Servlet或Callable、DeferredResult、Spring中的WebAsyncTask等的AsyncContext对象对业务的异步处理。在本文中,异步调用是指类似于Spring中调用@Async注释的异步方法。
你看到上面两个概念的区别了吗,你觉得有意义吗?您认为您已经成功地将异步请求与异步调用区分开来了吗?
那么,你有没有想过一个问题,我们平时说请求一个接口,调用一个接口,不也是这个意思吗?它们在这里是如何变成两个完全不同的概念的?
疑问探究
带着以上问题,我开始用搜索引擎搜索。当我们发现异步请求和异步调用的区别时,我们发现的内容基本上来自上面的文章和衍生文章,或者异步和同步的区别。这并不代表什么,但也说明这两个概念的区别还没有得到普遍的认可。
于是我开始尝试通过英文搜索引擎进行搜索。我先搜索了“异步调用和异步请求的区别”,但是没有得到想要的结果。大多数文章仍然在讨论异步和同步的区别。
更改关键词搜索“异步调用和异步方法的区别”,结果是一样的,没有想要的文章。但是,在堆栈溢出上发现了一个相关的问题“与web服务相关的同步与异步”。
这个问题下面出现了两个短语:异步服务和异步调用。仔细看两个短语的解释,发现是想要的结果。
异步调用与异步服务
其实在英文搜索的过程中,已经发现在讨论异步和同步的区别时,经常会出现异步请求和异步调用,两者都是在讨论异步和同步的区别,而不是两者的区别。所以异步调用或异步请求本质上是一回事。
然而,文章《SpringBoot中异步请求和异步调用》中提到的异步请求和异步调用之间的区别并没有明确异步请求和异步调用在概念上是什么。而且只有少数文章这么说,所以可以认为异步请求和异步调用是同一个概念。作者的“异步调用”指的是异步服务。
为了进一步证明上述结论,下面简单翻译一下问答中两个概念的解释。
Asynchronous service和Asynchronous calls
Asynchronous service
当您的web服务被执行时,它会花费很多时间,比如从文件系统中读取一个大文件。此时,如果您使用“同步”web服务,那么客户端必须
须等待处理完成,通常会阻塞线程,对于高并发的服务,会出现性能问题。如果将web服务设置为异步服务,那么可以把耗时服务委托给另外一个线程,或者使用非阻塞机制,在未来的某刻进行返回。还以读取大文件为例,可以使用异步的ReadFile方法来读取大文件。这样便能避免线程阻塞,提高吞吐量。
Asynchronous calls
值得注意的是:你可以通过异步的方式调用一个非异步的的服务。比如在JavaScript中的Ajax的调用:
var jqxhr = $.ajax( "AnyService.svc" )
.done(function() { alert("success"); })
.fail(function() { alert("error"); })
.always(function() { alert("complete"); });
alert("Called");
执行上述示例,首先展示“Called”,然后展示“success”,因为执行的过程中并不需要等到服务返回的结果。而被调用的服务也不需要是异步的。
总之,服务实现的异步与同步特性完全独立于客户端调用的异步和同步特性。也就是说客户端可以异步的去调用同步服务,而且客户端也可以同步的去调用异步服务。
小结
通过上面的追踪分析,关于异步请求和异步调用我们可以理解为是一回事,同时我们还得知了所谓的客户端异步和同步与服务的异步与同步是相互独立的。也就是客户端可以异步请求也可以同步请求,服务可以异步处理也可以同步处理。两两组合可以有四种情况。
另外,更重要的是我们要学会通过搜索中英文资料来解答自己心中的疑惑,而且英文资料相对更准确一些,所以首推英文。在探索疑惑问题的过程中往往还能有不少意外的收获。