PHP timeout handling summary

Source: Internet
Author: User
Tags apache error log
PHP timeout handling summary

In PHP development, I often use timeout processing to timeout. I will talk about several scenarios:

  1. Asynchronous data acquisition if a backend data source cannot be obtained successfully, the whole page is not affected.
  2. In order to ensure that the Web server will not be unable to access other pages due to poor page processing performance, some page operations will be set
  3. For some uploads or uncertain processing times, you need to set an unlimited number of timeout values for the entire process. otherwise, improper configuration of any part will lead to inexplicable execution interruption.
  4. Multiple backend modules (MySQL, Memcached, and HTTP interfaces), in order to prevent poor performance of a single interface, resulting in too slow data acquisition in the front, affecting the page opening speed and causing an avalanche
  5. ... Many scenarios that require timeout

Timeout settings need to be considered in all of these places, but timeout in PHP is classified and different processing methods and policies are different. for the system description, I have summarized the commonly used timeout processing in PHP.

Web server timeout processing Apache

Generally, when the performance is high, all timeout configurations are 30 seconds by default. However, when the file is uploaded or the network speed is very slow, the timeout operation may be triggered.

Currently, apachefastcgiphp-fpm mode has three timeout settings:

Fastcgi timeout settings:

Modify the fastcgi connection configuration of httpd. conf as follows:

 
  FastCgiExternalServer/home/forum/apache/apache_php/cgi-bin/php-cgi-socket/home/forum/php5/etc/php-fpm.sockScriptAlias/fcgi-bin/”/home/forum/apache/apache_php/cgi-bin/”AddHandlerphp-fastcgi.phpActionphp-fastcgi/fcgi-bin/php-cgiAddTypeapplication/x-httpd-php.php
 

The default configuration is 30 s. If you need to customize your own configuration, you need to modify the configuration, for example, to 100 s: (restart apache after modification ):

 
  FastCgiExternalServer/home/forum/apache/apache_php/cgi-bin/php-cgi-socket/home/forum/php5/etc/php-fpm.sock-idle-timeout100ScriptAlias/fcgi-bin/”/home/forum/apache/apache_php/cgi-bin/”AddHandlerphp-fastcgi.phpActionphp-fastcgi/fcgi-bin/php-cgiAddTypeapplication/x-httpd-php.php
 

If the timeout occurs, a 500 error is returned. disconnect from the backend php service and record an apache error log:

[ThuJan2718:30:152011][error][client10.81.41.110]FastCGI:commwithserver”/home/forum/apache/apache_php/cgi-bin/php-cgi”aborted:idletimeout(30sec)[ThuJan2718:30:152011][error][client10.81.41.110]FastCGI:incompleteheaders(0bytes)receivedfromserver”/home/forum/apache/apache_php/cgi-bin/php-cgi”

Other fastcgi configuration parameters:

IdleTimeout specifies the shortest time of a process, ProcessLifeTime, after expiration, the maximum number of processes of unconditional killMaxProcessCount DefaultMinClassProcessCount is the minimum number of processes started by each program. defamaxmaxclassprocesscount the maximum number of processes started by each program, the preceding error may be caused by a too small value. in MaxRequestsPerProcess, each process can complete a maximum of processing tasks, and then commit suicide.

Lighttpd

Configuration: lighttpd. conf

In Lighttpd configuration, there are several timeout parameters as follows (write-only timeout is considered in length, and the write timeout parameter is the same ):

Main options:

Server. max-keep-alive-idle = 5server. max-read-idle = 60server. read-timeout = 0server. max-connection-idle = 360 ----------------- # maximum number of requests for each keep-alive operation. the default value is 16server. max-keep-alive-requests = 100 # maximum waiting time of keep-alive, in seconds. the default value is 5server. max-keep-alive-idle = 1200 # Number of work sub-processes in lighttpd. the default value is 0. a single process runs the server. max-worker = 2 # restrict the maximum intermediate pause time (in seconds) during request sending ), # If the user does not end the request when sending the request, the pause is too long. lighttpd will automatically disconnect the connection # The default value is 60 (seconds) server. max-read-idle = 1200 # restrict the maximum intermediate pause time (in seconds) of a user in receiving a response ), # If the user is waiting for a long pause in the process of receiving a response (not completed), lighttpd will disconnect automatically # The default value is 360 (seconds) server. max-write-idle = 12000 # timeout limit for read client requests. the unit is seconds. if the value is set to 0, no limit is applied. # when the value is smaller than max-read-idle, read-timeout takes effect on the server. read-timeout = 0 # timeout limit for the write response page to the client. the unit is seconds. if the value is set to 0, no limit is applied. # when the value is smaller than max-write-idle, write-timeout takes effect on the server. write-timeout = 0 # maximum request processing time. if mod_proxy_core is used, it is the interaction time limit with the backend. the unit is second server. max-connection-idle = 1200 -----------------

