导航:首页 > 编程语言 > php调用接口超时

php调用接口超时

发布时间:2022-12-23 07:08:45

⑴ 接口超时

当设计的业务流程或者功能需要调用其他接口实现请求与响应的时候,可能由于网络等原因导致的接口超时导致业务中断或者功能反馈有误等。所以,对接口超时的知识做一个积累。

1、接口资源(Mysql、Redis、Memcached、HTTP 接口)具备这样一些特点:

(1)都是网络接口:网络会成为影响因素

(2)这些资源的可用性,连接速度、读取速度不可控

(3)分层模式,对于调用方来说,只明确是否能够读取数据、数据是否正确;对于资源提供方来说负责具体的数据逻辑。

2、所以涉及到接口开发时,需要注意(产品更多的关注点)

(1)超时机制:对于资源可能会很慢,对于应用程序来说,一个 HTTP 接口,假如返回数据需要十秒,本身是不可接受的那么,所以需要一个超时机制,结束这个资源调配的进程

(2)重试机制:假如一个资源特别重要,可以采取失败重试。比如下单跟第三方接口确认订单时,出现中断等原因导致接口返回有误,可以进行重试请求

(3)异常处理机制:当请求或者返回出现问题,导致功能无法正确发挥效果的时候,不应该仅是简单处理为返回空值,最好能明确产生异常的原因。同时,告知用户该操作失败的原因,和操作补偿,怎么样才让用户将该流程继续。

3、与用户的交互 (产品更多的关注点)

http://naotu..com/file/?token=fa42fb62487d60fb

4、研发技术上可能可以尝试的解决方案:

(1)增加超时时间

假设A系统有个方法methodA,会调用B系统的methodB这个http接口,如果mehodA不追求超快的 响应速度 ,那么你在调用methodB这个http接口时,可以增长超时时间,例如10秒超时。因为经常在某些时刻,由于网络原因或者系统原因,调用method会超时的。

(2)尝试多调用一次

如果第一次调用methodB超时了,那么你可以尝试多调用一次。当然前提是,methodA不追求超快的响应时间。

(3)使用待处理队列

如果methodA需要很快的响应速度,那么当调用methodB接口超时时,可以使用一个队列存储本次失败的记录,然后使用一个job每隔一段时间去扫这个队列,看看是否有待处理的数据。

备注:如果对方系统挂掉了,使用待处理队列的方式,比较合适。

(4)回滚数据

catch这个超时异常,然后记录日志后,抛出这个异常,并把之前的数据回滚。让对方的系统重新调用。

备注:宁愿没有数据,也不要存储脏数据。

(5)使用异步机制

如果你的业务方法中,需要调用对方的http接口,如果这个http接口不影响主流程的,那么可以使用一个线程,异步调用对方的http接口,并把超时时间设置长一些。由于使用了异步,主流程会立刻继续走的。

(6)问题:调用第三方支付接口响应时间超过10秒,导致大量线上订单因为超时失败,该接口是实时返回结果的,而且不是一直都慢,是偶尔慢。

解决方法:调用接口时设置超时时间,当接口超过9秒未返回结果, 自动将改订单设置为处理中 ,然后后由定时任务调用查询接口。

这样就把,一个实时返回结果的接口,当成一个异步的接口来用了,总比一大堆失败订单等着财务来找好。

可查看链接:

http://wulijun.github.io/2012/08/08/php-timeout-summary.html

http://www.jianshu.com/p/8555ce285375

⑵ 几种常见的PHP超时处理方法

【Web服务器超时处理】

[ Apache ]
一般在性能很高的情况下,缺省所有超时配置都是30秒,但是在上传文件,或者网络速度很慢的情况下,那么可能触发超时操作。
目前apachefastcgiphp-fpm模式下有三个超时设置:
fastcgi超时设置:
修改的fastcgi连接配置,类似如下:

复制代码 代码如下:

<IfMolemod_fastcgi.c>
FastCgiExternalServer/home/forum/apache/apache_php/cgi-bin/php-cgi-socket/home/forum/php5/etc/php-fpm.sock
ScriptAlias/fcgi-bin/"/home/forum/apache/apache_php/cgi-bin/"
AddHandlerphp-fastcgi.php
Actionphp-fastcgi/fcgi-bin/php-cgi
AddTypeapplication/x-
</IfMole>

