## 場景要求
客戶端調用服務器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攻擊通用過濾