梦入琼楼寒有月,行过石树冻无烟

Laravel Redis&Command

Laravel 可以通过 Command 以及相关方法来讲 Redis 进行存储并映射到 MySQL 数据库中,通过 composer require predis/predis 命令来安装 Laravel Redis 的扩展,前提是在 PHP 具有 redis 扩展。

1
查看是否具有 Redis 的扩展我们可以通过 ```php -m``` 的命令来进行查看,如果没有我们可以通过集成环境或者直接到 pecl 所提供的 PHP 扩展下载站 [PECL](https://pecl.php.net/package/redis)中来进行下载,可以通过 ```php --verion``` 来查看当前的 PHP 类型和当前环境信息等。

按照官方文档的示例,在安装完 Redis 扩展后,我们可以在 .env 文件中修改 REDIS_PASSWORD 等配置,此外,也可以建立多个 Redis 链接,但前提是在 config/database.php 中进行一定的配置。

我们也可以在 config/database.php 中配置 Redis 的相关的账号信息,比如账号密码和 Key 名等,都可以在 redis 中进行配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
'redis' => [  

'client' => env('REDIS_CLIENT', 'phpredis'),

'options' => [
'cluster' => env('REDIS_CLUSTER', 'redis'),
'prefix' => env('REDIS_PREFIX', Str::slug(env('APP_NAME', 'laravel'), '_').'_database_'),
],

'default' => [
'url' => env('REDIS_URL'),
'host' => env('REDIS_HOST', '127.0.0.1'),
'password' => env('REDIS_PASSWORD', 'redis'),
'port' => env('REDIS_PORT', '6379'),
'database' => env('REDIS_DB', '14'),
],

'cache' => [
'url' => env('REDIS_URL'),
'host' => env('REDIS_HOST', '127.0.0.1'),
'password' => env('REDIS_PASSWORD', null),
'port' => env('REDIS_PORT', '6379'),
'database' => env('REDIS_CACHE_DB', '15'),
],
],

之后,我们也可以在 app/Http/Controllers/ 中定义一个名为 RedisController.php 的控制器,引入 Illuminate\Support\Facades\Redis 扩展并作为 App\Http\Controllers\Controller 的延伸,定义两个基础的 Redis 存储方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<?php  

namespace App\Http\Controllers;

use Illuminate\Support\Facades\Redis;

class RedisController
{
public function set() {
Redis::set('key','hello,redis!');
}

public function get() {
$name = Redis::get('key');
var_dump($name);
}

}

之后,为了使得方法的正常执行,我们还需要通过路由来定义,在 routes/web.php 中写入:

1
2
Route::get('/get', 'RedisController@get');  
Route::get('/set', 'RedisController@set');

最后,我们就可以通过 http://127.0.0.1:8000/sethttp://127.0.0.1:8000/get 来进行对 Redis 的 Set 和 Get 的操作。

同样的 Laravel Predis 支持了 Redis 的命令,我们可以通过阅读 Redis 官方文档Redis 速查表 来配合 Laravel 来进行实现对 Redis 的操作。

对于 hMset 类型的插入,我们可以通过使用 Redis:hMset 的方式来进行插入,如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<?php  

namespace App\Http\Controllers;

use Illuminate\Support\Facades\Redis;

class RedisController
{
public function set() {
$key = 'HSET';
$value= [
'id' => '1',
'name' => 'test',
'mess' => 'This is test'
];
Redis::hMset($key,$value);
}

}

Command & Job

Redis 通常是一个缓存服务,主要用于作为中间层进行,我们可以通过使用 Reids 配合 Laravel 作为队列,通过 Laravel 队列所支持的 Command 来将 Redis 信息提取后映射到 MySQL 或其他数据库中。

在本文中,我们主要理解 Laravel 队列以及 Job(工作线程) 和 Command 的使用,同样的我们也可以通过 Controller 来进行调用 Job。

我们可以使用 Laravel artisan 命令来创建一个工作线程,并命名为 RedisJobTest

1
php artisan make:job RedisJobTest

创建完后他会在 app/Jobs/ 目录下生成一个 RedisJobTest.php 的 PHP 类,我们需要在里面进行编辑:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
<?php  

namespace App\Jobs;

use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\Redis;

class RedisJobTest implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

private $key;

/**
* Create a new job instance. * * @return void
*/ public function __construct(string $key)
{
// key
$this->key = $key;
}

/**
* Execute the job. * * @return void
*/ public function handle()
{
$llen = Redis::connection()->LLEN($this->key);
$lineToint = (int)$llen;

return dump($lineToint);
}
}

之后我们还需要创建一个命令,用于调用该队列,同样的我们也使用 Artisan 命令来进行创建:

1
php artisan make:command RedisJobCommand

然后在 app/Console/Commands/RedisJobCommand.php 下,来调用我们的工作线程:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
<?php  

namespace App\Console\Commands;

use App\Jobs\RedisJobTest;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Log;

class RedisJobCommand extends Command
{
/**
* The name and signature of the console command. * * @var string
*/ protected $signature = 'command:redis_job_test';

/**
* The console command description. * * @var string
*/ protected $description = 'Command description';

/**
* Create a new command instance. * * @return void
*/ public function __construct()
{
parent::__construct();
}

/**
* Execute the console command. * * @return mixed
*/ public function handle()
{
echo 'Redis run start';

RedisJobTest::dispatch('SET')
->delay(now()->addMinutes(1));

echo 'Redis run end';
}
}

在上述的 Code 中,我们主要通过 $signature 类型来定义一个命令,同样的我们也可以在 $description 添加该命令的方法和描述,最后在 handle 方法中写入 RedisJobTest::dispatch 来调用 RedisJobTest 工作线程。

1
通过上述的流程演示,我们可以通过工作线程来实现 Redis 锁,在 Laravel Job 中的 ```handle()``` 方法下,添加 Redis 锁即可:
1
2
3
4
5
6
7
Redis::throttle('key')->allow(10)->every(60)->then(function () {
// 任务逻辑...
}, function () {
// 无法获得锁...

return $this->release(10);
});

上述 code 中,主要 Redis 中的频率限制,也就是限制指定类型每 60 秒只执行10次,如果没有锁,那么一般情况下将会导致任务被放回队列使其被重试。

在大量的数据涌入的情况下可能会导致数据库的崩溃从而出现错误,因此我们需要使用到 Redis 锁,这些在 Laravel 中主要被称之为频率限制,我们可以翻阅官方文档来检索我们需要的 队列 | 综合话题 |《Laravel 6 中文文档 6.x》| Laravel China 社区 (learnku.com)

在官方文档中,我们也可以在调用队列的时候对其进行延迟分发,这主要通过 delay 方法来进行实现,详细的可以查阅官方文档的描述 队列 | 综合话题 |《Laravel 6 中文文档 6.x》| Laravel China 社区 (learnku.com)

⬅️ Go back