zoukankan      html  css  js  c++  java
  • redis哨兵模式下主从切换后,php实现自动切换

      redis的哨兵模式,在主服务器挂掉后,会通过选举将对应的从服务器切换为主服务器,以此来达到服务的高可用性。

      在业务层面如果主从做了切换可能相对应的服务器IP地址会发生改变,这样会带来程序的的正常运行。为了不影响其业务,会考虑使用VIP去实现IP的飘逸,但是在部分情况下,虚拟机并不支持VIP,这样就无法保证业务的正常运行。索引在此情况下,通过业务本身来实现连接新的主的IP。本文主要以PHP为例,相关代码如下

    <?php
    
    class SRedis
    {
    
        /**
         * 哨兵地址,支持多哨兵地址
         * @var array
         * eg:  [ [ 'host' => '127.0.0.1' , 'port' => 26379 ] ]
         */
        private $_sentinelAddr = [];
    
        private $_sentinelConn = null;
    
        private $_timeout = 10; //超时时间
    
        private $_masterName = 'mymaster'; //主节点名称
    
        private static $_handle = []; //存放redis连接实例
    
        public function __construct(array $iplist, string $masterName = null)
        {
            $this->_sentinelAddr = $iplist;
            $masterName !== null && $this->_masterName = $masterName;
            $this->_getSentinelConn();
        }
    
        /**
         * 获取redis主节点的实例
         * @return bool|Redis
         * @throws Exception
         */
        public function getInstansOf()
        {
            $masterInfo = $this->getMasterInfo();
            if ($masterInfo) {
                $instansof = $this->_connection($masterInfo[0], $masterInfo[1], $this->_timeout);
                return $instansof;
            }
            return false;
        }
    
        /**
         * 获取主节点的ip地址
         * @return array
         */
        public function getMasterInfo()
        {
            $masterInfo = [];
            if ($this->_sentinelConn != null) {
                $masterInfo = $this->_sentinelConn->rawcommand("sentinel", 'get-master-addr-by-name', $this->_masterName);
            }
            return $masterInfo;
    
        }
    
        /**
         * 设置哨兵连接句柄
         */
        private function _getSentinelConn()
        {
            if (is_array($this->_sentinelAddr) && $this->_sentinelAddr) {
                $this->_sentinelConn = $this->_RConnect($this->_sentinelAddr);
            }
        }
    
        /**
         * 获取redis句柄(如果是多主机,保证连接的是可用的哨兵服务器)
         * @param array $hosts
         * @return null|Redis
         */
        private function _RConnect(array $hosts)
        {
            $count = count($hosts);
            $redis = null;
            if ($count == 1) {
                $this->_connection($hosts[0]['host'], $hosts[0]['port'], $this->_timeout);
            } else {
                $i = 0;
                while ($redis == null && $i < $count) {
                    $redis = $this->_connection($hosts[$i]['host'], $hosts[$i]['port'], $this->_timeout);
                    $i++;
                }
            }
            return $redis;
        }
    
        /**
         * redis 连接句柄
         * @param string $host
         * @param int $port
         * @param int $timeout
         * @return null|Redis
         */
        private function _connection(string $host, int $port, int $timeout)
        {
            if (isset(self::$_handle[$host . ':' . $port])) {
                return self::$_handle[$host . ':' . $port];
            }
            try {
                $redis = new Redis();
                $redis->connect($host, $port, $timeout);
                self::$_handle[$host . ':' . $port] = $redis;
            } catch (Exception $e) {
                $redis = null;
            }
            return $redis;
        }
    }
    $hosts = [
        [
            'host' => '127.0.0.1',
            'port' => 26381
        ],
        [
            'host' => '127.0.0.1',
            'port' => 26380
        ]
    ];
    $masterName = 'mymaster';
    $sredis = new SRedis($hosts, $masterName);
    $masterRedis = $sredis->getInstansOf();
    if ($masterRedis) {
        print_r($masterRedis->hgetall("iplist"));
    } else {
        echo "redis 服务器连接失败";
    }
    
    
    
     
  • 相关阅读:
    Java的快速失败和安全失败
    Java RMI与RPC的区别
    Java动态代理之JDK实现和CGlib实现(简单易懂)
    JVM——字节码增强技术简介
    Linux内存分配机制之伙伴系统和SLAB
    操作系统动态内存管理——malloc和free的工作机制
    Java中的Map
    Java的PriorityQueue
    Java中的List
    Java中的Set
  • 原文地址:https://www.cnblogs.com/tm2015/p/11313434.html
Copyright © 2011-2022 走看看