@@ -44,6 +44,13 @@ class RedisConnection extends BaseConnection implements ConnectionInterface
4444 'name ' => null ,
4545 'seeds ' => [],
4646 ],
47+ 'sentinel ' => [
48+ 'enable ' => false ,
49+ 'master_name ' => '' ,
50+ 'nodes ' => [],
51+ 'persistent ' => '' ,
52+ 'read_timeout ' => 0 ,
53+ ],
4754 'options ' => [],
4855 ];
4956
@@ -93,15 +100,19 @@ public function reconnect(): bool
93100 $ db = $ this ->config ['db ' ];
94101 $ timeout = $ this ->config ['timeout ' ];
95102 $ cluster = $ this ->config ['cluster ' ]['enable ' ] ?? false ;
103+ $ sentinel = $ this ->config ['sentinel ' ]['enable ' ] ?? false ;
96104
97105 $ redis = null ;
98- if ($ cluster !== true ) {
99- $ redis = new \Redis ();
100- if (! $ redis ->connect ($ host , $ port , $ timeout )) {
101- throw new ConnectionException ('Connection reconnect failed. ' );
102- }
103- } else {
104- $ redis = $ this ->createRedisCluster ();
106+ switch (true ) {
107+ case $ cluster :
108+ $ redis = $ this ->createRedisCluster ();
109+ break ;
110+ case $ sentinel :
111+ $ redis = $ this ->createRedisSentinel ();
112+ break ;
113+ default :
114+ $ redis = $ this ->createRedis ($ host , $ port , $ timeout );
115+ break ;
105116 }
106117
107118 $ options = $ this ->config ['options ' ] ?? [];
@@ -178,4 +189,55 @@ protected function retry($name, $arguments, \Throwable $exception)
178189
179190 return $ result ;
180191 }
192+
193+ protected function createRedisSentinel ()
194+ {
195+ try {
196+ $ nodes = $ this ->config ['sentinel ' ]['nodes ' ] ?? [];
197+ $ timeout = $ this ->config ['timeout ' ] ?? 0 ;
198+ $ persistent = $ this ->config ['sentinel ' ]['persistent ' ] ?? null ;
199+ $ retryInterval = $ this ->config ['retry_interval ' ] ?? 0 ;
200+ $ readTimeout = $ this ->config ['sentinel ' ]['read_timeout ' ] ?? 0 ;
201+ $ masterName = $ this ->config ['sentinel ' ]['master_name ' ] ?? '' ;
202+
203+ $ host = '' ;
204+ $ port = 0 ;
205+ foreach ($ nodes as $ node ) {
206+ [$ sentinelHost , $ sentinelPort ] = explode (': ' , $ node );
207+ $ sentinel = new \RedisSentinel (
208+ $ sentinelHost ,
209+ intval ($ sentinelPort ),
210+ $ timeout ,
211+ $ persistent ,
212+ $ retryInterval ,
213+ $ readTimeout
214+ );
215+ $ masterInfo = $ sentinel ->getMasterAddrByName ($ masterName );
216+ if (is_array ($ masterInfo ) && count ($ masterInfo ) >= 2 ) {
217+ [$ host , $ port ] = $ masterInfo ;
218+ break ;
219+ }
220+ }
221+ $ redis = $ this ->createRedis ($ host , $ port , $ timeout );
222+ } catch (\Throwable $ e ) {
223+ throw new ConnectionException ('Connection reconnect failed ' . $ e ->getMessage ());
224+ }
225+
226+ return $ redis ;
227+ }
228+
229+ /**
230+ * @param string $host
231+ * @param int $port
232+ * @param float $timeout
233+ * @return \Redis
234+ */
235+ protected function createRedis ($ host , $ port , $ timeout )
236+ {
237+ $ redis = new \Redis ();
238+ if (! $ redis ->connect ((string ) $ host , (int ) $ port , $ timeout )) {
239+ throw new ConnectionException ('Connection reconnect failed. ' );
240+ }
241+ return $ redis ;
242+ }
181243}
0 commit comments