Several common timeout processing in PHP summarize _php skills

Source: Internet
Author: User
Tags apache error log curl fpm memcached mysql client php script time limit
In the PHP development work very much uses in the timeout processing to the timeout situation, I said several scenes:

1. Get data asynchronously if one of the backend data sources is unsuccessful, skip, not affect the entire page presentation
2. To ensure that the Web server will not be able to access other pages because of poor performance on a page, some page actions are set
3. For some upload or uncertain processing time, it is necessary for the whole process of the timeout set to infinity, or any one link set improper, will cause inexplicable execution interruption
4. Multiple back-end modules (MySQL, Memcached, HTTP interface), in order to prevent a single interface performance is too poor, causing the entire front to get data too slow, affecting the page opening speed, causing avalanches
5... Lots of situations that need to be timed out

These places need to consider timeout settings, but the PHP timeout is categorized, the various processing methods and strategies are different, in order to describe the system, I summed up the common PHP in the time-out processing summary.

"Web server timeout Processing"

Typically, in high performance situations, the default timeout configuration is 30 seconds, but when uploading files, or if the network is slow, the timeout operation may be triggered.
There are currently three timeout settings in APACHEFASTCGIPHP-FPM mode:
FastCGI Timeout setting:
Modify the httpd.conf fastcgi connection configuration, similar to the following:

Copy Code code as follows:


The default configuration is 30s, if you need to customize your configuration, you need to modify the configuration, such as 100 seconds: (after the change to restart Apache):

Copy Code code as follows:

fastcgiexternalserver/home/forum/apache/apache_php/cgi-bin/php-cgi-socket/home/forum/php5/etc/ php-fpm.sock-idle-timeout100

If the timeout returns a 500 error, disconnect the back-end PHP service and log 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 parameter description:
Copy Code code as follows:

IdleTimeout Daze time limit
Processlifetime the longest lifecycle of a process and unconditionally kill after expiration
Maxprocesscount Maximum number of processes
Defaultminclassprocesscount the minimum number of processes that each program starts
Defaultmaxclassprocesscount the maximum number of processes that each program starts
Ipcconnecttimeout Program Response Timeout time
Ipccommtimeout the maximum time to communicate with the program, the error may be that this value is set too small
Maxrequestsperprocess each process up to a maximum number of processing, after the completion of suicide

Configuration: lighttpd.conf
In the LIGHTTPD configuration, there are several parameters for timeouts (space considerations, write-only timeout, write-timeout parameters in the same vein):
Mainly involves options:
Copy Code code as follows:

The maximum number of requests #每次keep-alive, the default value is 16
The maximum wait time for the #keep-alive, in seconds, and the default value is 5
#lighttpd的work子进程数, the default value is 0, the single process runs
#限制用户在发送请求的过程中, the maximum intermediate pause time (in seconds),
#如果用户在发送请求的过程中 (no request), the middle pause time is too long, LIGHTTPD will actively disconnect
#默认值是60 (SEC)
#限制用户在接收应答的过程中, the maximum intermediate pause time (in seconds),
#如果用户在接收应答的过程中 (not finished), the middle pause time is too long, LIGHTTPD will actively disconnect
#默认值是 (SEC)
#读客户端请求的超时限制, unit is seconds, with 0 means no limit
When #设置小于max-read-idle, Read-timeout takes effect
#写应答页面给客户端的超时限制, unit is seconds, with 0 means no limit
When #设置小于max-write-idle, Write-timeout takes effect
#请求的处理时间上限, if you use Mod_proxy_core, that's the time limit for interacting with the backend, in seconds.

For a continuous request on a keep-alive connection, the maximum interval for sending the first request content is determined by the parameter max-read-idle, and from the second request the maximum interval for sending the requested content is determined by the parameter max-keep-alive-idle. The interval timeout between requests is also determined by Max-keep-alive-idle. The total time timeout for sending the requested content is determined by the parameter read-timeout. The timeout for lighttpd and back-end interaction data is determined by Max-connection-idle.
Extended reading:
Configuration: nginx.conf
Copy Code code as follows:

