In my situation, I face a problem with redis, our redis service(RDS) is unstable with unknown problem, but I need to solve consistency service and zero-downtime, so on my first solve problem that I do switch service in my application.

Here is my thinking steps:

  1. Redis service needs to bind container by singlton
  2. Trying to connect Master redis, if it’s failed, rebinding second redis service.
  3. No middleware for now, it should be in service provider.
//database.php
'redis' => [
        'client' => 'predis',
        'default' => [
            'host' => env('REDIS_HOST', '127.0.0.1'),
            'password' => env('REDIS_PASSWORD', null),
            'port' => env('REDIS_PORT', 6379),
            'database' => 0,
        ],
    ],

    'redis_backup' => [
        'client' => 'predis',
        'default' => [
            'host' => env('REDIS_BACKUP_HOST', '127.0.0.1'),
            'password' => env('REDIS_BACKUP_PASSWORD', null),
            'port' => env('REDIS_BACKUP_PORT', 6379),
            'database' => 0,
        ],
    ],

As we know, redis service provider by default is defered, so we need to put trying connection and rebinding in boot method.

<?php

namespace App\Providers;

use Illuminate\Redis\RedisManager;
use Illuminate\Support\Arr;
use Illuminate\Support\ServiceProvider;
use Throwable;

class BackupRedisServiceProvider extends ServiceProvider
{
    public function boot()
    {
            try {
                // ping redis service.
                $this->app['redis']->get(1);
            } catch (Throwable $e) { 
                // we don't care what exceptions, just use backup redis keeping the connection and operations.
                // enabled backup redis.
                $this->app->singleton('redis', function ($app) {
                    $config = $app->make('config')->get('database.redis_backup');

                    return new RedisManager(Arr::pull($config, 'client', 'predis'), $config);
                });

                $this->app->bind('redis.connection', function ($app) {
                    return $app['redis']->connection();
                });
            }
        }
    }
}

I thought it’s a attempt solution for me, but as you know, we need to solve service unstable and exceptions, this is a other story.