在异步调用返回

时间:2016-01-29 06:55:47

标签: http asynchronous request webserver response

我还没有理解Web服务器线程的行为,如果我做了一个异步调用来说一个数据库,并立即向客户端返回响应(说OK),甚至没有等待异步调用返回。首先,这是一个好方法吗?进行异步调用的线程会发生什么,如果再次使用它来提供另一个请求,然后先前的异步调用将返回到此特定线程。或者,Web服务器保持此线程等待,直到它所做的异步调用,返回。然后问题是许多挂起的线程将打开,并且Web服务器可用于接受更多请求。我正在寻找答案。

2 个答案:

答案 0 :(得分:2)

这取决于HTTP服务器的工作方式。但你应该非常谨慎。

假设您有一个主事件循环来处理传入的HTTP连接,以及管理HTTP通信的工作线程。 只有当工作线程有效地完全准备就绪时,才应该认为工作线程已接受新的HTTP请求管理。

就纯HTTP而言,更重要的是避免在收到整个查询之前发送回复。看起来很简单,而且情况通常如此。但是如果查询作为一个主体,可能是一个分块的主体,它可能需要时间来接收整个消息。 您应该从不之前发送响应,除非它类似于400错误的请求响应,然后是真正的tcp / ip连接关闭。如果您没有这样做,并且您有消息长度解析问题,那么您在查询结束之前发送响应的事实可能会导致安全问题。在某种http走私问题中,它可用于利用服务器与服务器前面的任何其他HTTP代理(ssl终结器,反向代理等)之间的消息解析差异。对于这个代理,如果你做了回复,就意味着你有了整个信息,它可以发送下一条消息,你实际上认为这只是身体的另一部分。

现在,如果您有完整的消息,您可以决定发送早期响应并分离异步任务以真正执行某些操作。但这意味着:

  • 您必须假设不应生成更多输出,您不会尝试向请求发布者发送任何输出,您应该考虑通信现已关闭
  • 工作线程不应该收到新的管理请求,这是困难的部分。如果此线程被标记为可用于新请求,则线程管理器也可能 kill (您在与工作者关联的Nginx或Apache请求计数器中,并且在达到限制后它们被杀死,创造新的)。它也可能会收到一个gracefull reload命令(通常是一个kill)等等。

因此,您开始进入一个区域,您应该知道HTTP服务器的内部结构,可能由您管理,也可能不管理,以及迟早会出现更改的地方。而你开始做出非常奇怪的事情,这通常导致奇怪的问题,难以重现。

通常,处理异步任务的最佳方式是使用消息传递系统,同时仍然能够理解发生的情况。将任务列表放在队列中,然后获得一个并行异步工作进程,它可以完成这些任务。如果需要,跟踪这些任务的状态。 同样的事情可能适用于客户端,在收到非常快的HTTP回答后,可能需要对任务状态执行一些ajax状态轮询。您可能只需要检查队列中任务的状态以发送响应。

你会对整个事情有更多的控制权。

对我来说,我真的不喜欢分离线程,来自奇怪的代码,执行繁重的任务而没有任何方式输出状态或报告错误,并且可能阻止了良好的应用程序停止调用(仍在等待奇怪的线程加入)并不意味着一个killall。

答案 1 :(得分:1)

这取决于此异步操作是否执行应通知客户端的内容。

如果返回200 OK(即成功完成),稍后异步操作失败,则客户端将不知道错误。

你当然有一些选择,例如通过websocket发送某种推送通知或发送另一个请求,这将返回实际结果和类似的东西。所以基本上取决于你的需求...

相关问题