缺省配置是30s,如果需要定制自己的配置,需要修改配置,比如修改为100秒:(修改后重启apache):

复制代码 代码如下:

<IfMolemod_fastcgi.c>
FastCgiExternalServer/home/forum/apache/apache_php/cgi-bin/php-cgi-socket/home/forum/php5/etc/php-fpm.sock-idle-timeout100
ScriptAlias/fcgi-bin/"/home/forum/apache/apache_php/cgi-bin/"
AddHandlerphp-fastcgi.php
Actionphp-fastcgi/fcgi-bin/php-cgi
AddTypeapplication/x-
</IfMole>

如果超时会返回500错误,断开跟后端php服务的连接,同时记录一条apache错误日志:
[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"
其他fastcgi配置参数说明:
复制代码 代码如下:

IdleTimeout发呆时限
ProcessLifeTime一个进程的最长生命周期,过期之后无条件kill
MaxProcessCount最大进程个数
DefaultMinClassProcessCount每个程序启动的最小进程个数
DefaultMaxClassProcessCount每个程序启动的最大进程个数
IPCConnectTimeout程序响应超时时间
IPCCommTimeout与程序通讯的最长时间,上面的错误有可能就是这个值设置过小造成的
MaxRequestsPerProcess每个进程最多完成处理个数,达成后自杀

[ Lighttpd ]
配置:lig
Lighttpd配置中,关于超时的参数有如下几个(篇幅考虑,只写读超时,写超时参数同理):
主要涉及选项:
server.max-keep-alive-idle=5
server.max-read-idle=60
server.read-timeout=0
server.max-connection-idle=360
复制代码 代码如下:

#每次keep-alive的最大请求数,默认值是16
server.max-keep-alive-requests=100
#keep-alive的最长等待时间,单位是秒,默认值是5
server.max-keep-alive-idle=1200
#lighttpd的work子进程数,默认值是0,单进程运行
server.max-worker=2
#限制用户在发送请求的过程中,最大的中间停顿时间(单位是秒),
#如果用户在发送请求的过程中(没发完请求),中间停顿的时间太长,lighttpd会主动断开连接
#默认值是60(秒)
server.max-read-idle=1200
#限制用户在接收应答的过程中,最大的中间停顿时间(单位是秒),
#如果用户在接收应答的过程中(没接完),中间停顿的时间太长,lighttpd会主动断开连接
#默认值是360(秒)
server.max-write-idle=12000
#读客户端请求的超时限制,单位是秒,配为0表示不作限制
#设置小于max-read-idle时,read-timeout生效
server.read-timeout=0
#写应答页面给客户端的超时限制,单位是秒,配为0表示不作限制
#设置小于max-write-idle时,write-timeout生效
server.write-timeout=0
#请求的处理时间上限,如果用了mod_proxy_core,那就是和后端的交互时间限制,单位是秒
server.max-connection-idle=1200

说明:
对于一个keep-alive连接上的连续请求,发送第一个请求内容的最大间隔由参数max-read-idle决定,从第二个请求起,发送请求内容的最大间隔由参数max-keep-alive-idle决定。请求间的间隔超时也由max-keep-alive-idle决定。发送请求内容的总时间超时由参数read-timeout决定。Lighttpd与后端交互数据的超时由max-connection-idle决定。
延伸阅读:

[ Nginx ]
配置:nf
复制代码 代码如下:

http{
#Fastcgi:(针对后端的fastcgi生效,fastcgi不属于proxy模式)
fastcgi_connect_timeout5;#连接超时
fastcgi_send_timeout10; #写超时
fastcgi_read_timeout10;#读取超时
#Proxy:(针对proxy/upstreams的生效)
proxy_connect_timeout15s;#连接超时
proxy_read_timeout24s;#读超时
proxy_send_timeout10s; #写超时
}

说明:
Nginx 的超时设置倒是非常清晰容易理解,上面超时针对不同工作模式,但是因为超时带来的问题是非常多的。
延伸阅读:
ml
ml
ml

【PHP本身超时处理】
[ PHP-fpm ]
配置:nf
复制代码 代码如下:

<?xmlversion="1.0"?>
<configuration>
//...
.
.
EquivalenttoPHP_FCGI_.fcgi
Usedwithanypm_style.
#php-cgi的进程数量
<valuename="max_children">128</value>
Thetimeout(inseconds)
Shouldbeusedwhen'max_execution_time'
'0s'means'off'
#php-fpm 请求执行超时时间,0s为永不超时,否则设置一个 Ns 为超时的秒数
<valuename="request_terminate_timeout">0s</value>
Thetimeout(inseconds).logfile
'0s'means'off'
<valuename="request_slowlog_timeout">0s</value>
</configuration>

说明:
在php.ini中,有一个参数max_execution_time可以设置PHP脚本的最大执行时间,但是,在php-cgi(php-fpm)中,该参数不会起效。真正能够控制PHP脚本最大执行时:
<valuename="request_terminate_timeout">0s</value>
就是说如果是使用mod_php5.so的模式运行max_execution_time是会生效的,但是如果是php-fpm模式中运行时不生效的。
延伸阅读:

[ PHP ]
配置:php.ini
选项:
max_execution_time=30
或者在代码里设置:
ini_set("max_execution_time",30);
set_time_limit(30);
说明:
对当前会话生效,比如设置0一直不超时,但是如果php的safe_mode打开了,这些设置都会不生效。
效果一样,但是具体内容需要参考php-fpm部分内容,如果php-fpm中设置了request_terminate_timeout的话,那么max_execution_time就不生效。
【后端&接口访问超时】
【HTTP访问】
一般我们访问HTTP方式很多,主要是:curl,socket,file_get_contents()等方法。
如果碰到对方服务器一直没有响应的时候,我们就悲剧了,很容易把整个服务器搞死,所以在访问http的时候也需要考虑超时的问题。
[ CURL 访问HTTP]
CURL 是我们常用的一种比较靠谱的访问HTTP协议接口的lib库,性能高,还有一些并发支持的功能等。
CURL:
curl_setopt($ch,opt)可以设置一些超时的设置,主要包括:
*(重要)CURLOPT_TIMEOUT设置cURL允许执行的最长秒数。
*(重要)CURLOPT_TIMEOUT_MS设置cURL允许执行的最长毫秒数。(在cURL7.16.2中被加入。从PHP5.2.3起可使用。)
CURLOPT_CONNECTTIMEOUT在发起连接前等待的时间,如果设置为0,则无限等待。
CURLOPT_CONNECTTIMEOUT_MS尝试连接等待的时间,以毫秒为单位。如果设置为0,则无限等待。在cURL7.16.2中被加入。从PHP5.2.3开始可用。
CURLOPT_DNS_CACHE_TIMEOUT设置在内存中保存DNS信息的时间,默认为120秒。
curl普通秒级超时:
$ch=curl_init();
curl_setopt($ch,CURLOPT_URL,$url);
curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);
curl_setopt($ch,CURLOPT_TIMEOUT,60);//只需要设置一个秒的数量就可以
curl_setopt($ch,CURLOPT_HTTPHEADER,$headers);
curl_setopt($ch,CURLOPT_USERAGENT,$defined_vars['HTTP_USER_AGENT']);
curl普通秒级超时使用:
curl_setopt($ch,CURLOPT_TIMEOUT,60);
curl如果需要进行毫秒超时,需要增加:
curl_easy_setopt(curl,CURLOPT_NOSIGNAL,1L);
或者是:
curl_setopt($ch,CURLOPT_NOSIGNAL,true);是可以支持毫秒级别超时设置的
curl一个毫秒级超时的例子:
复制代码 代码如下:

