为什么需要异步请求的事件循环(例如,AJAX 长轮询)
我知道使用普通的线程网络服务器(例如 Apache)进行 AJAX 长轮询被认为是糟糕的设计……但我不太明白为什么。
是否因为每个长轮询请求比正常请求花费更多的时间(从而占用处理器)?如果是这种情况,线程是否真的会占用如此多的开销,以至于它们在使用之前无法保持空闲一段时间?
I understand that it's considered bad design to use a normal, threaded webserver (e.g., Apache) for AJAX long polling…but I don't really understand why.
Is it because each longpolling request takes significantly more time than a normal one would (thus tying up the processor)? And if that's the case, do threads really take that much overhead that they cannot remain idle for awhile before use?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
澄清一下,AJAX 轮询是指客户端 JavaScript 发出未立即得到满足的 AJAX 请求。相反,服务器会等待,直到它想要将回复推送到客户端,然后使用已经打开的 AJAX 上下文来执行此操作。 (对吗?)
在处理每个连接其自己的线程的 Web 服务器上,该打开的连接将导致为网站上的每个客户端创建一个线程。该线程将保持运行,直到客户端关闭连接。当我说“正在运行”时,这只意味着该线程存在并且正在占用服务器资源;它可能在 sleep() 或 wait() 函数中空闲。但它仍然比基于事件的服务器消耗更多的系统资源。
Just to clarify, AJAX polling is when client-side javascript makes an AJAX request that isn't fulfilled immediately. Instead, the server waits until it wants to push a reply to the client and then uses the already-open AJAX context to do so. (right?)
On a web server that handles each connection its own thread, that open connection is going to cause one thread to be created for each client on the web site. The thread will stay running until the client closes the connection. When I say "running", that just means that the thread exists and is taking up server resources; it could be idling in a sleep() or wait() function. But it still consumes far more system resources than would be used in an event-based server.
并不是你占用了处理器,而是你阻塞了一个连接和线程池的一个线程。服务器必须配置一个更大的线程池。
如果您的应用程序试图与 Facebook 竞争,那么您将面临一个重大问题,如果它是中小企业中用于订购午餐的内部应用程序,那么没有人会受到伤害。
It is not that you are tying up the processor, but you are blocking a connection and a thread of the thread pool. The server has then to be configured with a much larger thread pool.
If your application tries to rival facebook you then have a major issue on your hands, if it is an internal application in a SME for ordering lunch, no one will be hurt.
这实际上并不是一个固定的问题,因为它有多种因素会影响答案。
例如,您是否使用 yaws(用 Erlang 编写的网络服务器)?那么这实际上就不是一个问题了,除了你占用了网络服务器上的端口之外,但线程不是问题。
您是否使用Java NewIO API,因此每个连接不需要专用线程,那么这不会成为线程的问题。
但是,如果您不必要地占用资源,无论您在做什么,那就不好了。例如,如果您保持数据库连接打开,进行一些主要处理,然后写回,这也是糟糕的设计。
仅在您需要时保留资源。
如果您要做一些需要大量时间的处理,那么您可能需要考虑更加异步的解决方案。
例如,提供一些唯一的编号,用户可以使用它来检查他们的请求是否已完成,以便他们可以关闭计算机,或者只是在需要时检查它,而不必担心丢失任何内容。
This is not really a cut and dried question since it has various factors that can affect the answer.
For example, are you using yaws (a webserver written in Erlang)? Then it wouldn't really be an issue, except that you are tying up ports on the webserver, but threads are not an issue.
Are you using Java NewIO API, so each connection doesn't take a dedicated thread, then it won't be an issue for threads.
But, if you are tying up resources needlessly, regardless of what you are doing, then that is bad. For example, if you keep a database connection open, do some major processing, then write back, that is also bad design.
Keep resources for only as long as you need them.
If you are going to do some processing that takes a sizeable amount of time then you may want to look at a more asynchronous solution.
For example, give some unique number that the user can use to check if their request is done, so they can shut down their computer, or just check it whenever they want, without worrying about losing anything.