-1

I am working on a PHP script that:

  • receives a client request;
  • processes the request via a CPU-and-Time-Intensive-binary-computation
  • store the result of the computation into a MySQL database
  • then respond to the client with a Status 200 OK

Problem: when there are 10s of 1000s of requests coming in per second during peak hours: the clients have to wait for a long time to receive Status 200 OK.

Flexibilities: The script does not need to respond to the client with the result of the computation. The script does not even need to respond Status 200 OK based on the success/failure of the computation - the computation may eventually fail and that's completely okay. So the actual computation could really happen in parallel behind the scene.

What tools / packages / libraries / strategies should be used to achieve this kind of intensive request handling design on PHP? Is it even something on the PHP side or is it solvable from the Apache side?

Notes:

  • Running Apache, MySQL, PHP, Redis on Ubuntu [AMPRU]
  • Clients will just send a request and receive a Status 200 OK right away.
  • Clients will not wait for the computation of the request to complete.
  • There is no auto-scaling or load-balancing concept in place: it's a single AMPRU server.
  • Better if multiple computations can happen in parallel behind the scenes
halfer
  • 19,824
  • 17
  • 99
  • 186
Rakib
  • 12,376
  • 16
  • 77
  • 113
  • possible duplicate of [PHP threading call to a php function asynchronously](http://stackoverflow.com/questions/13846192/php-threading-call-to-a-php-function-asynchronously) – Bulat Aug 07 '15 at 23:17
  • i understand that threads can be started and then have to be joined back in the parent context? Here i am trying to delegate the calculation away from the runtime that receives the request. Is it achievable via threads? – Rakib Aug 07 '15 at 23:23
  • I would think so. If you start your process in a different thread, you will be able to return result (200 OK) straight away without waiting for execution to complete. The only question is whether you need to manage processes in child threads, may be this is a better place to dig - http://stackoverflow.com/questions/124462/asynchronous-php-calls – Bulat Aug 07 '15 at 23:27

1 Answers1

2

This is classic use case for a queue. Of the tech-stack you have listed, Redis has support for queues (check out PHP-Resque for the library), or there are other tools that can be used, such as Beanstalkd (a favourite of mine, with the Pheanstalk PHP library), or Amazon SQS. There are a number of other options, both self-hosted., or available as services.

The website, or other mechanism receives the data, and queue it - returning the 200 OK. The back-end workers, as simple as a cron-based system, or (better) multiple long-running (occasionally restarting to clean-up) scripts, pull items from the queue and performs the work, saving the results.

I've literally run hundreds of millions of jobs like this, through such systems. The workers, if they can reach the queue and database servers, don't even have to run on the same machines (I was running dozens of workers across as many servers).

Alister Bulman
  • 34,482
  • 9
  • 71
  • 110
  • great... my `ab -n 1000 -c 10` was originally taking 200+ seconds. I just implemented `redis-queue` and it brought down the `ab` time to only about 3 seconds. Super excited. Need to work on building the worker now. – Rakib Aug 11 '15 at 09:22
  • 1
    FYI: I used PHP-resque https://github.com/chrisboulton/php-resque/ to implement the redis based queuing system. Great 9 episode step-by-step tutorial series is also available at http://kamisama.me/2012/10/09/background-jobs-with-php-and-resque-part-1-introduction/ – Rakib Aug 13 '15 at 03:13