olegkravec/laravel-redis-router

此包的最新版本(1.2.5)没有可用的许可证信息。

Laravel Redis Pub/Sub 路由器

1.2.5 2021-02-05 10:29 UTC

This package is auto-updated.

Last update: 2024-09-05 18:29:13 UTC


README

安装

composer require olegkravec/laravel-redis-router

通用

laravel-redis-router 是 Laravel MVC 架构的类似实现,用于处理和发送 Redis Pub/Sub 消息

它是如何工作的?

例如,你有两个不同的服务,称为服务 A 和服务 B,这两个服务都是 REST API 应用程序,但服务 B 必须从服务 A 获取数据。有几种不同的方式可以接收数据,例如 HTTP API 请求,但在高负载项目中,HTTP 请求速度太慢,无法在服务之间传输数据,因此我们需要更好的解决方案。

Redis Pub/Sub 机制允许订阅频道,并向所有订阅者发布消息,所有订阅者都将实时接收数据。

我们将做一个例子,其中服务 A 将订阅频道 users:* 并接收所有请求,并将它们发送回响应频道。服务 B 将请求一些特定的数据(用户)。

步骤 1 - 注册服务 A

要启动 laravel-redis-router,我们应该运行: php artisan listen:service users

这意味着服务 A 将订阅 {users} 频道。

步骤 2 - 服务 A 的控制器

php artisan make:controller UserRedisController

创建模式: {SERVICE_NAME}RedisController 例如:对于通知服务,我们必须注册 NotificationRedisController... 例如...

步骤 3 - 实现 Service A 的第一个方法

namespace App\Http\Controllers;

use App\Models\User;
use Illuminate\Support\Collection;
use OlegKravets\LaravelRedisService\Controllers\RedisCommandController;

class UserRedisController extends RedisCommandController
{
    protected static $bind_model = User::class;

    public static function test(string $data) : Collection {
        return new Collection(['ok!', "key" => $data . " World"]);
    }
}

首先,你必须知道:每个控制器都可以绑定到模型(Eloqument),这允许从服务 B 直接通过呈现模型从数据库请求数据

我们实现了 test 方法,它有一个名为 $data 的参数,参数没有限制,你可以声明你需要的任何数量的参数,也可以是任何 基本 类型。

*Redis 控制器必须始终返回集合

步骤 4 - 从服务 B 请求数据

请求控制器的函数

$out = new OutboundStream();
    $out->request("users:*", static function($response) {
        echo "Response is: $response";
    }, "test", "Hello");

在你的控制台你将看到: Response is: {'0':"ok!", "key": "Hello World"}

响应是包含你的数据的 JSON 对象。

直接从数据库请求数据

$out = new OutboundStream();
    $out->request("users:*", static function($response) {
        $user = json_decode($response);
        echo "Response is: " . $user->name;
    }, 'find', 1);

在你的控制台你将看到: Response is: Oleg

响应是包含你的数据的 JSON 对象。

Redis 监视器中的样子

SERVICE A - "PSUBSCRIBE" "users:*"
SERVICE B - "PSUBSCRIBE" "users:322d3a41-c34c-46fe-aa7f-c3aff180a569"
SERVICE B - "PUBLISH" "users:6efc4e14-6679-49d9-be16-97246e02d32b" "request||where||[[\"id\",\"!=\",-65535]]"
SERVICE A - "PUBLISH" "users:6efc4e14-6679-49d9-be16-97246e02d32b" "response||[{\"id\":2,\"name\":\"Nayeli Kulas\",\"email\":\"dare.edgar@example.com\",\"email_verified_at\":\"2020-10-20T13:48:39.000000Z\",\"password\":\"\",\"created_at\":\"2020-10-20T13:48:39.000000Z\",\"updated_at\":\"2020-10-20T13:48:39.000000Z\"}]
SERVICE B - "PUNSUBSCRIBE" "users:6efc4e14-6679-49d9-be16-97246e02d32b"
  1. 服务 A 订阅了所有 users 频道及其所有包 ID。
  2. 服务 B 创建了包 322d3a41-c34c-46fe-aa7f-c3aff180a569 并订阅了其频道
  3. 服务 B 向包的频道发送请求 request||where||[[\"id\",\"!=\",-65535]]
  4. 服务 A 解析请求后,首先在控制器中调用 where 方法,如果不在绑定的模型中,则生成响应的集合。
  5. 生成的响应由服务 A 发送到所需的频道。
  6. 服务 B 从包的频道取消订阅。

每个包都应该有一个 ID,因为我们无法实现数值递增 ID,所以我们只是创建 UUID(例如:322d3a41-c34c-46fe-aa7f-c3aff180a569)

协议看起来如何

request||where||[[\"id\",\"!=\",-65535]] 这个字符串表示接收到的 Redis Pub 事件实际上是一个 'Request',在我们的控制器中,我们应该调用 'where' 方法,参数为 '[["id","!=",-65535]]'

参数可以不止一个,例如: request||where||api_token||12345_token