Redis pub/sub 連線一段時間出現訂閱失敗的處理方式
Redis subscribe 在訂閱一段時間可能失敗的情況有兩種, 1. 啟動沒多久就發生超時, 2. 長期才發生的連結斷開
在實際開發過程,兩種方式情境都可以同時設置,處理方式如下:
超時狀況處理方式
在 PHP 使用 Redis Pub/Sub 很容易遇到超時問題:
例如,
<?php
use \Redis;
...
$redis = new Redis();
$redis->connect(getenv('REDIS_SERVER_HOST'), getenv('REDIS_SERVER_PORT'),0);
$redis->select(8);
$redis->subscribe(array('order-offset' , 'order-done'), function($instance, $channelName, $message){
//treatment...
}
});
當 sub 端連線一段時間沒有收到回應,就會爆出以下錯誤:
Worker[8089] process terminated
worker[none:8089] exit with status 64000
RedisException: read error on connection to 0.0.0.0:6379 in...
可能的原因有 php_stream_get_line
解決的方式,有以下兩種:
方法一、關閉PHP超時
如果要關閉PHP超時,可能要再確定是否會影響PHP其他程序,例如 file_get_content
php
CVT2HUGO: 與 ```bufstart```
ini_set('default_socket_timeout', -1);
CVT2HUGO: 返回NULL
方法二、關閉 redis 超時
單獨關閉 redis 超時
<?php
$redis->setOption(Redis::OPT_READ_TIMEOUT, -1);
<?php
use \Redis;
...
$redis = new Redis();
$redis->connect(getenv('REDIS_SERVER_HOST'), getenv('REDIS_SERVER_PORT'),0);
$redis->setOption(Redis::OPT_READ_TIMEOUT, -1);
$redis->select(8);
$redis->subscribe(array('order-offset' , 'order-done'), function($instance, $channelName, $message){
//treatment...
}
});
訂閱失敗處理方式
有時啟動 redis 幾個月之後,會突然遇到無法連線的問題,
可以將 redis.conf 的 tcp-keepalive 設定為 60 (預設為 0 ,表示不檢查心跳)
每 60秒會執行一次健康檢查。