Note:

For a continuous request on a keep-alive connection, the maximum interval between sending the first request content is determined by the max-read-idle parameter, starting from the second request, the maximum interval between sending request content is determined by the max-keep-alive-idle parameter. The interval timeout between requests is also determined by max-keep-alive-idle. The total time for sending request content timeout is determined by the read-timeout parameter. The timeout between Lighttpd and backend interaction data is determined by max-connection-idle.

Additional reading:

Http://www.snooda.com/read/244

Nginx

Configuration: nginx. conf

Http {# Fastcgi: (for backend fastcgi, fastcgi does not belong to the proxy mode) fastcgi_connect_timeout5; # connection timeout fastcgi_send_timeout10; # write timeout fastcgi_read_timeout10; # read timeout # Proxy: (effective for proxy/upstreams) proxy_connect_timeout15s; # connection timeout proxy_read_timeout24s; # read timeout proxy_send_timeout10s; # write timeout}

Note:

Nginx timeout settings are clear and easy to understand. the above timeout settings are applicable to different working modes, but there are many problems caused by timeout.

Additional reading:

Http://hi.baidu.com/pibuchou/blog/item/a1e330dd71fb8a5995ee3753.html http://hi.baidu.com/pibuchou/blog/item/7cbccff0a3b77dc60b46e024.html http://hi.baidu.com/pibuchou/blog/item/10a549818f7e4c9df703a626.html http://www.apoyl.com /? P = 466

PHP timeout processing PHP-fpm

Configuration: php-fpm.conf

 
 
  
//... Setsthelimitonthenumberofsimultaneousrequeststhatwillbeserved. EquivalenttoApacheMaxClientsdirective. maximum. # Number of php-cgi processes
  
   
128Thetimeout (inseconds) comment 'max _ execution_time 'inioptiondoesnotstopscriptexecutionforsomereason '0s' means 'off' # php-fpm request execution timeout time, 0 s is never timeout, otherwise set an Ns to the timeout time in seconds
   
    
0 sThetimeout (inseconds) forservingofsinglerequestafterwhichaphpbacktracewillbedumpedtoslow. logfile '0s' means 'off'
    
     
0 s
    
   
  
 

Note:

In php. ini, max_execution_time can be used to set the maximum execution time of PHP scripts. However, this parameter does not take effect in php-cgi (php-fpm. The maximum execution time of PHP scripts can be controlled:

 
  0s
 

That is to say, running max_execution_time in mod_php5.so mode will take effect, but it will not take effect if running in php-fpm mode.

Additional reading:

Http://blog.s135.com/file_get_contents/

PHP

Configuration: php. ini

Option:

max_execution_time=30

Or set in the code:

ini_set(“max_execution_time”,30);set_time_limit(30);

Note:

The setting takes effect for the current session. for example, if the setting 0 never times out, but if the php safe_mode is enabled, these settings will not take effect.

The results are the same, but you need to refer to the php-fpm content. if request_terminate_timeout is set in php-fpm, max_execution_time will not take effect.

Backend & interface access timeout HTTP access

Generally, there are many HTTP access methods, such as curl, socket, and file_get_contents.

If the other server never responds, we will suffer. it is easy to get rid of the entire server. Therefore, timeout needs to be considered when accessing http.

CURL access HTTP

CURL is a commonly used lib library for accessing HTTP protocol interfaces with high performance and some features supported by concurrency.

CURL:

Curl_setopt ($ ch, opt) can be used to set some timeout settings, including: * (important) CURLOPT_TIMEOUT to set the maximum number of seconds that cURL can be executed. * (Important) CURLOPT_TIMEOUT_MS sets the maximum number of milliseconds that cURL can be executed. (Added in cURL7.16.2. It can be used from PHP5.2.3 .) CURLOPT_CONNECTTIMEOUT is the waiting time before the connection is initiated. if it is set to 0, it will wait infinitely. CURLOPT_CONNECTTIMEOUT_MS indicates the waiting time for the connection attempt, in milliseconds. If it is set to 0, the system waits for no limit. Added to cURL7.16.2. Available from PHP5.2.3. CURLOPT_DNS_CACHE_TIMEOUT sets the time for saving DNS information in the memory. the default value is 120 seconds.

Curl common second-level timeout:

$ Ch = curl_init (); curl_setopt ($ ch, CURLOPT_URL, $ url); curl_setopt ($ ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt ($ ch, CURLOPT_TIMEOUT, 60 ); // you only need to set the number of seconds to curl_setopt ($ ch, CURLOPT_HTTPHEADER, $ headers); curl_setopt ($ ch, CURLOPT_USERAGENT, $ defined_vars ['http _ USER_AGENT ']);

Curl common timeout in seconds:

Curl_setopt ($ ch, CURLOPT_TIMEOUT, 60); add curl_easy_setopt (curl, CURLOPT_NOSIGNAL, 1L) if millisecond timeout is required for curl );

Or:

Curl_setopt ($ ch, CURLOPT_NOSIGNAL, true); supports millisecond-level timeout settings

Example of curl timeout in milliseconds:

 0) {echo "cURLError ($ curl_errno): $ curl_errorn";} else {echo "Datareceived: $ datan";} else {// Serversleep (10 ); echo "Done. ";}?>

Other tips:

  1. According to the experience, the cURL version> = libcurl/7.21.0 takes effect in milliseconds.
  2. There is also a problem with curl_multi's millisecond-level timeout .. Single Access supports ms-level timeout, and multiple concurrent calls of curl_multi are not allowed.
Access HTTP through stream processing

In addition to curl, we often use fsockopen, or file operation functions for HTTP protocol processing. Therefore, timeout processing for this block is also required.

Generally, connection timeout can be set directly, but stream read timeout needs to be handled separately.

Write your own code for processing:

$tmCurrent=gettimeofday();$intUSGone=($tmCurrent['sec']-$tmStart['sec'])*1000000+($tmCurrent['usec']-$tmStart['usec']);if($intUSGone>$this->_intReadTimeoutUS){returnfalse;}

You can also use the built-in stream processing functions stream_set_timeout () and stream_get_meta_data () for processing:

     

File_get_contents timeout:

  Array ('timeout' => 5 // set a timeout time in seconds); $ ctx = stream_context_create ($ timeout); $ text = file_get_contents ("http://example.com /", 0, $ ctx);?>

Fopen timeout:

  Array ('timeout' => 5 // set a timeout time in seconds); $ ctx = stream_context_create ($ timeout ); if ($ fp = fopen ("http://example.com/", "r", false, $ ctx) {while ($ c = fread ($ fp, 8192 )) {echo $ c;} fclose ($ fp) ;}?>

MySQL

Mysql clients in php do not have the timeout option, and neither mysql nor mysqli, but libmysql provides the timeout option, which is hidden in php.

To use this operation in PHP, we need to define some MySQL operation constants. The major constants involved include:

MYSQL_OPT_READ_TIMEOUT=11;MYSQL_OPT_WRITE_TIMEOUT=12;

After the two parameters are defined, you can use options to set the corresponding values.

Note that the internal implementation of mysql is as follows:

  1. The unit of timeout setting is seconds. the minimum value is 1 second.
  2. However, the underlying read of mysql will be retried twice, so it will actually be 3 seconds

Two retries + each time = three times the timeout time, that is, the minimum timeout time is 3 seconds, which is not lower than this value. this is acceptable for most applications, but needs to be optimized for a small number of applications.

View a php instance set to access mysql timeout:

  Options (MYSQL_OPT_READ_TIMEOUT, 3); $ mysqli-> options (MYSQL_OPT_WRITE_TIMEOUT, 1); // connect to the database $ mysqli-> real_connect ("localhost", "root", "root ", "test"); if (mysqli_connect_errno () {printf ("Connectfailed: % s/n", mysqli_connect_error (); exit ();} // execute the query for sleep1 seconds without timeout printf ("Hostinformation: % s/n", $ mysqli-> host_info); if (! ($ Res = $ mysqli-> query ('selectsleep (1) ') {echo "query1error :". $ mysqli-> error. "/n";} else {echo "Query1: querysuccess/n";} // if (! ($ Res = $ mysqli-> query ('selectsleep (9) ') {echo "query2error :". $ mysqli-> error. "/n";} else {echo "Query2: querysuccess/n";} $ mysqli-> close (); echo "closemysqlconnection/n";?>

Additional reading:

Http://blog.csdn.net/heiyeshuwu/article/details/5869813

Memcached PHP extension

Php_memcache client:

Connection timeout: boolMemcache: connect (string $ host [, int $ port [, int $ timeout])

There is no explicit timeout setting parameter in get and set.

Libmemcached client: there is no obvious timeout parameter in the php interface.

Note: There are many problems with accessing Memcached in PHP. you need to perform some hack operations or refer to online patches.

C & C ++ access Memcached

Client: libmemcached client

Note: The memcache timeout configuration can be set to a smaller value. for example, it may take 5 to 10 milliseconds to query from the database.

The following is a time-out C ++ example for connecting to and reading set data:

// Connection creation timeout (connected to Memcached) memcached_st * MemCacheProxy: _ create_handle () {memcached_st * mmc = NULL; memcached_return_tprc; if (_ mpool! = NULL) {// getfrompoolmmc = memcached_pool_pop (_ mpool, false, & prc); if (mmc = NULL) {__ LOG_WARNING _ ("MemCacheProxy ", "gethandlefrompoolerror [% d]", (int) prc);} returnmmc;} memcached_st * handle = memcached_create (NULL); if (handle = NULL) {__ LOG_WARNING _ ("MemCacheProxy", "create_handleerror"); returnNULL;} // sets the connection/read timeout period (handle, MEMCACHED_BEHAVIOR_HASH, MEMCACHED_HASH_DEFAULT); round (hand Le, handle, _ noblock); // The parameter MEMCACHED_BEHAVIOR_NO_BLOCK is set to 1 to make the timeout configuration take effect. if the parameter is not set, the timeout configuration will not take effect. the critical time will be tragic and will easily cause an avalanche memcached_behavi, timeout, _ connect_timeout); // connection timeout memcached_behavior_set (handle, timeout, _ read_timeout); // read timeout memcached_behavior_set (handle, timeout, _ send_timeout ); // write timeout memcached_behavior_set (handle, MEMCACHED_BE HAVIOR_POLL_TIMEOUT, _ poll_timeout); // Set consistent hash // round (handle, handle); memcached_behavior_set (handle, handle, handle); memcached_returnrc; for (uinti = 0; I <_ server_count; I ++) {rc = memcached_server_add (handle, _ ips [I], _ ports [I]); if (MEMCACHED_SUCCESS! = Rc) {__ LOG_WARNING _ ("MemCacheProxy", "addserver [% s: % d] failed. ", _ ips [I], _ ports [I]) ;}}_ mpool = memcached_pool_create (handle, _ min_connect, _ max_connect); if (_ mpool = NULL) {__ LOG_WARNING _ ("MemCacheProxy", "create_poolerror"); returnNULL;} mmc = memcached_pool_pop (_ mpool, false, & prc); if (mmc = NULL) {__ LOG_WARNING _ ("MyMemCacheProxy", "gethandlefrompoolerror [% d]", (int) prc);} // _ LOG_DEBUG _ ("MemCacheProxy", "gethandle [% P] ", handle); returnmmc;} // set a key timeout (set a data to memcached) boolMemCacheProxy: _ add (memcached_st * handle, unsignedint * key, constchar * value, intlen, unsignedinttimeout) {memcached_returnrc; chartmp [1024]; snprintf (tmp, sizeof (tmp), "% u # % u", key [0], key [1]); // There is a timeout value rc = memcached_set (handle, tmp, strlen (tmp), (char *) value, len, timeout, 0 ); if (MEMCACHED_SUCCESS! = Rc) {returnfalse;} returntrue;} // Memcache data read timeout (not set)

Interface definition in libmemcahed source code:

LIBMEMCACHED_APIchar*memcached_get(memcached_st*ptr,constchar*key,size_tkey_length,size_t*value_length,uint32_t*flags,memcached_return_t*error);LIBMEMCACHED_APImemcached_return_tmemcached_mget(memcached_st*ptr,constchar*const*keys,constsize_t*key_length,size_tnumber_of_keys);

The interface shows that there is no timeout setting when reading data.

Additional reading:

Http://hi.baidu.com/chinauser/item/b30af90b23335dde73e67608 http://libmemcached.org/libMemcached.html

How to implement timeout

The program requires timeout. for example, when you access a backend Socket Module separately and the Socket module does not belong to any of the above descriptions, its protocol is also private, in this case, you may need to implement some timeout policies on your own. in this case, you need some processing code.

PHP timeout implementation

I. beginner: the simplest timeout implementation (seconds)

The idea is simple: link a backend and set it to non-blocking mode. if there is no connection, it will keep repeating and judge the difference between the current time and the timeout time.

Original timeout in phpsocket: (the current time of each loop is reduced, performance will be poor, and cpu usage will be high)

  _ Connect ($ socket, $ host, $ port) // endless loop if no connection is established {$ err = socket_last_error ($ socket ); if ($ err = 115 | $ err = 114) {if (time ()-$ time) >=$ timeout) // Determine whether the timeout is {socket_close ($ socket); die ("Connectiontimedout. n ");} sleep (1); continue;} die (socket_strerror ($ err ). "n");} socket_set_block ($ this-> socket) // restore the blocking mode ordie ("Unabletosetblockonsocketn");?>

II. Upgrade: PHP built-in asynchronous IO implementation (millisecond-level timeout)

Note:

Asynchronous IO: the concept of asynchronous IO is opposite to that of synchronous IO. When an asynchronous process is called, the caller cannot obtain the result immediately. After the call is completed, the caller is notified by status, notification, and callback. Asynchronous IO divides bits into groups for transmission. The group can be 8 characters long or 1 character long. The sender can send these bit groups at any time, and the receiver never knows when they will arrive.

Multiplexing: the multiplexing model detects multiple IO operations and returns operable sets. This allows you to operate on them. This prevents blocking IO from being able to process various IO and non-blocking system resources at any time.

Use socket_select () for timeout

socket_select(…,floor($timeout),ceil($timeout*1000000));

Select features: timeout can be set to microseconds!

Use the time-out code of socket_select () (understand some asynchronous IO programming knowledge)

Programming call programming

   can_read(0)as$socket){if($socket==$client->socket){//NewClientSocket$select->add(socket_accept($client->socket));}else{//there’ssomethingtoreadon$socket}}}?>

Programming asynchronous multiplexing IO & timeout connection Processing Programming

   sockets=array();foreach($socketsas$socket){$this->add($socket);}}functionadd($add_socket){array_push($this->sockets,$add_socket);}functionremove($remove_socket){$sockets=array();foreach($this->socketsas$socket){if($remove_socket!=$socket)$sockets[]=$socket;}$this->sockets=$sockets;}functioncan_read($timeout){$read=$this->sockets;socket_select($read,$write=NULL,$except=NULL,$timeout);return$read;}functioncan_write($timeout){$write=$this->sockets;socket_select($read=NULL,$write,$except=NULL,$timeout);return$write;}}?>

Timeout implementation in C & C ++

Generally, in LinuxC/C ++, you can use: alarm () to set the timer to implement second-level timeout, or: select (), poll (), epoll () asynchronous IO multiplexing for millisecond-level timeout. You can also use a secondary encapsulated asynchronous io Library (libevent, libev.

I. timeout using signals in alarm (seconds)

Note: Linux kernel connect usually times out in 75 seconds. we can set a shorter time, for example, 10 seconds, to return data from connect in advance. Here the signal processing mechanism is used to call alarm and generate the SIGALRM signal after the timeout (which can also be implemented using select)

Example code for timeout setting of connect using alarym in seconds:

// Signal processing function staticvoidconnect_alarm (intsigno) {debug_printf ("SignalHandler"); return ;}// implement staticvoidconn_alarm () {Sigfunc * sigfunc; // existing signal processing function sigfunc = signal (SIGALRM, connect_alarm); // establish the signal processing function connect_alarm, (if any) save the existing signal processing function inttimeout = 5; // Set the alarm if (alarm (timeout )! = 0 ){//... The alarm has been set for processing} // connection operation if (connect (m_Socket, (structsockaddr *) & addr, sizeof (addr) <0) {if (errno = EINTR) {// if the error code is set to EINTR, debug_printf ("Timeout") is interrupted during the Timeout ");

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.