#Fastcgi:(Fastcgi for the backend, Fastcgi is not in proxy mode)
fastcgi_send_timeout10; #写超时
fastcgi_read_timeout10; #读取超时
#Proxy:(in effect for proxy/upstreams)
proxy_connect_timeout15s; #连接超时
proxy_read_timeout24s; #读超时
proxy_send_timeout10s; #写超时

The timeout setting for Nginx is very clear and easy to understand, and the above timeout is for different working modes, but the problem with timeouts is very much.
Extended reading:
"PHP itself timeout processing"
Configuration: php-fpm.conf
Copy Code code as follows:

<?xmlversion= "1.0"?>
Number of processes #php-cgi
<valuename= "Max_children" >128</value>
Thetimeout (inseconds) forservingasinglerequestafterwhichtheworkerprocesswillbeterminated
Shouldbeusedwhen ' Max_execution_time ' Inioptiondoesnotstopscriptexecutionforsomereason
' 0s ' means ' off '
#php-FPM request execution timeout, 0s to never time out, otherwise set an Ns to timeout for the number of seconds
<valuename= "Request_terminate_timeout" >0s</value>
Thetimeout (inseconds) forservingofsinglerequestafterwhichaphpbacktracewillbedumpedtoslow.logfile
' 0s ' means ' off '
<valuename= "Request_slowlog_timeout" >0s</value>

In PHP.ini, there is a parameter max_execution_time can set the maximum execution time for a PHP script, but in php-cgi (PHP-FPM), the parameter does not work. Really able to control the maximum execution of PHP scripts:
<valuename= "Request_terminate_timeout" >0s</value>
This means that if you run the Max_execution_time using mode, it will take effect, but it is not effective if the runtime is in PHP-FPM mode.
Extended reading:
Configuration: PHP.ini
or set in code:
Ini_set ("Max_execution_time", 30);
Set_time_limit (30);
Effective for the current session, such as setting 01 straight does not time out, but if the PHP safe_mode is open, these settings will not take effect.
The effect is the same, but the specific content needs to refer to php-fpm part of the content, if the php-fpm set the Request_terminate_timeout, then Max_execution_time will not take effect.
"Back-end & interface Access Timeout"
"HTTP Access"
Generally we visit HTTP way many, mainly is: Curl,socket,file_get_contents () and other methods.
If you encounter the other server has not been responding, we are tragic, it is easy to kill the entire server, so when accessing HTTP also need to consider the problem of timeout.
[CURL Access HTTP]
CURL is one of the most reliable LIB libraries for accessing HTTP protocol interfaces, with high performance and some concurrent support functions.
curl_setopt ($ch, opt) can set some time-out settings, mainly including:
* (important) Curlopt_timeout sets the maximum number of seconds that the curl allows to execute.
* (important) Curlopt_timeout_ms sets the maximum number of milliseconds that the curl allows to execute. (Joined in the cURL7.16.2.) Can be used from PHP5.2.3. )
Curlopt_connecttimeout the time to wait before initiating the connection, and if set to 0, wait indefinitely.
Curlopt_connecttimeout_ms the time, in milliseconds, that the attempt to connect waits. If set to 0, wait indefinitely. Be joined in the cURL7.16.2. Available starting from PHP5.2.3.
Curlopt_dns_cache_timeout sets the time to save DNS information in memory by default of 120 seconds.
Curl Normal Second level timeout:
$ch =curl_init ();
curl_setopt ($ch, Curlopt_url, $url);
curl_setopt ($ch, curlopt_returntransfer,1);
curl_setopt ($ch, curlopt_timeout,60);//Only need to set a number of seconds to
curl_setopt ($ch, Curlopt_httpheader, $headers);
curl_setopt ($ch, curlopt_useragent, $defined _vars[' http_user_agent '));
Curl Normal Second level timeout usage:
curl_setopt ($ch, curlopt_timeout,60);
Curl If you need to do a millisecond timeout, you need to increase:
Curl_easy_setopt (curl,curlopt_nosignal,1l);
Or is:
curl_setopt ($ch, curlopt_nosignal,true), which can support the millisecond-level timeout setting
Curl example of a millisecond timeout:
Copy Code code as follows:

