Rumah  >  Soal Jawab  >  teks badan

Amalan Laravel menggunakan Redis untuk mengehadkan semasa hanya dalam persekitaran pengeluaran

Latar belakang

Secara lalai, Laravel menyediakan dua perisian tengah untuk mengehadkan kadar (mendikit):

\Illuminate\Routing\Middleware\ThrottleRequests::class
\Illuminate\Routing\Middleware\ThrottleRequestsWithRedis::class

Seperti yang dinyatakan dalam dokumentasi, jika anda menggunakan Redis sebagai pemacu cache, anda boleh menukar pemetaan dalam Kernel.php seperti ini:

/**
 * 应用程序的中间件别名。
 *
 * 别名可用于将中间件方便地分配给路由和组,而不是使用类名。
 *
 * @var array<string, class-string|string>
 */
protected $middlewareAliases = [
    // ...
    'throttle' => \Illuminate\Routing\Middleware\ThrottleRequestsWithRedis::class
    // ...
];

Soalan

Masalahnya ialah perkara di atas tidak dinamik tetapi bergantung kepada persekitaran. Contohnya, dalam stagingproduction环境中,我使用Redis,但在我的localdevelopmentpersekitaran saya, saya tidak menggunakan Redis.

Penyelesaian yang mungkin

Terdapat penyelesaian kotor yang jelas, seperti ini (Kernel.php):

/**
 * 应用程序的中间件别名。
 *
 * 别名可用于将中间件方便地分配给路由和组,而不是使用类名。
 *
 * @var array<string, class-string|string>
 */
protected $middlewareAliases = [
    // ...
    'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class
    // ...
];

/**
 * 创建一个新的HTTP内核实例。
 *
 * @param  \Illuminate\Contracts\Foundation\Application  $app
 * @param  \Illuminate\Routing\Router  $router
 * @return void
 */
public function __construct(Application $app, Router $router)
{
    if ($app->environment('production')) {
        $this->middlewareAliases['throttle'] = \Illuminate\Routing\Middleware\ThrottleRequestsWithRedis::class;
    }

    parent::__construct($app, $router);
}

Adakah terdapat cara "standard" untuk memilih perisian tengah yang berkaitan secara dinamik tanpa mengatasi Kernel构造函数的情况下实现这一点?基本上,我希望我的应用程序可以根据环境是否设置为production(或者默认缓存存储设置为redis).

Kemas kini

Penyelesaian di atas tidak berfungsi kerana kernel diakses sebelum aplikasi dibut, jadi persekitaran tidak tersedia pada masa ini. Penyelesaian lain yang saya cari sekarang ialah melanjutkan kelas asas ThrottleRequests supaya kelas yang berkaitan boleh dipanggil secara dinamik.

P粉541565322P粉541565322257 hari yang lalu354

membalas semua(1)saya akan balas

  • P粉043432210

    P粉0434322102024-01-11 16:27:49

    Selepas banyak penyelidikan dan ujian, saya sampai pada kesimpulan bahawa RouteServiceProvider中动态设置throttlemiddleware adalah penyelesaian terbaik, kodnya adalah seperti berikut:

    class RouteServiceProvider extends ServiceProvider
    {
        /**
         * 启动任何应用程序服务。
         *
         * @return void
         */
        public function boot(): void
        {
            $this->registerThrottleMiddleware();
        }
    
        /**
         * 注册用于限制请求的中间件。
         *
         * @return void
         */
        private function registerThrottleMiddleware(): void
        {
            $router = app()->make('router');
    
            $middleware = config('cache.default') !== 'redis'
                ? \Illuminate\Routing\Middleware\ThrottleRequests::class
                : \Illuminate\Routing\Middleware\ThrottleRequestsWithRedis::class;
    
            $router->aliasMiddleware('throttle', $middleware);
        }
    }

    balas
    0
  • Batalbalas