<?php
if(!isset($_GET['foo'])){
//Client
$ch=curl_init('');
curl_setopt($ch,CURLOPT_RETURNTRANSFER,true);
curl_setopt($ch,CURLOPT_NOSIGNAL,1);//注意,毫秒超时一定要设置这个
curl_setopt($ch,CURLOPT_TIMEOUT_MS,200);//超时毫秒,cURL7.16.2中被加入。从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.";
}
?>

其他一些技巧:
1. 按照经验总结是:cURL版本>=libcurl/7.21.0版本,毫秒级超时是一定生效的,切记。
2. curl_multi的毫秒级超时也有问题。。单次访问是支持ms级超时的,curl_multi并行调多个会不准
[流处理方式访问HTTP]
除了curl,我们还经常自己使用fsockopen、或者是file操作函数来进行HTTP协议的处理,所以,我们对这块的超时处理也是必须的。
一般连接超时可以直接设置,但是流读取超时需要单独处理。
自己写代码处理:
复制代码 代码如下:

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

或者使用内置流处理函数stream_set_timeout()和stream_get_meta_data()处理:
复制代码 代码如下:

<?php
//Timeoutinseconds
$timeout=5;
$fp=fsockopen("",80,$errno,$errstr,$timeout);
if($fp){
fwrite($fp,"GET/HTTP/1.0rn");
fwrite($fp,"Host:rn");
fwrite($fp,"Connection:Closernrn");
stream_set_blocking($fp,true);//重要,设置为非阻塞模式
stream_set_timeout($fp,$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超时:
复制代码 代码如下:

<?php
$timeout=array(
'http'=>array(
'timeout'=>5//设置一个超时时间,单位为秒
)
);
$ctx=stream_context_create($timeout);
$text=file_get_contents("",0,$ctx);
?>

fopen超时:
复制代码 代码如下:

<?php
$timeout=array(
'http'=>array(
'timeout'=>5//设置一个超时时间,单位为秒
)
);
$ctx=stream_context_create($timeout);
if($fp=fopen("","r",false,$ctx)){
while($c=fread($fp,8192)){
echo$c;
}
fclose($fp);
}
?>

【MySQL】
php中的mysql客户端都没有设置超时的选项,mysqli和mysql都没有,但是libmysql是提供超时选项的,只是我们在php中隐藏了而已。
那么如何在PHP中使用这个操作捏,就需要我们自己定义一些MySQL操作常量,主要涉及的常量有:
MYSQL_OPT_READ_TIMEOUT=11;
MYSQL_OPT_WRITE_TIMEOUT=12;
这两个,定义以后,可以使用options设置相应的值。
不过有个注意点,mysql内部实现:
1.超时设置单位为秒,最少配置1秒
2.但mysql底层的read会重试两次,所以实际会是3秒
重试两次+自身一次=3倍超时时间,那么就是说最少超时时间是3秒,不会低于这个值,对于大部分应用来说可以接受,但是对于小部分应用需要优化。
查看一个设置访问mysql超时的php实例:
复制代码 代码如下:

<?php
//自己定义读写超时常量
if(!defined('MYSQL_OPT_READ_TIMEOUT')){
define('MYSQL_OPT_READ_TIMEOUT',11);
}
if(!defined('MYSQL_OPT_WRITE_TIMEOUT')){
define('MYSQL_OPT_WRITE_TIMEOUT',12);
}
//设置超时
$mysqli=mysqli_init();
$mysqli->options(MYSQL_OPT_READ_TIMEOUT,3);
$mysqli->options(MYSQL_OPT_WRITE_TIMEOUT,1);
//连接数据库
$mysqli->real_connect("localhost","root","root","test");
if(mysqli_connect_errno()){
printf("Connectfailed:%s/n",mysqli_connect_error());
exit();
}
//执行查询sleep1秒不超时
printf("Hostinformation:%s/n",$mysqli->host_info);
if(!($res=$mysqli->query('selectsleep(1)'))){
echo"query1error:".$mysqli->error."/n";
}else{
echo"Query1:querysuccess/n";
}
//执行查询sleep9秒会超时
if(!($res=$mysqli->query('selectsleep(9)'))){
echo"query2error:".$mysqli->error."/n";
}else{
echo"Query2:querysuccess/n";
}
$mysqli->close();
echo"closemysqlconnection/n";
?>

延伸阅读:

【Memcached】
[PHP扩展]
php_memcache客户端:
连接超时:boolMemcache::connect(string$host[,int$port[,int$timeout]])
在get和set的时候,都没有明确的超时设置参数。
libmemcached客户端:在php接口没有明显的超时参数。
说明:所以说,在PHP中访问Memcached是存在很多问题的,需要自己hack部分操作,或者是参考网上补丁。
[C&C++访问Memcached]
客户端:libmemcached客户端
说明:memcache超时配置可以配置小点,比如5,10个毫秒已经够用了,超过这个时间还不如从数据库查询。
下面是一个连接和读取set数据的超时的C++示例:
复制代码 代码如下:

//创建连接超时(连接到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;
}
//设置连接/读取超时
memcached_behavior_set(handle,MEMCACHED_BEHAVIOR_HASH,MEMCACHED_HASH_DEFAULT);
memcached_behavior_set(handle,MEMCACHED_BEHAVIOR_NO_BLOCK,_noblock);//参数MEMCACHED_BEHAVIOR_NO_BLOCK为1使超时配置生效,不设置超时会不生效,关键时候会悲剧的,容易引起雪崩
memcached_behavior_set(handle,MEMCACHED_BEHAVIOR_CONNECT_TIMEOUT,_connect_timeout);//连接超时
memcached_behavior_set(handle,MEMCACHED_BEHAVIOR_RCV_TIMEOUT,_read_timeout);//读超时
memcached_behavior_set(handle,MEMCACHED_BEHAVIOR_SND_TIMEOUT,_send_timeout);//写超时
memcached_behavior_set(handle,MEMCACHED_BEHAVIOR_POLL_TIMEOUT,_poll_timeout);
//设置一致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;
}
//设置一个key超时(set一个数据到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]);
//有个timeout值
rc=memcached_set(handle,tmp,strlen(tmp),(char*)value,len,timeout,0);
if(MEMCACHED_SUCCESS!=rc){
returnfalse;
}
returntrue;
}

