一分一毛也是爱

微信

微信

支付宝

支付宝

观海听潮

观海听潮博客

登录
还没有账号?去注册
观海听潮

观海听潮博客

注册
  • 欢迎来自美国弗吉尼亚州的访客,您好!
×

我的名片

网名:观海听潮

职业:PHP开发工程师

现居:山东省-青岛市

Email:1256699215@qq.com

网站统计

  • 观海听潮•博客
  • 54篇
  • 145条
  • 22689次
  • 300次
  • 美国弗吉尼亚州

您现在的位置是:首页  > 技术杂谈  > redis  > php  > Thinkphp Thinkphp

观海听潮

php监听redis哨兵模式

观海听潮 120天前 1097 0条评论
摘要
php来监听redis主从服务的变化,从而自动去更改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配置文件内容如下:

截图 (22).png

能用到的参数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对象。

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


转载请注明: 观海听潮博客

本文地址:https://chengzhigang.cn/al/48.html

讨厌 (0)
微博logo QQ空间logo QQlogo 豆瓣logo 人人logo 百度贴吧logo 有道云笔记logo

文章评论

表情表情
×
图片图片

评论列表