Summary of several common timeout processing in PHP _ PHP Tutorial

Source: Internet
Author: User
Tags apache error log
Summary of several common timeout processing methods in PHP. 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, it will not affect the usage of timeout to timeout in PHP Development. I will discuss 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. in some scenarios where the upload or uncertain processing time is required, you need to set all the timeout values in the entire process to an unlimited value. otherwise, improper configuration of any link will cause 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, 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]

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:

The code is as follows:

ScriptAlias/fcgi-bin/"/home/forum/apache/apache_php/cgi-bin /"

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 ):

The code is as follows:

ScriptAlias/fcgi-bin/"/home/forum/apache/apache_php/cgi-bin /"

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 (0 bytes) receivedfromserver "/home/forum/apache/apache_php/cgi-bin/php-cgi"
Other fastcgi configuration parameters:

The code is as follows:

ProcessLifeTime: the maximum life cycle of a process. it is killed unconditionally after expiration.
MaxProcessCount maximum number of processes
DefaultMinClassProcessCount: minimum number of processes started by each program
DefaultMaxClassProcessCount maximum number of processes started by each program
Response timeout of IPCConnectTimeout program
The maximum time for IPCCommTimeout to communicate with the program. The error above may be caused by a small value.
MaxRequestsPerProcess: each process can complete a maximum of processes and commit suicide.

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 = 5
Server. max-read-idle = 60
Server. read-timeout = 0
Server. max-connection-idle = 360

The code is as follows:

# Maximum number of requests for each keep-alive operation. the default value is 16.
Server. max-keep-alive-requests = 100
# The maximum waiting time of keep-alive, in seconds. the default value is 5.
Server. max-keep-alive-idle = 1200
# Number of work sub-processes in lighttpd. the default value is 0. a single process runs.
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, and the lighttpd will automatically disconnect
# The default value is 60 seconds)
Server. max-read-idle = 1200
# Restrict the maximum intermediate pause time (in seconds) of a user when receiving a response ),
# If the user receives a response (not completed) and the pause takes too long, the lighttpd will automatically disconnect
# The default value is 360 (seconds)
Server. max-write-idle = 12000
# Read client request timeout limit, in seconds. if the value is set to 0, no limit is imposed.
# When the value is smaller than max-read-idle, read-timeout takes effect.
Server. read-timeout = 0
# Timeout limit for writing a response page to the client. the unit is seconds. if the value is set to 0, no limit is imposed.
# Write-timeout takes effect when the value is set to less than max-write-idle
Server. write-timeout = 0
# Maximum request processing time. if mod_proxy_core is used, the interaction time with the backend is limited, in seconds.
Server. max-connection-idle = 1200

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:
Configuration: nginx. conf

The code is as follows:

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

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:// /? P = 466
[PHP timeout processing]
Configuration: php-fpm.conf

The code is as follows:

# Number of php-cgi processes
Thetimeout (inseconds) forservingasinglerequestafterwhichtheworkerprocesswillbeterminated
Shouldbeusedwhen 'max _ execution_time 'inioptiondoesnotstopscriptexecutionforsomereason
'0s' means 'off'
# Php-fpm request execution timeout, 0 s is never timeout, otherwise set an Ns as the timeout seconds
0 s
Thetimeout (inseconds) forservingofsinglerequestafterwhichaphpbacktracewillbedumpedtoslow. logfile
'0s' means 'off'
0 s

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:
0 s
That is to say, running max_execution_time in mode will take effect, but it will not take effect if running in php-fpm mode.
Additional reading:
Configuration: php. ini
Max_execution_time = 30
Or set in the code:
Ini_set ("max_execution_time", 30 );
Set_time_limit (30 );
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_setopt ($ ch, opt) can be used to set timeout settings, including:
* (Important) CURLOPT_TIMEOUT sets 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.
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 );
Curl needs to be added if millisecond timeout is required:
Curl_easy_setopt (curl, CURLOPT_NOSIGNAL, 1L );
Curl_setopt ($ ch, CURLOPT_NOSIGNAL, true); supports millisecond-level timeout settings
Example of curl timeout in milliseconds:

The code is as follows:

If (! Isset ($ _ GET ['foo']) {
// Client
$ Ch = curl_init ('http: // /');
Curl_setopt ($ ch, CURLOPT_RETURNTRANSFER, true );
Curl_setopt ($ ch, CURLOPT_NOSIGNAL, 1); // note that you must set this parameter for millisecond timeout.
Curl_setopt ($ ch, CURLOPT_TIMEOUT_MS, 200); // timeout in milliseconds, added to cURL7.16.2. Available from PHP5.2.3
$ 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 ";
} Else {
Echo "Datareceived: $ datan ";
} Else {
// Server
Sleep (10 );
Echo "Done .";

Other tips:
1. according to the empirical summary, the cURL version> = libcurl/7.21.0 is effective 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:

The code is as follows:

$ TmCurrent = gettimeofday ();
$ IntUSGone = ($ tmCurrent ['SEC ']-$ tmStart ['SEC']) * 1000000
+ ($ TmCurrent ['usec ']-$ tmStart ['usec']);
If ($ intUSGone> $ this-> _ intReadTimeoutUS ){

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

The code is as follows:

// Timeoutinseconds
$ Timeout = 5;
$ Fp = fsockopen ("", 80, $ 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); // you can specify a timeout value.
$ 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! ";
} Else {
Echo $ data;

File_get_contents timeout:

The code is as follows:

$ Timeout = array (
'Http' => array (
'Timeout' => 5 // set a timeout time, in seconds
$ Ctx = stream_context_create ($ timeout );
$ Text = file_get_contents ("", 0, $ ctx );

Fopen timeout:

The code is as follows:

$ Timeout = array (
'Http' => array (
'Timeout' => 5 // set a timeout time, in seconds
$ Ctx = stream_context_create ($ timeout );
If ($ fp = fopen ("", "r", false, $ ctx )){
While ($ c = fread ($ fp, 8192 )){
Echo $ c;
Fclose ($ fp );

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:
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:

The code is as follows:

// Customize read/write timeout constants
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 );
// 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 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 ";
// Execution of the query sleep9 seconds will time out
If (! ($ Res = $ mysqli-> query ('selectsleep (9 )'))){
Echo "query2error:". $ mysqli-> error. "/n ";
} Else {
Echo "Query2: querysuccess/n ";
$ Mysqli-> close ();
Echo "closemysqlconnection/n ";

Additional reading:
[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:

The code is as follows:

// Connection creation timeout (connection to Memcached)
Memcached_st * MemCacheProxy: _ create_handle ()
Memcached_st * mmc = NULL;
If (_ mpool! = NULL) {// getfrompool
Mmc = memcached_pool_pop (_ mpool, false, & 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_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 );
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, & prc );
If (mmc = NULL ){
_ LOG_WARNING _ ("MyMemCacheProxy", "gethandlefrompoolerror [% d]", (int) prc );
// _ LOG_DEBUG _ ("MemCacheProxy", "gethandle [% p]", handle );
// Set a key timeout (set a data to memcached)
BoolMemCacheProxy: _ add (memcached_st * handle, unsignedint * key, constchar * value, intlen, unsignedinttimeout)
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 );

// 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:
[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.
[Timeout implementation in PHP]
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)

The code is as follows:

$ Host = " ";
$ Port = "80 ";
$ Timeout = 15; // timeoutinseconds
$ Socket = socket_create (AF_INET, SOCK_STREAM, SOL_TCP)
Ordie ("Unabletocreatesocketn ");
Socket_set_nonblock ($ socket) // be sure to set it to blocking mode.
Ordie ("Unabletosetnonblockonsocketn ");
$ Time = time ();
// Values are subtracted from each loop.
While (! @ Socket_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) // you need to determine whether the timeout period exists.
Socket_close ($ socket );
Die ("Connectiontimedout. n ");
Sleep (1 );
Die (socket_strerror ($ err). "n ");
Socket_set_block ($ this-> socket) // restores the blocking mode.
Ordie ("Unabletosetblockonsocketn ");

II. Upgrade: PHP built-in asynchronous IO implementation (millisecond-level timeout)
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)

The code is as follows:

Programming call programming #
$ Server = newServer;
$ Client = newClient;
For (;;){
Foreach ($ select-> 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
Classselect {
Var $ sockets;
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, $ hour T = NULL, $ timeout );
Return $ read;
Functioncan_write ($ timeout ){
$ Write = $ this-> sockets;
Socket_select ($ read = NULL, $ write, $ response t = 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:

The code is as follows:

// Signal processing function
Staticvoidconnect_alarm (intsigno)
Debug_printf ("SignalHandler ");
// Alarm timeout connection implementation
Staticvoidconn_alarm ()
Sigfunc * sigfunc; // existing signal processing function
Sigfunc = signal (SIGALRM, connect_alarm); // sets up the signal processing function connect_alarm (if any) to save the existing signal processing function.
Inttimeout = 5;
// Set the alarm
If (alarm (timeout )! = 0 ){
//... The alarm has been set for processing.
// Perform connection operations
If (connect (m_Socket, (structsockaddr *) & addr, sizeof (addr) <0 ){
If (errno = EINTR) {// if the error code is set to EINTR, the timeout is interrupted.
Debug_printf ("Timeout ");

Upload 1. asynchronously obtain data. if a backend data source cannot be obtained successfully, it will be skipped and the whole process will not be affected...

Related Article

E-Commerce Solutions

Leverage the same tools powering the Alibaba Ecosystem

Learn more >

Apsara Conference 2019

The Rise of Data Intelligence, September 25th - 27th, Hangzhou, China

Learn more >

Alibaba Cloud Free Trial

Learn and experience the power of Alibaba Cloud with a free trial worth $300-1200 USD

Learn more >

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.