//Memcache读取数据超时(没有设置)
libmemcahed源码中接口定义:
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);
从接口中可以看出在读取数据的时候,是没有超时设置的。
延伸阅读:

【如何实现超时】
程序中需要有超时这种功能,比如你单独访问一个后端Socket模块,Socket模块不属于我们上面描述的任何一种的时候,它的协议也是私有的,那么这个时候可能需要自己去实现一些超时处理策略,这个时候就需要一些处理代码了。
[PHP中超时实现]
一、初级:最简单的超时实现 (秒级超时)
思路很简单:链接一个后端,然后设置为非阻塞模式,如果没有连接上就一直循环,判断当前时间和超时时间之间的差异。
phpsocket中实现原始的超时:(每次循环都当前时间去减,性能会很差,cpu占用会较高)
复制代码 代码如下:

<?
$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) //务必设置为阻塞模式
ordie("Unabletosetnonblockonsocketn");
$time=time();
//循环的时候每次都减去相应值
while(!@socket_connect($socket,$host,$port))//如果没有连接上就一直死循环
{
$err=socket_last_error($socket);
if($err==115||$err==114)
{
if((time()-$time)>=$timeout)//每次都需要去判断一下是否超时了
{
socket_close($socket);
die("Connectiontimedout.n");
}
sleep(1);
continue;
}
die(socket_strerror($err)."n");
}
socket_set_block($this->socket)//还原阻塞模式
ordie("Unabletosetblockonsocketn");
?>