if (!isset ($_get[' foo ')) {
$ch =curl_init ('');
curl_setopt ($ch, curlopt_returntransfer,true);
curl_setopt ($ch, curlopt_nosignal,1);/Note that the millisecond timeout must be set this
curl_setopt ($ch, curlopt_timeout_ms,200),//timeout milliseconds, cURL7.16.2 added. From PHP5.2.3 to use
$data =curl_exec ($ch);
$curl _errno=curl_errno ($ch);
$curl _error=curl_error ($ch);
Curl_close ($ch);
if ($curl _errno>0) {
echo "Curlerror ($curl _errno): $curl _errorn";
echo "datareceived: $datan";
Sleep (10);
echo "Done."

Some other tips:
1. According to the experience is: Curl version >=libcurl/7.21.0 version, the millisecond timeout is certain to take effect, remember.
2. Curl_multi has a problem with the millisecond timeout. Single access is to support MS level timeout, Curl_multi parallel multiple will not be allowed
[Stream processing Access HTTP]
In addition to curl, we often use the fsockopen, or the file operation function to deal with the HTTP protocol, so we are also necessary for this block of timeout processing.
The general connection timeout can be set directly, but the stream read timeout needs to be handled separately.
Write your own code processing:
Copy Code code as follows:

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

or use the built-in stream handler functions Stream_set_timeout () and Stream_get_meta_data () Processing:
Copy Code code as follows:

$timeout = 5;
$FP =fsockopen ("", $errno, $errstr, $timeout);
if ($fp) {
Fwrite ($fp, "get/http/1.0rn");
Fwrite ($fp, "HOST:EXAMPLE.COMRN");
Fwrite ($fp, "connection:closernrn");
Stream_set_blocking ($fp, true);//important, set to non-blocking mode
Stream_set_timeout ($fp, $timeout);//Set timeout
$info =stream_get_meta_data ($FP);
while ((!feof ($FP)) && (! $info [' timed_out ']) {
$data. =fgets ($fp, 4096);
$info =stream_get_meta_data ($FP);
Flush ();
if ($info [' timed_out ']) {
echo "connectiontimedout!";

File_get_contents timeout:
Copy Code code as follows:

$timeout =array (
' HTTP ' =>array (
' Timeout ' =>5//set a timeout in seconds
$ctx =stream_context_create ($timeout);
$text =file_get_contents ("", 0, $ctx);

fopen Timeout:
Copy Code code as follows:

$timeout =array (
' HTTP ' =>array (
' Timeout ' =>5//set a timeout in seconds
$ctx =stream_context_create ($timeout);
if ($fp =fopen ("", "R", False, $ctx)) {
while ($c =fread ($fp, 8192)) {
Fclose ($FP);

The MySQL client in PHP does not have the option to set timeouts, mysqli and MySQL, but Libmysql is a timeout option, but we are hiding it in PHP.
So how to use this operation in PHP pinch, we need to define some of our own MySQL operation constants, mainly related to the constants are:
These two, after the definition, you can set the corresponding value using the options.
However, there is a point of attention, MySQL internal implementation:
1. Timeout set to seconds, minimum configuration 1 seconds
2. But the MySQL bottom of read will retry two times, so the actual will be 3 seconds
Retry two times + self once = 3 times times Timeout, then that means the minimum timeout is 3 seconds, not lower than this value, for most applications, but for a small number of applications need to be optimized.
View a set of PHP instances that access MySQL timeout:
Copy Code code as follows:

Define your own read and write Hyper-constant
if (!defined (' mysql_opt_read_timeout ')) {
Define (' Mysql_opt_read_timeout ', 11);
if (!defined (' mysql_opt_write_timeout ')) {
Define (' Mysql_opt_write_timeout ', 12);
Set timeout
$mysqli =mysqli_init ();
$mysqli->options (mysql_opt_read_timeout,3);
$mysqli->options (mysql_opt_write_timeout,1);
Connecting to a database
$mysqli->real_connect ("localhost", "root", "root", "test");
if (Mysqli_connect_errno ()) {
printf ("connectfailed:%s/n", Mysqli_connect_error ());
Exit ();
Execute query Sleep1 seconds not timed out
printf ("hostinformation:%s/n", $mysqli->host_info);
if (!) ( $res = $mysqli->query (' selectsleep (1) ')) {
echo "Query1error:". $mysqli->error. " /n ";
echo "query1:querysuccess/n";
Execute query sleep9 seconds will timeout
if (!) ( $res = $mysqli->query (' Selectsleep (9) ')) {
echo "Query2error:". $mysqli->error. " /n ";
echo "query2:querysuccess/n";
$mysqli->close ();
echo "closemysqlconnection/n";

Extended reading:
[PHP extensions]
Php_memcache Client:
Connection timeout: Boolmemcache::connect (String$host[,int$port[,int$timeout]])
There is no explicit timeout setting parameter for get and set.
Libmemcached client: There is no obvious timeout parameter in the PHP interface.
Description: So, in PHP access memcached is a lot of problems, you need to hack part of the operation, or refer to the online patch.
[C&c++ access memcached]
Client: libmemcached Client
Description: Memcache Timeout configuration can be configured to small points, such as 5, 10 milliseconds is enough, more than this time to query from the database.
The following is a C + + example of a timeout for connecting and reading set data:
Copy Code code as follows:

Create connection timeout (connect to memcached)
Memcached_st*memcacheproxy::_create_handle ()
if (_mpool!=null) {//getfrompool
Mmc=memcached_pool_pop (_MPOOL,FALSE,&AMP;PRC);
if (mmc==null) {
__log_warning__ ("Memcacheproxy", "gethandlefrompoolerror[%d]", (int) PRC);
Memcached_st*handle=memcached_create (NULL);
if (handle==null) {
__log_warning__ ("Memcacheproxy", "Create_handleerror");
Set connection/Read timeout
Memcached_behavior_set (Handle,memcached_behavior_hash,memcached_hash_default);
Memcached_behavior_set (Handle,memcached_behavior_no_block,_noblock);//Parameter memcached_behavior_no_block is 1 to make the timeout configuration effective. Do not set timeout will not take effect, the critical time will be tragic, easy to cause avalanches
Memcached_behavior_set (handle,memcached_behavior_connect_timeout,_connect_timeout);//Connection Timeout
Memcached_behavior_set (handle,memcached_behavior_rcv_timeout,_read_timeout);//Read timeout
Memcached_behavior_set (handle,memcached_behavior_snd_timeout,_send_timeout);//write timeout
Memcached_behavior_set (handle,memcached_behavior_poll_timeout,_poll_timeout);
Set consistent hash
Memcached_behavior_set_distribution (handle,memcached_distribution_consistent);
Memcached_behavior_set (handle,memcached_behavior_distribution,memcached_distribution_consistent);
for (uinti=0;i<_server_count;i++) {
Rc=memcached_server_add (Handle,_ips[i],_ports[i]);
__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");
Mmc=memcached_pool_pop (_MPOOL,FALSE,&AMP;PRC);
if (mmc==null) {
__log_warning__ ("Mymemcacheproxy", "gethandlefrompoolerror[%d]", (int) PRC);
__log_debug__ ("Memcacheproxy", "gethandle[%p]", handle);
Sets a key timeout (set one data to memcached)
Boolmemcacheproxy::_add (Memcached_st*handle,unsignedint*key,constchar*value,intlen,unsignedinttimeout)
snprintf (tmp,sizeof (TMP), "%u#%u", key[0],key[1]);
There's a timeout value.
Rc=memcached_set (Handle,tmp,strlen (TMP), (char*) value,len,timeout,0);

Memcache Read Data timeout (not set)
Libmemcahed interface definition in 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);
It can be seen from the interface that there is no timeout setting when reading data.
Extended reading:
"How to implement timeouts"
The program needs to have timeout this function, such as you have a separate access to a back-end socket module, the socket module does not belong to any of us described above, its protocol is also private, then this time may need to implement some of their own time-out processing strategy, this time need some processing code.
[Timeout implementation in PHP]
First, primary: The simplest timeout implementation (second-level timeout)
The idea is simple: link to a backend, then set to Non-blocking mode, and if there is no connection on the loop, to determine the difference between the current time and timeout time.
Phpsocket in the original timeout: (each cycle is the current time to reduce performance will be very poor, CPU occupancy will be higher)
Copy Code code as follows:

$host = "";
$port = "80";
$timeout =15;//timeoutinseconds
$socket =socket_create (AF_INET,SOCK_STREAM,SOL_TCP)
Ordie ("Unabletocreatesocketn");
Socket_set_nonblock ($socket)//must be set to blocking mode
Ordie ("Unabletosetnonblockonsocketn");
$time =time ();
Every time you subtract the corresponding value from the loop
while (! @socket_connect ($socket, $host, $port))//If there is no connection, the loop is dead.
$err =socket_last_error ($socket);
if ($err ==115| | $err ==114)
if ((Time ()-$time) >= $timeout)//Every time you need to determine whether the timeout
Socket_close ($socket);
Sleep (1);
Die (Socket_strerror ($err). " n ");
Socket_set_block ($this->socket)//restore blocking mode
Ordie ("Unabletosetblockonsocketn");

Second, upgrade: Using PHP with asynchronous IO to implement (millisecond timeout)
Asynchronous IO: The concept of asynchronous IO is relative to synchronous IO. When an asynchronous procedure call is issued, the caller cannot immediately obtain the result. When the part that actually handles this call is completed, the caller is notified by status, notification, and callback. Asynchronous IO transmits bits into a group, which can be 8-bit 1 characters or longer. The sender can send these bit groups at any time, and the receiver never knows when they will arrive.
Multiplexing: A reuse model is a method of detecting multiple IO operations, returning an operational set so that it can be manipulated. This avoids blocking IO not being able to handle the determination of the various IO and non-blocking usage resources at any time.
Use Socket_select () to implement timeout
Socket_select (Floor ($timeout), ceil ($timeout *1000000));
Select features: Can be set to the microsecond level other timeout!
Use Socket_select () timeout code (need to know some asynchronous IO programming knowledge to understand)
Copy Code code as follows:

Programming Call Class Programming #
$server =newserver;
$client =newclient;
for (;;) {
foreach ($select->can_read (0) as$socket) {
if ($socket = = $client->socket) {
$select->add (socket_accept ($client->socket));
There ' Ssomethingtoreadon$socket
Programming Asynchronous Multiplexing IO & Timeout Connection processing class programming
Functionselect ($sockets) {
$this->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);
Functioncan_write ($timeout) {
$write = $this->sockets;
Socket_select ($read =null, $write, $except =null, $timeout);

[Timeout implementation in c&c++]
Generally in linuxc/c++, you can use: Alarm () to set the timer to implement the second level timeout, or: Select (), poll (), Epoll () asynchronous multiplexing IO Implementation of the millisecond timeout. It can also be implemented using an asynchronous IO Library (Libevent,libev) with two encapsulation.
The use of Alarm signal implementation timeout (second level timeout)
Description: Linux kernel Connect timeout is usually 75 seconds, we can set a smaller time, such as 10 seconds in advance from connect to return. This uses a signal processing mechanism to invoke alarm, which generates a SIGALRM signal after a timeout (also available with Select)
Use the Alarym second level to implement connect to set timeout code example:
Copy Code code as follows:

//Signal processing function
Staticvoidconnect_alarm (Intsigno)
debug_printf ("Si Gnalhandler ");
//alarm Timeout connection Implementation
Staticvoidconn_alarm ()
sigfunc*sigfunc;//existing signal processing functions
Sigfunc=signal (S Igalrm,connect_alarm)//Establish signal processing function connect_alarm, (if any) to save the existing signal processing function
//Set alarm
if (alarm (timeout)!=0) {
//... The alarm clock has been set to handle
//Connect Operation
if (Connect (M_socket, (structsockaddr*) &addr,sizeof (addr)) <0) {
if (errno ==EINTR) {///If the error number is set to Eintr, the
debug_printf ("Timeout") is interrupted by a 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: 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.