简体   繁体   中英

Restart PHP FCGI process automatically once it dies on Windows when using with nginx

I am using PHP FCGI to execute PHP scripts (These are Restful Web Services written in PHP which handles web requests from web pages) with Nginx on Windows. Everything works fine until the request counts reaches "php_fcgi_max_requests". I am setting this to 1000 as every tutorial for Nginx + PHP FCGI out there suggests this value for PHP stability. But I want to know if there is a way if the PHP FCGI can be recycled while using with Nginx on Windows OS. In other words, once the 1000 requests are handled and PHP FCGI dies, then PHP FCGI restarts itself and start handling requests again. I require this nginx+ PHP FCGI always running on Windows until and unless it is explicitly closed by the user.

I have researched a lot online but could not find a solution for this for Nginx on Windows. Any other operating system is, unfortunately, not an option. I need a solution for Windows only and I need a light server which does not take up much memory and is quick to install.

If you think my goal cannot be achieved with Nginx + PHP FCGI, I am open to suggestions if the PHP FCGI can be used with any other light server (like Nginx) on Windows where it can handle as many requests as possible (no limit to requests or at least recycle itself when the process dies off on reaching max requests).

It would be very helpful if somebody can provide me any guidance.

FYI, I start the Nginx server and PHP FCGI like below:

set PATH=<customized path>;%PATH% 
set PHP_FCGI_MAX_REQUESTS=1000
RunHiddenConsole.exe %CD%\nginx\PHP\php-cgi.exe -b 127.0.0.1:9000 
RunHiddenConsole.exe nginx.exe

here, RunHiddenConsole.exe is from here: https://www.nginx.com/resources/wiki/start/topics/examples/phpfastcgionwindows/

Please let me know if anybody need any more technical details.

Thanks a lot in advance.

Not sure if you are still stuck with this issue. The work around I used was to design a windows service that monitors the number of requests Nginx has handled. I used multiple instances of PHP-CGI (Fast CGI) in order to load-balance the server.

I cannot share the full code as I did this for work, but I can provide the steps to design your own implementation.

Some background information on why I implemented this the way I did:

  • Nginx is not able to restart php-cgi.exe (on Windows at least)
  • The default value for PHP_FCGI_MAX_REQUESTS is 500 . By default php-cgi.exe will terminate after handling 500 web requests.
  • Our web server is on an embedded system, it will not be seeing high traffic.

Step 1
Configure Nginx to allow for active monitoring. This will allow you to track the number of requests your server has been getting.

Even if PHP-CGI has crashed, it is still possible to get the request information from Nginx.

Add the following location information into your server{} block in nginx.conf

    location /nginx_status {
        stub_status on;
        access_log   off;
        allow 127.0.0.1;
        deny all;
    } 

Now, from your server, if you visit localhost/nginx_status you will be able to see the number of handled (the 3rd number in the 3rd line is the number of requests). Nginx Doc on stub_status

Step 2
Access the Nginx status from your service (mine is written in C# .NET 4.0)
My service checks and updates the requests value throughout it's lifetime. You can get the string from the web page using the following code:

//
// Get the Nginx Status String containing the number of requests to the site.
//
private string ReadSiteStatus()
{
    string nginxStatus = ERROR_NO_NGINX;
    using (WebClient client = new WebClient())
    {
        try
        {
            nginxStatus = client.DownloadString("http://127.0.0.1/nginx_status");
        } catch (Exception ex)
        {
            WriteToFile(ex.Message);
        }
    }   
    return nginxStatus;
}

From here you can set up a function to parse the request number from this string.

Step 3
Setup Nginx to load balance multiple PHP-CGI instances. For our implementation, we used three instances. In the http{} block of nginx.conf , add the following block.

#Reference the three Fast CGI servers
upstream myproject{
    server 127.0.0.1:9000 weight=1 fail_timeout=5;
    server 127.0.0.1:9001 weight=1 fail_timeout=5;
    server 127.0.0.1:9002 weight=1 fail_timeout=5;
}

In your server{} block, locate the location ~\\.php${} block. Update the fastcgi_pass to reference the upstream block defined in http .

# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000, 9001, and 9002
location ~ \.php$ {
    fastcgi_pass   myproject;
    fastcgi_index  index.php;
    fastcgi_param  SCRIPT_FILENAME  $document_root/$fastcgi_script_name;
    include        fastcgi_params;
}

Step 4
Start the three instances of PHP-CGI. One listening on each of the ports: 9000, 9001, and 9002.

I wanted to do this from within my service but had issues with calling the PHP-CGI executable directly. I wrote a batch file that starts PHP-CGI. It takes a port number as a parameter. The file was named start-php.bat

@ECHO OFF
SET PHP_FCGI_MAX_REQUESTS=2000
C:\Nginx\RunHiddenConsole.exe C:\NGinx\PHP\php-cgi -b 127.0.0.1:%1 -c 
C:\NGinx\PHP\php.ini
EXIT

Example usage:

> start-php.bat 9000

Would start an instance listening on port 9000.

RunHiddenConsole.exe is required to run PHP-CGI in the background, it is referred to on NGinx's site here .

Step 5
Build the service.

Here is the part that is up to your implementation. I can provide you with the general workflow / algorithm.

  1. On Start, stop all instances of PHP-CGI
  2. Start the instances of PHP-CGI required by your Nginx config file (call into batch script provided)
  3. Create a queue of the PHP-CGI processes, keep track of which one is on which port.
  4. Create a loop to check the status every x-seconds.
  5. If you have reached a certain number of requests, stop the next process in the queue. Get the port of that process (track it in your service). Start a new instance of PHP-CGI on that port, add it back to the queue.

Hope this helps.

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