二、升级:使用PHP自带异步IO去实现(毫秒级超时)
说明:
异步IO:异步IO的概念和同步IO相对。当一个异步过程调用发出后,调用者不能立刻得到结果。实际处理这个调用的部件在完成后,通过状态、通知和回调来通知调用者。异步IO将比特分成小组进行传送,小组可以是8位的1个字符或更长。发送方可以在任何时刻发送这些比特组,而接收方从不知道它们会在什么时候到达。
多路复用:复用模型是对多个IO操作进行检测,返回可操作集合,这样就可以对其进行操作了。这样就避免了阻塞IO不能随时处理各个IO和非阻塞占用系统资源的确定。
使用socket_select()实现超时
socket_select(...,floor($timeout),ceil($timeout*1000000));
select的特点:能够设置到微秒级别的超时!
使用socket_select()的超时代码(需要了解一些异步IO编程的知识去理解)
复制代码 代码如下:

编程 调用类 编程#
<?php
$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
}
}
}
?>
编程 异步多路复用IO & 超时连接处理类 编程
<?php
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;
}
}
?>

[C&C++中超时实现]
一般在LinuxC/C++中,可以使用:alarm()设置定时器的方式实现秒级超时,或者:select()、poll()、epoll()之类的异步复用IO实现毫秒级超时。也可以使用二次封装的异步io库(libevent,libev)也能实现。
一、使用alarm中用信号实现超时 (秒级超时)
说明:Linux内核connect超时通常为75秒,我们可以设置更小的时间如10秒来提前从connect中返回。这里用使用信号处理机制,调用alarm,超时后产生SIGALRM信号(也可使用select实现)
用alarym秒级实现connect设置超时代码示例:
复制代码 代码如下:

