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秒會執行一次健康檢查。