php监听redis哨兵模式

在哨兵模式已经部署好的情况下,如何让php能监听到redis呢?

比如说,在主服务7269端口中断后,7270端口变成主服务,但是在项目代码中,redis的端口号是默认的,是不会变的,所有还是会造成

redis连接不上,从而出现错误。

在写这篇文章前,本人已经查了很多方法。

网上有一种公共的方法,就是下载php-redis扩展,然后使用

$redis->rawCommand('SENTINEL', 'masters');

这个方法来获取redis信息,我不用这个方法是因为我本人通过这个方法只返回了false,可能是我配置或者代码有问题。

于是我自己写了一个方法:

function sentinelPort(){

   try{

       $redis = new \Redis();

       $fileurl = Env::get('config_path') . 'redis.php';

       $config = Rconfig::load($fileurl,'redis');

       $host = $config['host'];

       $port = $config['port'];

       $password = $config['password'];

       $redis->connect($host, $port);

       $redis->auth($password);

       $redis->ping();

       $redisInfo = $redis->info();

       if(is_array($redisInfo)&&isset($redisInfo['role'])&&$redisInfo['role']=='master'){

           return $redis;

       }else{

           throw new \Exception($port.'是从服务器');

       }

   }catch(\Exception $e){

       write_error_log($e);

       $portArr = [7269,7270,7271];//端口号

       $portArr = array_flip($portArr);

       unset($portArr[$port]);

       $newPort = array_rand($portArr,1);

       if(setconfig('redis.php',['port'],[$newPort])){

 return sentinelPort();

       }

   }

}

这个方法是用户获取redis对象的方法,并且当主服务中断后,也是可以重新获取到新的主服务的,不会出现报错。

1、利用try catch来捕捉redis连接错误信息

2、我这个是基于Thinkphp方法写的,把redis的基本信息都存到redis.php配置文件中,当然redis.php是自己创建的。

之所以用这种方法来获取redis信息是因为在哨兵模式下,主服务的端口号会变动,所以redis.php也是要动态修改的。但是

config去取redis.php信息时,总是取到修改之前的信息。

3、redis.php配置文件内容如下:

能用到的参数host,ip地址;port,端口号;password,密码;

4、当主服务中断后,redis连接会出错,就会执行catch中的方法。

write_error_log($e);//记录错误日志,这个方法在https://chengzhigang.cn/index/article/index.html?id=40中提到过。

$portArr;//当前redis的所有端口号;

健值对调,删除当前错误的端口,并且错剩下的端口中随机取出一个来。

setconfig('redis.php',['port'],[7270]);//假设当前随机取到的端口号是7270,然后把7270记入到redis.php配置中,替换原先的7279,

这个是因为Thinkphp5.1不支持更改动态更改配置文件而写的方法,这个是从网上找的。具体方法如下:

function setconfig($file,$pat, $rep){

   /**

    * 原理就是 打开config配置文件 然后使用正则查找替换 然后在保存文件.

    * 传递的参数为2个数组 前面的为配置 后面的为数值.  正则的匹配为单引号  如果你的是分号 请自行修改为分号

    * $pat[0] = 参数前缀;  例:   default_return_type

      $rep[0] = 要替换的内容;    例:  json

    */

   if (is_array($pat) and is_array($rep)) {

       for ($i = 0; $i < count($pat); $i++) {

           $pats[$i] = '/\'' . $pat[$i] . '\'(.*?),/';

           $reps[$i] = "'". $pat[$i]. "'". "=>" . "'".$rep[$i] ."',";

       }

       $fileurl = Env::get('config_path') . $file;

       $string = file_get_contents($fileurl); //加载配置文件

       $string = preg_replace($pats, $reps, $string); // 正则查找然后替换

       file_put_contents($fileurl, $string); // 写入配置文件

       return true;

} else {

       return flase;

   }

}

然后重新执行获取redis对象的方法。

5、当redis连接成功后,我们需要知道它连接的是不是主服务器,所以需要

$redis->info();这个方法来判断它是否是主服务器,如果role是master,那就直接返回redis对象。

如果不是,就返回错误,重新跑这个逻辑。

博客地址:观海听潮博客

你可能感兴趣的:(php监听redis哨兵模式)