浅谈php处理后端&接口访问超时的解决方法


Posted in PHP onOctober 29, 2016

【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允许执行的最长毫秒数。 (在cURL 7.16.2中被加入。从PHP 5.2.3起可使用。 )

CURLOPT_CONNECTTIMEOUT 在发起连接前等待的时间,如果设置为0,则无限等待。

CURLOPT_CONNECTTIMEOUT_MS 尝试连接等待的时间,以毫秒为单位。如果设置为0,则无限等待。  在cURL 7.16.2中被加入。从PHP 5.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('http://example.com/');
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_NOSIGNAL, 1);  
//注意,毫秒超时一定要设置这个
    curl_setopt($ch, CURLOPT_TIMEOUT_MS, 200); 
//超时毫秒,cURL 7.16.2中被加入。从PHP 5.2.3起可使用
    $data = curl_exec($ch);
    $curl_errno = curl_errno($ch);
    $curl_error = curl_error($ch);
    curl_close($ch);
 
    if ($curl_errno > 0) {
        echo "cURL Error ($curl_errno): $curl_error\n";
    } else {
        echo "Data received: $data\n";
    }
} 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) {
return false;
}

或者使用内置流处理函数 stream_set_timeout() 和 stream_get_meta_data() 处理:

<?php 
// Timeout in seconds 
$timeout = 5; 
$fp = fsockopen("example.com", 80, $errno, $errstr, $timeout); 
if ($fp) { 
    fwrite($fp, "GET / HTTP/1.0\r\n"); 
    fwrite($fp, "Host: example.com\r\n"); 
    fwrite($fp, "Connection: Close\r\n\r\n"); 
    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 "Connection Timed Out!"; 
    } else { 
        echo $data; 
    } 
}

file_get_contents 超时:

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

fopen 超时:

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

以上就是小编为大家带来的浅谈php处理后端&接口访问超时的解决方法全部内容了,希望大家多多支持三水点靠木~

PHP 相关文章推荐
Ajax实时验证用户名/邮箱等是否已经存在的代码打包
Dec 01 PHP
解析PHP中的正则表达式以及模式匹配
Jun 19 PHP
php获取错误信息的方法
Jul 17 PHP
使用图灵api创建微信聊天机器人
Jul 23 PHP
整理php防注入和XSS攻击通用过滤
Sep 13 PHP
php 问卷调查结果统计
Oct 08 PHP
PHP统计目录中文件以及目录中目录大小的方法
Jan 09 PHP
PHP扩展框架之Yaf框架的安装与使用
May 18 PHP
PHP 闭包详解及实例代码
Sep 28 PHP
php爬取天猫和淘宝商品数据
Feb 23 PHP
PHP预定义超全局数组变量小结
Aug 20 PHP
基于PHP实现用户登录注册功能的详细教程
Aug 04 PHP
完美解决phpexcel导出到xls文件出现乱码的问题
Oct 29 #PHP
php通过PHPExcel导入Excel表格到MySQL数据库的简单实例
Oct 29 #PHP
浅谈PHP定义命令空间的几个注意点(推荐)
Oct 29 #PHP
php+mongodb判断坐标是否在指定多边形区域内的实例
Oct 28 #PHP
PHP创建多级目录的两种方法
Oct 28 #PHP
PHP查询大量数据内存耗尽问题的解决方法
Oct 28 #PHP
遍历指定目录,并存储目录内所有文件属性信息的php代码
Oct 28 #PHP
You might like
php图片加水印原理(超简单的实例代码)
2013/01/18 PHP
php在window iis的莫名问题的测试方法
2013/05/14 PHP
php实现用于删除整个目录的递归函数
2015/03/16 PHP
优化JavaScript脚本的性能的几个注意事项
2006/12/22 Javascript
URL地址中的#符号使用说明
2011/02/12 Javascript
js为数字添加逗号并格式化数字的代码
2013/08/23 Javascript
javascript中expression的用法整理
2014/05/13 Javascript
node.js+express制作网页计算器
2016/01/17 Javascript
一步一步封装自己的HtmlHelper组件BootstrapHelper(二)
2016/09/14 Javascript
vue2.0获取自定义属性的值
2017/03/28 Javascript
基于vue+ bootstrap实现图片上传图片展示功能
2017/05/17 Javascript
详解vue服务端渲染(SSR)初探
2017/06/19 Javascript
Vue实现导航栏点击当前标签变色功能
2020/08/19 Javascript
Python实现微信公众平台自定义菜单实例
2015/03/20 Python
在CentOS上配置Nginx+Gunicorn+Python+Flask环境的教程
2016/06/07 Python
python实现二维码扫码自动登录淘宝
2016/12/27 Python
python入门教程之识别验证码
2017/03/04 Python
python使用Apriori算法进行关联性解析
2017/12/21 Python
python之super的使用小结
2018/08/13 Python
Python爬虫:将headers请求头字符串转为字典的方法
2019/08/21 Python
TensorFlow实现打印每一层的输出
2020/01/21 Python
Python异步编程之协程任务的调度操作实例分析
2020/02/01 Python
python opencv圆、椭圆与任意多边形的绘制实例详解
2020/02/06 Python
使用python采集Excel表中某一格数据
2020/05/14 Python
浅谈keras通过model.fit_generator训练模型(节省内存)
2020/06/17 Python
python 获取计算机的网卡信息
2021/02/18 Python
CSS3标注引用的出处和来源的方法
2020/02/25 HTML / CSS
学校后勤人员职责
2013/12/27 职场文书
环保宣传标语
2014/06/12 职场文书
消防宣传口号
2014/06/16 职场文书
小学生2014国庆节演讲稿:祖国在我心中
2014/09/21 职场文书
初中作文评语集锦
2014/12/25 职场文书
党员争先创优承诺书
2015/01/20 职场文书
索赔员岗位职责
2015/02/15 职场文书
python 中yaml文件用法大全
2021/07/04 Python
浅谈spring boot使用thymeleaf版本的问题
2021/08/04 Java/Android