In php.ini, there is a parameter max_execution_time that can set the maximum execution time of PHP scripts. However, in php-cgi (php-fpm), this parameter will not take effect. When you can really control the maximum execution of PHP scripts:
0s
That is to say, if you use mod_php5.so mode to run max_execution_time, it will take effect, but if it is php It does not take effect when running in -fpm mode.
Extended reading:
http://blog.s135.com/file_get_contents/
[ PHP ]
Configuration: php.ini
Options:
max_execution_time=30
Or Set in the code:
ini_set("max_execution_time",30);
set_time_limit(30);
Note:
takes effect for the current session. For example, setting 0 will never time out, but if php's safe_mode If turned on, these settings will not take effect.
The effect is the same, but the specific content needs to refer to the php-fpm part. If request_terminate_timeout is set in php-fpm, then max_execution_time will not take effect.
[Backend & interface access timeout]
[HTTP access]
Generally, we access HTTP in many ways, mainly: curl, socket, file_get_contents() and other methods.
If the other party's server never responds, we will be in tragedy. It is easy to kill the entire server, so we also need to consider the timeout issue when accessing http.
[CURL access HTTP]
CURL is a commonly used and reliable lib library for accessing the HTTP protocol interface. It has high performance and some concurrency support functions.
CURL:
curl_setopt($ch,opt) can set some timeout settings, mainly including:
*(Important) CURLOPT_TIMEOUT sets the maximum number of seconds that cURL is allowed to execute.
*(Important) CURLOPT_TIMEOUT_MS sets the maximum number of milliseconds cURL is allowed to execute. (Added in cURL7.16.2. Available from PHP5.2.3.)
The time CURLOPT_CONNECTTIMEOUT waits before initiating a connection. If set to 0, it will wait indefinitely.
CURLOPT_CONNECTTIMEOUT_MS The time to wait for a connection attempt, in milliseconds. If set to 0, wait infinitely. Added in cURL7.16.2. Available starting from PHP5.2.3.
CURLOPT_DNS_CACHE_TIMEOUT sets the time to save DNS information in memory, the default is 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);//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' ]);
Use curl's normal second-level timeout:
curl_setopt($ch,CURLOPT_TIMEOUT,60);
If curl requires millisecond timeout, you need to add:
curl_easy_setopt(curl,CURLOPT_NOSIGNAL,1L) ;
Or:
curl_setopt($ch,CURLOPT_NOSIGNAL,true); can support millisecond-level timeout settings
Example of a millisecond-level timeout for curl:
Copy code The code is as follows:
if(!isset($_GET['foo'])){
//Client
$ch=curl_init('http://example.com/');
curl_setopt($ch,CURLOPT_RETURNTRANSFER,true);
curl_setopt($ch,CURLOPT_NOSIGNAL,1);//Note, milliseconds The timeout must be set
curl_setopt($ch,CURLOPT_TIMEOUT_MS,200); //Timeout in milliseconds, added in cURL7.16.2. Available from PHP5.2.3 onwards
$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.";
}
?>
Some other tips:
1. According to the experience summary: cURL version >= libcurl/7.21.0 version, millisecond timeout will definitely take effect, remember.
2. There is also a problem with the millisecond timeout of curl_multi. . A single access supports ms-level timeout, but curl_multi will be inaccurate if multiple calls are made in parallel
[Access HTTP via stream processing]
In addition to curl, we often use fsockopen or file operation functions to perform HTTP protocols. Therefore, our timeout processing of this piece is also necessary.
General connection timeout can be set directly, but stream read timeout needs to be handled separately.
Write your own code to process:
Copy the code The code is as follows:
$tmCurrent=gettimeofday ();
$intUSGone=($tmCurrent['sec']-$tmStart['sec'])*1000000
+($tmCurrent['usec']-$tmStart['usec']);
if($intUSGone>$this->_intReadTimeoutUS){
returnfalse;
}
Or use the built-in stream processing functions stream_set_timeout() and stream_get_meta_data() to process:
Copy code The code is as follows:
//Timeoutinseconds
$timeout=5;
$fp=fsockopen("example.com",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);//Set timeout
$info =stream_get_meta_data($fp);
while((!feof($fp))&&(!$info['timed_out'])){
$data.=fgets($fp,4096);
$info=stream_get_meta_data($fp);
ob_flush;
flush();
}
if($info['timed_out']){
echo "ConnectionTimedOut!";
}else{
echo$data;
}
}
file_get_contents timeout:
Copy code The code is as follows:
$timeout=array(
'http'=>array(
'timeout'=>5//Settings A timeout in seconds
)
);
$ctx=stream_context_create($timeout);
$text=file_get_contents("http://example.com/",0,$ ctx);
?>
fopen timeout:
Copy code The code is as follows:
$timeout=array(
'http'=>array(
'timeout'=>5//Set a timeout 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]
The mysql client in php does not have the option to set a timeout, neither mysqli nor mysql, but libmysql provides the timeout option, but we hide it in php That’s all.
So how to use this operation in PHP requires us to define some MySQL operation constants ourselves. The main constants involved are:
MYSQL_OPT_READ_TIMEOUT=11;
MYSQL_OPT_WRITE_TIMEOUT=12;
These two, After definition, you can use options to set the corresponding value.
But there is a point to note, the internal implementation of mysql:
1. The timeout setting unit is seconds, and the minimum configuration is 1 second
2. However, the underlying read of mysql will retry twice, so the actual time will be 3 seconds
Retry twice + itself once = 3 times the timeout, which means that the minimum timeout is 3 seconds and will not be lower than this value. It is acceptable for most applications, but a small number of applications need to be optimized.
View a php instance that sets the timeout for accessing mysql:
Copy the code The code is as follows:
//Define your own read and write timeout constant
if(!defined('MYSQL_OPT_READ_TIMEOUT')){
define('MYSQL_OPT_READ_TIMEOUT',11);
}
if(!defined('MYSQL_OPT_READ_TIMEOUT',11); ')){
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 query sleep1 seconds No timeout
printf("Hostinformation:%s/n",$mysqli->host_info);
if(!($res=$mysqli->query('selectsleep(1)'))) {
echo "query1error:".$mysqli->error."/n";
}else{
echo "Query1:querysuccess/n";
}
//Execute Querying sleep for 9 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";
?>
Extended 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]])
Nothing during get or set Explicit timeout setting parameters.
libmemcached client: There is no obvious timeout parameter in the php interface.
Note: Therefore, there are many problems when accessing Memcached in PHP. You need to hack some operations by yourself, or refer to online patches.
[C&C++ access Memcached]
Client: libmemcached client
Note: The memcache timeout configuration can be configured smaller, such as 5 or 10 milliseconds is enough. If it exceeds this time, it is better to query from the database.
The following is a C++ example of timeout for connecting and reading set data:
Copy code The code is as follows:
//Create connection timeout (connect to Memcached)
memcached_st*MemCacheProxy::_create_handle()
{
memcached_st*mmc=NULL;
memcached_return_tprc;
if( _mpool!=NULL){//getfrompool
mmc=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;
}
//Set connection/read timeout
memcached_behavior_set(handle,MEMCACHED_BEHAVIOR_HASH,MEMCACHED_HASH_DEFAULT);
memcached_behavior_set(handle,MEMCACHED_BEHAVIOR_NO_B LOCK,_noblock) ;//The parameter MEMCACHED_BEHAVIOR_NO_BLOCK is set to 1 to make the timeout configuration take effect. If the timeout is not set, it will not take effect. It will be tragic at critical times and can easily cause an avalanche
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);
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;
}
//Settings A key times out (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 read data 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);
It can be seen from the interface that there is no timeout setting when reading data of.
Extended reading:
http://hi.baidu.com/chinauser/item/b30af90b23335dde73e67608
http://libmemcached.org/libMemcached.html
[How to implement timeout]
The program needs to have a timeout function. For example, if you access a back-end Socket module alone, and the Socket module does not belong to any of the ones we described above, its protocol is also private, so you may need it at this time. To implement some timeout processing strategies yourself, you will need some processing code at this time.
[Timeout implementation in PHP]
1. Elementary: The simplest timeout implementation (second-level timeout)
The idea is very simple: connect to a backend, and then set it to non-blocking mode. If there is no connection, Keep looping to determine the difference between the current time and the timeout time.
The original timeout is implemented in phpsocket: (the current time is subtracted for each loop, the performance will be poor, and the CPU usage will be high)
Copy code The code is as follows:
$host="127.0.0.1";
$port="80";
$timeout=15;//timeoutinseconds
$socket=socket_create(AF_INET,SOCK_STREAM,SOL_TCP)
ordie("Unabletocreatesocketn");
socket_set_nonblock($socket) //Be sure to set to blocking mode
ordie("Unabletosetnonblockonsocketn");
$time=time();
//When looping, subtract the corresponding value each time
while(!@socket_connect($socket,$host,$port))//If there is no connection, it will continue Infinite loop
{
$err=socket_last_error($socket);
if($err==115||$err==114)
{
if((time()- $time)>=$timeout)//Every time you need to check whether it has timed out
{
socket_close($socket);
die("Connectiontimedout.n");
}
sleep(1);
continue;
}
die(socket_strerror($err)."n");
}
socket_set_block($this->socket)/ /Restore blocking mode
ordie("Unabletosetblockonsocketn");
?>
2. Upgrade: Use PHP’s own asynchronous IO to implement (millisecond timeout)
Explanation:
Asynchronous IO: The concept of asynchronous IO is opposite to synchronous IO. When an asynchronous procedure call is issued, the caller does not get the result immediately. The component that actually handles the call notifies the caller through status, notifications, and callbacks when it is complete. Asynchronous IO transfers bits into small groups, which can be 8 bits, 1 character or longer. The sender can send these groups of bits at any time, and the receiver never knows when they will arrive.
Multiplexing: The multiplexing model detects multiple IO operations and returns an operable collection so that they can be operated on. This avoids the determination that blocking IO cannot handle each IO at any time and non-blocking occupancy of system resources.
Use socket_select() to implement timeout
socket_select(...,floor($timeout),ceil($timeout*1000000));
Features of select: A timeout can be set to the microsecond level!
Use the timeout code of socket_select() (you need to know some knowledge of asynchronous IO programming to understand)
Copy the code The code is as follows:
Programming call class 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 class 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,$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 Linux C/C++, you can use: alarm() to set the timer Method to achieve second-level timeout, or: asynchronous multiplexed IO such as select(), poll(), epoll() to achieve millisecond-level timeout. You can also use secondary encapsulated asynchronous io libraries (libevent, libev) to achieve this.
1. Use signals in alarm to implement timeout (second-level timeout)
Explanation: The Linux kernel connect timeout is usually 75 seconds. We can set a smaller time such as 10 seconds to return from connect early. Here we use the signal processing mechanism, call alarm, and generate the SIGALRM signal after timeout (can also be implemented using select)
Use alarym seconds to implement connect setting timeout code example:
Copy code The code is as follows:
//Signal processing function
staticvoidconnect_alarm(intsigno)
{
debug_printf("SignalHandler");
return;
}
//Alarm timeout connection implementation
staticvoidconn_alarm()
{
Sigfunc*sigfunc;//Existing signal processing function
sigfunc=signal(SIGALRM,connect_alarm);// Create the signal processing function connect_alarm, (if any) save the existing signal processing function
inttimeout=5;
//Set the alarm clock
if(alarm(timeout)!=0){
// ...The alarm clock has been set and processed
}
//Perform connection operation
if(connect(m_Socket,(structsockaddr*)&addr,sizeof(addr))<0){
if(errno ==EINTR){//If the error number is set to EINTR, it means that the timeout was interrupted
debug_printf("Timeout");
http://www.bkjia.com/PHPjc/326022.htmlwww.bkjia.comtruehttp: //www.bkjia.com/PHPjc/326022.htmlTechArticleIn PHP development, there are many situations where timeout processing is used. Let me talk about a few scenarios: 1 . Acquire data asynchronously. If a certain back-end data source is not successfully obtained, it will be skipped and does not affect the entire...