krak / symfony-messenger-redis
Symfony Messenger Redis 适配器
Requires
- ext-json: *
- ext-redis: *
- symfony/messenger: ^4.4|^5.4|^6.2
Requires (Dev)
- nyholm/symfony-bundle-test: ^1.6
- phpunit/phpunit: ^9.0
- symfony/dependency-injection: ^5.4
- symfony/http-kernel: ^5.4
- symfony/property-access: ^5.4
- symfony/serializer: ^5.4
README
此库为 Symfony Messenger ^4.4 系统提供自定义 Redis 列表集成。
标准 Redis 实现需要 Redis 5.0,并使用流功能,此适配器使用 Redis 列表来实现队列功能。
安装
使用 composer 在 krak/symfony-messenger-redis
上安装。
如果 symfony 的 composer 安装没有自动注册捆绑包,您可以手动完成此操作
<?php return [ //... Krak\SymfonyMessengerRedis\MessengerRedisBundle::class => ['all' => true], ];
使用方法
您可以使用此队列与以下框架消息传递配置
framework: messenger: transports: acme_redis: dsn: '%env(MESSENGER_TRANSPORT_DSN)%' options: { queue: queue_acme }
其中 MESSENGER_TRANSPORT_DSN
环境变量类似于: redis://localhost:6379
这将注册一个名为 acme_redis
的传输,它将正确使用此库中配置的 Redis 传输。
唯一消息
如果您需要确保特定作业在队列中等待时是唯一的,可以使用 UniqueStamp。
use Symfony\Component\Messenger\Envelope; use Krak\SymfonyMessengerRedis\Stamp\UniqueStamp; Envelope::wrap($message)->with(new UniqueStamp('optional-unique-id'));
如果您没有传递一个标识符来强制唯一性,传输将执行消息体的 md5 哈希以创建一个标识符。
此戳记的示例用法
- 每次在系统中保存一个产品时,都会派发一个 ProductUpdatedMessage。
- 您有消息处理器根据该产品信息执行一些昂贵的操作
- 如果单个产品在未实际更改的情况下快速保存,那么为该产品排队 100 次相同的作业就没有意义了
- 使用唯一戳记可以确保如果队列中已经有了该特定产品的消息,则不会添加另一个消息,因为原始消息尚未被处理。
延迟消息
此库支持核心 SF 消息传递提供的 DelayStamp。
防抖消息
您可以使用 DebounceStamp 防抖消息发送到传输。
DebounceStamp 类似于 DelayStamp,但基本上,如果防抖消息是新的,我们将将其完全像唯一和延迟消息一样进入队列。但如果队列中仍然有一个类似的消息等待,那么我们会将其移除,并以新的延迟重新添加。对于不了解防抖的人来说,请参阅 https://redd.one/blog/debounce-vs-throttle
use Symfony\Component\Messenger\Envelope; use Krak\SymfonyMessengerRedis\Stamp\DebounceStamp; Envelope::wrap($message)->with(new DebounceStamp('delay-in-ms', 'optional-unique-id'));
可用选项
以下是可用于传输选项数组或作为查询参数的可用选项
- 队列
- 必需: 是
- 默认: N/A
- 描述: 用于在 Redis 中存储消息的内部列表名称。系统还会创建一个名为
{queue}_processing
的处理队列来存储已处理的消息。
- 数据库
- 必需: 否
- 默认: N/A
- 描述: 执行 Redis 操作时要选择的 Redis 数据库。此值也可以通过查询参数从 dsn 设置,或者在 dsn 中设置路径(
redis//redis:6379?db=1
或redis://redis:6379/1
)。
TLS 支持
要启用 TLS 支持,将 DSN 方案更改为 rediss://
而不是 redis://
,以指出 Redis 客户端应使用 TLS 连接。
已处理队列
此库使用 rpoplpush 可靠队列模式。然而,请注意,此库不会尝试清理已处理的队列。
我们已取得显著进展,确保当一切正常工作时,即使在使用自动扩展接收器的情况下,处理队列也能始终被清理。
然而,如果由于某种原因,一个工作进程被通过 SIGKILL
(也称为 kill -9
)杀掉,那么工作进程可能会在队列中留下一个未完成的项目,因为它没有完成其处理。随着时间的推移,这可能会导致 _processing
持续积累不需要的消息。
这些 _processing
列表占用空间不会对其他东西造成伤害,除了存储空间。定期使用 DEL
命令清除这些列表也不会对任何事物造成伤害。但需要验证这不会对任何正在运行的进程造成伤害(我认为不会)。
同时使用 Symfony 的 Redis 传输
symfony 的 redis 和 krak redis 传输都注册了 dsn 前缀: redis://
。在您希望支持这两种传输的情况下,您需要使用 use_krak_redis
选项来禁用此库的 redis 传输。
framework: messenger: transports: krak_redis: dsn: '%env(MESSENGER_TRANSPORT_DSN)%' options: { queue: queue_acme } sf_redis: dsn: '%env(MESSENGER_TRANSPORT_DSN)%' options: { use_krak_redis: false } # this allows symfony's redis transport factory to take precedence
测试
您可以使用以下命令运行测试套件:composer test
为了使功能测试套件通过,您需要在本地启动 redis docker 容器。
请记住,您需要在您的本地 php cli 上安装 redis-ext,并且需要通过 docker-compose
启动 docker 中的 redis 实例。