简体   繁体   中英

How can I provide real-time notifications without tying up resources?

I'm using AJAX to implement long polling on a page which I want to update whenever new rows are inserted into the database. The way this is done is with jQuery's .ajax() calling, for example, poll.php?ky=41 , which queries the database a number of times for rows with an ID of > 41 (with a small wait in between) until a specified timeout. It will fulfil the request immediately if there is a result, or after the given timeout.

In effect, this keeps a hidden connection always open to the server, waiting for it to respond, in order to get notifications.

This works, but I'm using DreamHost and after 8 php53.cgi worker processes are spawned, no requests to my site are fulfilled (ie forever loading) until one times out. This affects every other page on my website. The HTTP Server is Apache 2.2.22-14.

To alleviate the problem, I have reduced the delays and the timeouts so it is closer to regular polling, and added longer delays when there have been no updates for a while. This means notifications may come a few seconds late, but so far my server has been running fine.

What I'm worried about is how well (or rather, how poorly) this will scale.

My question is: given that I'm on a shared host (DreamHost), and this page must be compatible with as many browsers as possible (except mobile), is there a more efficient way to get instant "push" notifications from the server?

Or, what other options do I have? Should I switch back to regular polling?

TL; DR

Polling is fast, but long-polling (waiting before fulfilling the AJAX request) ties up resources. The difference is that long-polling will get the result as soon as it arrives, whereas polling will only pick it up the next time an AJAX request is sent after the new information comes in. Ideally, I would like the advantage of long-polling without tying up threads & causing other users to wait before pages are served.

In this case, the solution is to simply use regular polling (eg an AJAX call every 500 ms) to get quick notifications rather than using long-polling and tying up threads.

From Dave,

Many requests are better handled than long requests. As the threads never really die they just get reused. It will also allow the system to skip a cycle if there's no available threads in the end. Now at some point you'll hit apache+php configuration issues being on shared hosting. After that go with perhaps a small vps and swap to nginx or my personal fave cherokee and use phpfpm then you can build an actual worker thread thats reserved for your poll loop

and

Since the threads are always open there's no overhead for you allowing your poll script to complete and then restart (if the db connection is done right there'll be little additional db load either between pooled conns and prep-statements even better memcached or similar) means you only lock the thread for the duration of the run then immediately release it for other processes to pickup and use it this is how you can support more than 8 users on 8 threads as they're recycled. Don't worry about recalling its always more efficient than longpoll unless you use realtime sockets and daemons

As of now the problem is resolved.

I think in php every open connection means a running thread. You have to make the connected time quite short and to use polling.

The only help would be to organize the polling as fast as possible, so I would try to store a very simple information queue for every session, say in apc_fetch/apc_store (if there is only one apache running for your app). A very simple page has_update.php?session_id just reads that status line and returns 0 or 1, and 0 most of the time, in the smallest format possible. So 5x per second should not be an performance issue too soon.

If and only if has_update.php returns 1 the normal ajax-call should fire.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM