浅谈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 相关文章推荐
PHP中break及continue两个流程控制指令区别分析
Apr 18 PHP
PHP面向对象学习笔记之一 基础概念
Oct 06 PHP
php生成缩略图示例代码分享(使用gd库实现)
Jan 20 PHP
PHP遍历并打印指定目录下所有文件实例
Feb 10 PHP
php获取中文拼音首字母类和函数分享
Apr 24 PHP
PHP使用GIFEncoder类生成的GIF动态图片验证码
Jul 01 PHP
PHP使用gmdate实现将一个UNIX 时间格式化成GMT文本的方法
Mar 19 PHP
PHP中创建和验证哈希的简单方法实探
Jul 06 PHP
PHP导入导出Excel代码
Jul 07 PHP
thinkphp中字符截取函数msubstr()用法分析
Jan 09 PHP
PHP Yaf框架的简单安装使用教程(推荐)
Jun 08 PHP
php json相关函数用法示例
Mar 28 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
在 IE 中调用 javascript 打开 Excel 表
2006/12/21 Javascript
js函数的延迟加载实现代码
2012/10/11 Javascript
优化javascript的执行效率一些方法总结
2013/12/25 Javascript
javascript中bind函数的作用实例介绍
2014/09/28 Javascript
jquery解决客户端跨域访问问题
2015/01/06 Javascript
JQuery实现图片轮播效果
2015/09/15 Javascript
js识别uc浏览器的代码
2015/11/06 Javascript
JS判断是否手机或pad访问实现方法
2016/12/09 Javascript
jQuery基于正则表达式的表单验证功能示例
2017/01/21 Javascript
JS严格模式知识点总结
2018/02/27 Javascript
js用正则表达式筛选年月日的实例方法
2021/01/04 Javascript
[01:17:12]职来职往完美电竞专场
2014/09/18 DOTA
Python的Bottle框架的一些使用技巧介绍
2015/04/08 Python
深入源码解析Python中的对象与类型
2015/12/11 Python
黑科技 Python脚本帮你找出微信上删除你好友的人
2016/01/07 Python
浅谈python 线程池threadpool之实现
2017/11/17 Python
Python实现两款计算器功能示例
2017/12/19 Python
TensorFlow实现卷积神经网络
2018/05/24 Python
用Python读取几十万行文本数据
2018/12/24 Python
Python实现Word表格转成Excel表格的示例代码
2020/04/16 Python
keras自定义回调函数查看训练的loss和accuracy方式
2020/05/23 Python
基于python实现复制文件并重命名
2020/09/16 Python
python用tkinter实现一个gui的翻译工具
2020/10/26 Python
CSS3 实用技巧:实现黑白图像效果示例代码
2013/07/11 HTML / CSS
html5+css3之CSS中的布局与Header的实现
2014/11/21 HTML / CSS
阿玛尼意大利官网:Armani意大利
2018/10/30 全球购物
Python面试题:如何用Python来发送邮件
2016/03/15 面试题
收银出纳员岗位职责
2014/02/23 职场文书
物业总经理岗位职责
2014/02/28 职场文书
2014年征兵标语
2014/06/20 职场文书
支部书记四风对照材料
2014/08/28 职场文书
幼儿园中班个人总结
2015/02/28 职场文书
房租涨价通知
2015/04/23 职场文书
初婚未育证明样本
2015/06/18 职场文书
《酸的和甜的》教学反思
2016/02/18 职场文书
Python基础之常用库常用方法整理
2021/04/30 Python