//信号处理函数
staticvoidconnect_alarm(intsigno)
{
debug_printf("SignalHandler");
return;
}
//alarm超时连接实现
staticvoidconn_alarm()
{
Sigfunc*sigfunc;//现有信号处理函数
sigfunc=signal(SIGALRM,connect_alarm);//建立信号处理函数connect_alarm,(如果有)保存现有的信号处理函数
inttimeout=5;
//设置闹钟
if(alarm(timeout)!=0){
//...闹钟已经设置处理
}
//进行连接操作
if(connect(m_Socket,(structsockaddr*)&addr,sizeof(addr))<0){
if(errno==EINTR){//如果错误号设置为EINTR,说明超时中断了
debug_printf("Timeout");

⑶ 几种常见的PHP超时处理方法

一、在php.ini里面设置 max_execution_time = 1800;
二、通过PHP的ini_set 函数设置 ini_set("max_execution_time", "1800");
三、通过set_time_limit 函数设置 set_time_limit(1800) ;

⑷ php webservice 调用错误出现 Fault occurred while processing

本地调用接口的时候的参数中有很多参数是空的,将这些参数替换为空字符串 ""再试试,说不准就好了。

对于我这个方法的问题追踪最终的产生原因 ,是webservice服务端的处理中没有空从参数进行处理,也就是说这是服务端的问题,客户端可以使用替换null为空字符串的方法进行解决。

⑸ php进程超时接口返回504错误分析

在一次接口测试中,发现返回的http 504 time out 的错误,然后查看了php-fpm的错误日志,发现了如下错误

从表现上看,是php进程超时导致的进程被kill了,那么这个超时时间以及kill的机制是跟哪些参数有关呢,这里系统这里一下。

Nginx服务一般因为php的错误或者超时会有两种错误码502 bad Gateway 或者 504 Gateway Time-out

一种情况是php产生了语法错误,比如循环调用、变量作用域错误、方法不存在等,如果开启错误日志输出的话,这种错误在php-fpm的错误日志中是可以看到调用栈信息的。

另外一种情况可能就是超时引起的php-fpm主动kill的情况,在php.ini和php.fpm中有两个配置项,用来管理php脚本的最大执行时间

当php脚本的执行时间超过这个时间时,PHP-FPM不只会终止脚本的执行,还会终止执行脚本的Worker进程。所以Nginx会发现与自己通信的连接断掉了,就会返回给客户端502错误。

以顶部的错误为例,当报502错误是,nginx的errorlog中有如下日志,:

所以只需将这两项的值调大一些就可以让PHP脚本不会因为执行时间长而被终止了。request_terminate_timeout可以覆盖max_execution_time,

所以如果不想改全局的php.ini,那只改PHP-FPM的配置就可以了。

此外要注意的是Nginx的upstream模块中的max_fail和fail_timeout两项。这两个配置表示在fail_timeout事件内,如果fail的测试达到max_fail,那么在接下来的fail_timeout时间内,Nginx都会认为上游服务器挂掉了,都会返回502错误。

所以可以将max_fail调大一些,将fail_timeout调小一些。

PHP-FPM设置的脚本最大执行时间已经够长了,但执行耗时PHP脚本时,发现Nginx报错从502变为504了。这是为什么呢?

因为我们修改的只是PHP的配置,Nginx中也有关于与上游服务器通信超时时间的配置

以Nginx超时时间为90秒,PHP-FPM超时时间为300秒为例,报504 Gateway Timeout错误时的Nginx错误访问日志如下:

调高这三项的值(主要是read和send两项,默认不配置的话Nginx会将超时时间设为60秒)之后,504错误也解决了。

而且这三项配置可以配置在http、server级别,也可以配置在location级别。担心影响其他应用的话,就配置在自己应用的location中吧。

要注意的是factcgi_connect/read/send_timeout是对FastCGI生效的,而proxy_connect/read/send_timeout是对proxy_pass生效的。

参考链接: http://www.cnblogs.com/fei33423/p/8184098.html 感谢分享!

⑹ php 调用微信接口频繁,怎么限制让他发送10条消息1秒钟之后再发送

正常接口返回格式是{code:0,msg:'',data:{}},接口限制的时候可以返回{code:1001,msg:'请一秒钟后重试.',data:{}}
你可以记录一个cahce值,内容就存用户这次访问本接口的时间戳,和发送次数;每次请求进来的时候,取用户cache,比对发送次数,如果不到10次,提示msg,然后ajax接收到code=1001的返回值就搁置按钮1秒钟.

⑺ php soap 如何设置超时

在使用soap前,先检查soap的url是否可访问。如为true则继续执行Soap,否则给出超时提醒。
下面是我经常使用的判断网站链接是否可用的函数,希望对你有用。

//判断URL在指定时间内是否有相应
function checkUrl($url, $timeout = 3){
$ret = false;
$handle = curl_init();
curl_setopt($handle, CURLOPT_URL,$url);
curl_setopt($handle, CURLOPT_NOBODY, true);
curl_setopt($handle, CURLOPT_TIMEOUT,$timeout);//设置默认超时时间为3秒
$result = curl_exec($handle);
$httpCode = curl_getinfo($handle, CURLINFO_HTTP_CODE);
curl_close($handle);
if(strpos($httpCode,'2') == 0){
$ret = true;
}
return $ret;
}

⑻ 关于php写登陆超时:下面代码,网站没有登陆的时候会显示‘logintime’未定义,怎么解决。

开头请先调用session_start();,你的代码没有问题,经测试可以正常使用

⑼ php 调用http接口 出现错误

122.Internal Server Error
The server encountered an internal error or misconfiguration and was unable to complete your request.
Please contact the server administrator at [email protected] to inform them of the time this error occurred, and the actions you performed just before this error.
More information about this error may be available in the server error log
问题原因:内部服务器出错,这个服务偶然的一个内部错误或者丢失配置并且无法去编译你的请求;请联系这个服务的管理员通过xx邮箱去通知他们这个错误发生的时间,并且这个检查你的在这个错误之前执行过得程序.很多内部关于错误可能有效的在这个服务错误日志中
解决方法:刷新一下页面就行了,服务器炸了
125.Internal Server Error
The server encountered an internal error or misconfiguration and was unable to complete your request
问题原因
解决方法:服务器目录,虚拟主机配置出错
132.500 Internal Server Error
The server encountered an internal error or misconfiguration and was unable to complete your request.
Please contact the server administrator at [email protected] to inform them of the time this error occurred, and e actions you performed just before this error.
More information about this error may be available in the server error log.
问题原因:500是服务器错误,内部服务错误,这个服务器偶然遇见了一个内部错误或者丢失了配置文件,导致无法去处理你的请求,请联系管理员,更多的错误信息,或许在服务器日志里
解决方法:这个是重写模式的文件语法格式不正确,导致的服务器加载这个错误文件时报错.解决方法,任意换一个重写文件
我编程这么久,就遇到过这三次,你根据自己问题看下哪一条适用吧。

⑽ 如果php运行超时怎么返回超时错误给前端

返回前端只适用于是使用AJAX进行加载的。

varres=$.ajax({
url:'xxxxxx/index.php',
timeout:1000,//超时时间设置,单位毫秒
complete:function(xhr,status){
if(status=='timeout'){
//超时处理
}
}
});
阅读全文

与php调用接口超时相关的资料

热点内容
dvd光盘存储汉子算法 浏览:757
苹果邮件无法连接服务器地址 浏览:963
phpffmpeg转码 浏览:671
长沙好玩的解压项目 浏览:145
专属学情分析报告是什么app 浏览:564
php工程部署 浏览:833
android全屏透明 浏览:737
阿里云服务器已开通怎么办 浏览:803
光遇为什么登录时服务器已满 浏览:302
PDF分析 浏览:485
h3c光纤全工半全工设置命令 浏览:143
公司法pdf下载 浏览:382
linuxmarkdown 浏览:350
华为手机怎么多选文件夹 浏览:683
如何取消命令方块指令 浏览:349
风翼app为什么进不去了 浏览:778
im4java压缩图片 浏览:362
数据查询网站源码 浏览:150
伊克塞尔文档怎么进行加密 浏览:892
app转账是什么 浏览:163