亚洲精品久久久中文字幕-亚洲精品久久片久久-亚洲精品久久青草-亚洲精品久久婷婷爱久久婷婷-亚洲精品久久午夜香蕉

更多QQ空间微信QQ好友腾讯朋友复制链接
您的位置:首頁/技術文章
文章詳情頁

詳解PHP解決守護進程Redis假死

【字号: 作者:豬豬瀏覽:14日期:2022-09-07 08:15:24
目錄一、一個簡單的守護進程示例二、一個不再假死(偽活)的 Redis 常駐進程示例一、一個簡單的守護進程示例

<?php$redis = new Redis();$redis->connect(’localhost’, 6379);$redis->auth(’xxxxx’); // Redis 密碼如果沒有設置為空字符串。$redis->select(1);$queueKey = ’redis_queue_services_key’; // 業務數據隊列。$queueIngKey = ’redis_queue_services_ing_key’; // 處理中的隊列。try { while (true) {$element = $redis->bRPopLPush($queueKey, $queueIngKey, 60);if ($element) { $data = json_decode($element, true); /** * ...... 此處省略業務邏輯 ...... * */} else { usleep(100000); // 睡眠 0.1 秒。} }} catch (Exception $e) { exit('Error:{$e->getMessage()}');}

這段代碼我們很容易看懂。

它就是通過Redis的阻塞方法bRPopLPush循環從 Redis 隊列中取出數據并處理。如果沒有取到數據就休眠一秒。之所以休眠是為了保證 CPU 能得到充分的利用。因為,我們已經使用了阻塞方法阻塞 60 秒。所以,這個位置休眠與否并不重要。

當我們的業務出現任何錯誤,我們通過try catch進行異常捕獲然后將錯誤信息直接輸出并退當前腳本。

博主寒冰第一次編寫常駐后臺運行的守護進程時,就是如上這種方式寫的代碼。結果,這段代碼運行到 30s 的時候報錯了。提示我們 socket 流超時。于是我在這個腳本頭部加了如下代碼:

ini_set(’default_socket_timeout’, -1);

這樣我們的PHP就不會主動段掉我們與 Redis 的 socket 連接了。

但是,好景不長。過了一段時間,大概半個月吧。運維同學告訴我 Redis 隊列的數據出現了未消費的情況。然后,我查看了消費日志。的確沒有產生新的消費日志。因為我有一個習慣,每個消費消費的時候都會把成功消費的日志寫到文件中。消費失敗的也寫入日志文件中。這樣,我就知道失敗的具體原因。

但是,這次我真的沒有發現有任何的錯誤發生。

常駐后臺進程處理存活狀態。并沒有變成孤兒進程。 常駐后臺進程內存也沒有出現泄漏。 系統 CPU/內存 資源都處理正在狀態。 系統打開的句柄資源也是低消狀態。 帶寬也處理低消狀態。 其它常駐進程也處理正常消費的工作狀態。也就排除了 Redis 故障的問題。

我當時也懷疑過是不是像MySQL一樣常時間連接不進行任何操作,服務器端會主動斷開連接。但是,MySQL 服務器端主動段掉連接會提示:MySQL server has gone away的錯誤。但是,我們的 Redis 服務器端沒有給我們報任何錯誤信息呀。

我們公司用的是阿里云的 Redis 產品。我懷疑是不是 Redis 版本太低造成的這個隱性 BUG。于是,我們將阿里云的 Redis 服務升級到了阿里云支持的最新版本。

結果還是失敗了。我們的 Redis 還是假死了。或者說我們的 Redis 處于偽活狀態。

你認為 Redis 活著,其實它早已經死了。你認為 Redis 死了,但是它卻沒有死亡的特征。

最后,我冷靜下來。

我假定此時的 Redis 已經死了。只是沒有告訴客戶端而已。那么我只需要每次檢測一下 Redis 連接是否存活就好了。

于是,我翻看了 Redis 的 API。發現它提供了一個ping()的方法來檢測連接是否存活。

二、一個不再假死(偽活)的 Redis 常駐進程示例

<?php$redis = new Redis();$redis->connect(’localhost’, 6379);$redis->auth(’xxxxx’); // Redis 密碼如果沒有設置為空字符串。$redis->select(1);$queueKey = ’redis_queue_services_key’; // 業務數據隊列。$queueIngKey = ’redis_queue_services_ing_key’; // 處理中的隊列。try { while (true) {$element = $redis->bRPopLPush($queueKey, $queueIngKey, 60);if ($element) { $data = json_decode($element, true); /** * ...... 此處省略業務邏輯 ...... * */} else { $pong = $redis->ping(); if ($pong != ’+PONG’) {throw new Exception(’Redis ping failure!’, 500); } usleep(100000); // 睡眠 0.1 秒。} }} catch (Exception $e) { exit('Error:{$e->getMessage()}');}

通過代碼對比,我們在第一版代碼的基礎上加了如下代碼:

$pong = $redis->ping();if ($pong != ’+PONG’) { throw new Exception(’Redis ping failure!’, 500);}

我們向 Redis 服務器發送ping的時候,服務器會返回+PONG字符串。當然,這個是 Redis 擴展封裝過的方法。真正的 ping 是不會有 + 號的。

當我們每次 ping 的時候,Redis 服務器就會認為我們的 Redis 客戶端連接處于存活狀態。就不會斷掉我們的連接了。

把代碼進行改造之后,假死頭痛的問題再也沒出現了。

以上就是詳解PHP解決守護進程Redis假死的詳細內容,更多關于PHP解決守護進程Redis假死的資料請關注好吧啦網其它相關文章!

標簽: PHP
相關文章:
主站蜘蛛池模板: 精品欧美一区二区vr在线观看 | 狠狠色综合久久婷婷 | 日本精品久久久久中文字幕 1 | 久青草视频97国内免费影视 | 国产一区二区三区不卡观 | 国产专区一区 | 国产精品久久久久三级 | 中文字幕在线观看日韩 | 欧美一级中文字幕 | 国产aa毛片 | 日韩免费在线播放 | 成人国产欧美精品一区二区 | 国产亚洲精品久久久久久小说 | 国产一级淫片免费大片 | 欧美做爰gif动态图一区二区 | 微拍秒拍99福利精品小视频 | 精品一本久久中文字幕 | 欧美久久一区二区三区 | 麻豆一区二区免费播放网站 | 33333在线亚洲 | 国内自拍视频在线播放 | 男人黄女人色视频在线观看 | 亚洲精品久久久久久久777 | xnxx 美女18| 在线观看的毛片 | 日韩 欧美 亚洲 中文字幕 | 一级做a爰片久久毛片图片 一级做a爰片久久毛片看看 | 欧美国产亚洲精品高清不卡 | 日韩欧美色综合 | 免费看日日麻批免费视频播放 | 久草视频2 | 亚洲国产美女精品久久 | 在线观看国产一区二区三区 | 国产精品嫩草影院在线播放 | 亚洲国语在线视频手机在线 | 国产成年网站v片在线观看 国产成版人视频网站免费下 | 日本免费一级 | 国产精品久久久久久久久齐齐 | 一区二区三区欧美日韩 | 天堂影院jav成人天堂免费观看 | 国产精品一区二区无线 |