| 
16 | 16 | use Hyperf\Contract\StdoutLoggerInterface;  | 
17 | 17 | use Hyperf\Pool\Connection as BaseConnection;  | 
18 | 18 | use Hyperf\Pool\Exception\ConnectionException;  | 
 | 19 | +use Hyperf\Redis\Exception\InvalidRedisConnectionException;  | 
19 | 20 | use Psr\Container\ContainerInterface;  | 
20 | 21 | 
 
  | 
21 | 22 | /**  | 
@@ -193,25 +194,37 @@ protected function createRedisSentinel(): \Redis  | 
193 | 194 |             $retryInterval = $this->config['retry_interval'] ?? 0;  | 
194 | 195 |             $readTimeout = $this->config['sentinel']['read_timeout'] ?? 0;  | 
195 | 196 |             $masterName = $this->config['sentinel']['master_name'] ?? '';  | 
 | 197 | +            shuffle($nodes);  | 
196 | 198 | 
 
  | 
197 |  | -            $host = '';  | 
198 |  | -            $port = 0;  | 
 | 199 | +            $host = null;  | 
 | 200 | +            $port = null;  | 
199 | 201 |             foreach ($nodes as $node) {  | 
200 |  | -                [$sentinelHost, $sentinelPort] = explode(':', $node);  | 
201 |  | -                $sentinel = new \RedisSentinel(  | 
202 |  | -                    $sentinelHost,  | 
203 |  | -                    intval($sentinelPort),  | 
204 |  | -                    $timeout,  | 
205 |  | -                    $persistent,  | 
206 |  | -                    $retryInterval,  | 
207 |  | -                    $readTimeout  | 
208 |  | -                );  | 
209 |  | -                $masterInfo = $sentinel->getMasterAddrByName($masterName);  | 
210 |  | -                if (is_array($masterInfo) && count($masterInfo) >= 2) {  | 
211 |  | -                    [$host, $port] = $masterInfo;  | 
212 |  | -                    break;  | 
 | 202 | +                try {  | 
 | 203 | +                    [$sentinelHost, $sentinelPort] = explode(':', $node);  | 
 | 204 | +                    $sentinel = new \RedisSentinel(  | 
 | 205 | +                        $sentinelHost,  | 
 | 206 | +                        intval($sentinelPort),  | 
 | 207 | +                        $timeout,  | 
 | 208 | +                        $persistent,  | 
 | 209 | +                        $retryInterval,  | 
 | 210 | +                        $readTimeout  | 
 | 211 | +                    );  | 
 | 212 | +                    $masterInfo = $sentinel->getMasterAddrByName($masterName);  | 
 | 213 | +                    if (is_array($masterInfo) && count($masterInfo) >= 2) {  | 
 | 214 | +                        [$host, $port] = $masterInfo;  | 
 | 215 | +                        break;  | 
 | 216 | +                    }  | 
 | 217 | +                } catch (\Throwable $exception) {  | 
 | 218 | +                    $logger = $this->container->get(StdoutLoggerInterface::class);  | 
 | 219 | +                    $logger->warning('Redis sentinel connection failed, caused by ' . $exception->getMessage());  | 
 | 220 | +                    continue;  | 
213 | 221 |                 }  | 
214 | 222 |             }  | 
 | 223 | + | 
 | 224 | +            if ($host === null && $port === null) {  | 
 | 225 | +                throw new InvalidRedisConnectionException('Connect sentinel redis server failed.');  | 
 | 226 | +            }  | 
 | 227 | + | 
215 | 228 |             $redis = $this->createRedis($host, $port, $timeout);  | 
216 | 229 |         } catch (\Throwable $e) {  | 
217 | 230 |             throw new ConnectionException('Connection reconnect failed ' . $e->getMessage());  | 
 | 
0 commit comments