## 场景要求
客户端调用服务器a.php接口,需要执行一个长达5s-20s不等的耗资源操作,但是客户端响应请求时间为5秒(微信公众账号服务器请求响应超时时间),5s以上无回复即断开连接。
## 解决设想
客户端调用a.php之后,a.php执行异步多线程操作调用b.php,a.php调用成功后即刻反馈给客户端回执,b.php自动执行耗资源操作。
## 难点
PHP没有真正实现多线程操作的方法。所以需要通过其它手段来进行模拟多线程。
## 方案一
利用CURL非阻塞调用b.php,实现过程可以参考
http://blog.csdn.net/linvo/article/details/5956629
但是有一个问题,就是a.php会继续等待b.php的响应。
于是临时想了一个解决方案:
在此处代码中,将$curlopt_timeout改为1
```
/**
* 单个CURL调用超时限制
*/
public $curlopt_timeout = 1;
private $param = array();
```
但是这样做就违背了curl本身的逻辑限制。
## 方案二
利用socket
在a.php中加入以下代码
```
$fp = fsockopen("test.com", 80, $errno, $errstr, 30);
if (!$fp){
echo 'error fsockopen';
}
else{
stream_set_blocking($fp,0);
$http = "GET /test/b.php HTTP/1.1\r\n";
$http .= "Host: test.com\r\n";
$http .= "Connection: Close\r\n\r\n";
fwrite($fp,$http);
fclose($fp);
}
```
即可实现a.php调用b.php无阻塞。
代码中stream_set_blocking函数用来设定socket链接为无阻塞方式(默认为阻塞)。
## 问题
在使用方案二以后,遇到了一个问题,即客户端短时间内多次调用a.php,出现部分请求 没有执行b.php 的情况。
解决方法:
在Nginx的nginx.conf文件中,查看worker_processes为1,判断服务端响应请求的线程启动限制太大,得知服务器本身配置为双核CPU,判断2-4线程比较合适,于是修改worker_processes为4.问题得到解决!
```
报错:stream_set_blocking() expects parameter 1 to be resource, null given
解决方法,修改php.ini函数设置,找到
disable_functions =
将proc_open和stream_socket_server两个参数删除
重启php
```
完整代码:
```
/**
* @parem $url 网页地址 http://www.test.com/test/test.php
* @parem $port 网址端口 默认80
* @parem $t 脚本请求时间 默认30s
* @parem $method 请求方式 get/post
* @parem $data ['test'=>'1']
* */
public function asyncPHP($url, $port = 80, $t = 30, $method = 'get', $data = null)
{
$info = parse_url($url);
$fp = fsockopen($info["host"], $port, $errno, $errstr, $t);
//stream_set_blocking函数用来设定socket链接为无阻塞方式
stream_set_blocking($fp, 0);
// 判断是否有数据
if (isset($data) && !empty($data)) {
$query = http_build_query($data); // 数组转url 字符串形式
} else {
$query = null;
}
// 判断 请求方式
if ($method == 'post') {
$head = "POST " . $info['path'] . " HTTP/1.0" . PHP_EOL;
} else {
$head = "GET " . $info['path'] . "?" . $query . " HTTP/1.0" . PHP_EOL;
}
$head .= "Host: " . $info['host'] . PHP_EOL; // 请求主机地址
$head .= "Referer: " . $url . PHP_EOL;
if (isset($data) && !empty($data) && ($method == 'post')) {
$head .= "Content-type: application/x-www-form-urlencoded" . PHP_EOL;
$head .= "Content-Length: " . strlen(trim($query)) . PHP_EOL;
$head .= PHP_EOL;
$head .= trim($query);
} else {
$head .= PHP_EOL;
}
fwrite($fp, $head);
fclose($fp);
}
```
- 技能知识点
- 对死锁问题的理解
- 文件系统原理:如何用1分钟遍历一个100TB的文件?
- 数据库原理:为什么PrepareStatement性能更好更安全?
- Java Web程序的运行时环境到底是怎样的?
- 你真的知道自己要解决的问题是什么吗?
- 如何解决问题
- 经验分享
- GIT的HTTP方式免密pull、push
- 使用xhprof对php7程序进行性能分析
- 微信扫码登录和使用公众号方式进行扫码登录
- 关于curl跳转抓取
- Linux 下配置 Git 操作免登录 ssh 公钥
- Linux Memcached 安装
- php7安装3.4版本的phalcon扩展
- centos7下php7.0.x安装phalcon框架
- 将字符串按照指定长度分割
- 搜索html源码中标签包的纯文本
- 更换composer镜像源为阿里云
- mac 隐藏文件显示/隐藏
- 谷歌(google)世界各国网址大全
- 实战文档
- PHP7安装intl扩展和linux安装icu
- linux编译安装时常见错误解决办法
- linux删除文件后不释放磁盘空间解决方法
- PHP开启异步多线程执行脚本
- file_exists(): open_basedir restriction in effect. File完美解决方案
- PHP 7.1 安装 ssh2 扩展,用于PHP进行ssh连接
- php命令行加载的php.ini
- linux文件实时同步
- linux下php的psr.so扩展源码安装
- php将字符串中的\n变成真正的换行符?
- PHP7 下安装 memcache 和 memcached 扩展
- PHP 高级面试题 - 如果没有 mb 系列函数,如何切割多字节字符串
- PHP设置脚本最大执行时间的三种方法
- 升级Php 7.4带来的两个大坑
- 不同域名的iframe下,fckeditor在chrome下的SecurityError,解决办法~~
- Linux find+rm -rf 执行组合删除
- 从零搭建Prometheus监控报警系统
- Bug之group_concat默认长度限制
- PHP生成的XML显示无效的Char值27消息(PHP generated XML shows invalid Char value 27 message)
- XML 解析中,如何排除控制字符
- PHP各种时间获取
- nginx配置移动自适应跳转
- 已安装nginx动态添加模块
- auto_prepend_file与auto_append_file使用方法
- 利用nginx实现web页面插入统计代码
- Nginx中的rewrite指令(break,last,redirect,permanent)
- nginx 中 index try_files location 这三个配置项的作用
- linux安装git服务器
- PHP 中运用 elasticsearch
- PHP解析Mysql Binlog
- 好用的PHP学习网(持续更新中)
- 一篇写给准备升级PHP7的小伙伴的文章
- linux 安装php7 -系统centos7
- Linux 下多php 版本共存安装
- PHP编译安装时常见错误解决办法,php编译常见错误
- nginx upstream模块--负载均衡
- 如何解决Tomcat服务器打开不了HOST Manager的问题
- PHP的内存泄露问题与垃圾回收
- Redis数据结构 - string字符串
- PHP开发api接口安全验证
- 服务接口API限流 Rate Limit
- php内核分析---内存管理(一)
- PHP内存泄漏问题解析
- 【代码片-1】 MongoDB与PHP -- 高级查询
- 【代码片-1】 php7 mongoDB 简单封装
- php与mysql系统中出现大量数据库sleep的空连接问题分析
- 解决crond引发大量sendmail、postdrop进程问题
- PHP操作MongoDB GridFS 存储文件,如图片文件
- 浅谈php安全
- linux上keepalived+nginx实现高可用web负载均衡
- 整理php防注入和XSS攻击通用过滤