问题 确定Web应用程序中的同步与异步


题:

我被告知最佳实践表明,长时间运行的http Web请求应该转换为更短的异步请求,并具有轮询完成的机制。

为什么?

重要区别:

我正在开发一个Web服务API。它不是由浏览器(它会挂起负载)调用,而是由富客户端(无论如何异步调用远程服务)和脚本(可以执行相同的异步技巧)调用

动机:

我想知道,因为我正在尝试决定何时应该异步请求,截止点是什么?我正在研究基于Web的API,其请求需要0.001秒到400秒(以及介于两者之间的任何地方),具体取决于请求(不是参数,而是他们调用的实际方法)。

我可以使一切都异步(除了轮询命令完成),但这使API客户端完成的工作变得复杂(即从请求中获取结果,轮询完成等)

据我所知,我也可以使所有内容同步,因为无论如何都要完成相同数量的工作,因此负载似乎相似。

此外,我使用的所有Web服务似乎都遵循混合模型,因此他们必须以某种方式做出决定。

我真正回答这个问题的唯一方法就是知道为什么存在最佳实践。


13060
2018-05-11 22:23


起源

在确定连接超时之前,浏览器允许连接保持空闲多长时间? - Will A
@Will“这取决于”,但用户很可能会在此之前很长时间内点击REFRESH REFRESH REFRESH REFRESH BACK BACK REFRESH(虽然可能会诅咒网站开发者)。 (我做)
@pst - 好点,我也是! - Will A
@pst这是一个缺乏加载屏幕的问题。如果请求花费的时间过长,则会在开始时返回加载屏幕,并通知用户进度。 - Raynos
@Pace如果富客户端没有调用它,那么具有良好定义的通信协议的TCP套接字会更好吗? - Raynos


答案:


异步API不会阻止。每个同步调用都会等待并阻止您的结果返回。这只是一个睡眠线程和浪费的计算。

如果您需要发生某些事情,请发送异步请求,并在请求返回时进行进一步的计算。这意味着您的线程处于空闲状态,可以接受其他工作。

异步请求是扩展到数千个并发用户的方法。

但这使API客户端完成的工作变得复杂

这只是API设计的问题。通常,您可以使用回调调用Web API来处理此问题。不需要轮询。

WebService.Call("someMethod" (data) -> {
   // do something when data returns.
});

16
2018-05-11 22:29



睡眠线程如何浪费计算?此外,如果客户希望,客户端始终可以异步打包调用。这对服务器规模没有帮助,因为服务器仍在进行工作。如果必须,服务器可以异步与其他服务器进行通信以进行扩展,但这并不要求客户端 - 服务器通信是异步的。 - Pace
@Pace你可以拥有的线程数量有限。每个线程都在睡觉而不是闲置是一个浪费的线程。它可以帮助客户扩展,因为他们无需在服务器上等待完成计算。 - Raynos
对于异步服务器,每个请求都有两个线程。一个线程在执行实际工作,另一个线程正在响应轮询,我没有看到异步模型如何减少服务器上的线程数。 - Pace
@Pace异步服务器可以通过基于事件循环来减少此问题。看一下像nginx和node.js这样的例子 - Raynos
这是一个有效的论点,可以被认为是我的问题的答案。从技术上讲,除非我转移到基于事件循环的服务器(现在使用Tomcat),否则我不会获得这种优势,所以我会等待,看看其他响应是什么回来并明天标记为正确。 - Pace