zlikavac32/beanstalkd-lib

Beanstalkd客户端和工作进程实现

0.5.2 2020-07-20 12:03 UTC

This package is auto-updated.

Last update: 2024-09-20 21:33:12 UTC


README

Build Status

不同的Beanstalkd客户端库。

目录

  1. 介绍
    1. 协议
    2. 客户端
    3. 框架无关
    4. 各种信号处理策略
    5. 优雅退出支持
    6. 面向装饰器
    7. 自动触摸作业
    8. 通道特定配置
  2. 安装
  3. 使用
    1. 配置
    2. 生产者
    3. 工作进程
  4. 示例

介绍

库由两层组成,ProtocolClientProtocol 是Beanstalkd命令的一对一映射,而 Client 是高级API,它将功能分解为多个接口。

还提供了作业调度器/运行器功能,以及信号处理支持。

协议

协议接口为 Zlikavac32\BeanstalkdLib\Protocol,默认实现为 Zlikavac32\BeanstalkdLib\Protocol\ProtocolOverSocket

方法代表协议中定义的Beanstalkd命令。这意味着方法中没有默认值。每个不同的Beanstalkd错误都有自己的异常,以便更容易进行错误恢复。

客户端

客户端是Beanstalkd的高级API,它由三个主要接口组成

  • Zlikavac32\BeanstalkdLib\Client - 面向通用服务器命令的接口
  • Zlikavac32\BeanstalkdLib\TubeHandle - 面向通道相关命令的接口
  • Zlikavac32\BeanstalkdLib\JobHandle - 面向作业相关命令的接口

为了表达高级API,接口方法不再直接映射到Beanstalkd命令。

状态响应有自己的类,这些类提供了对那些值的可读接口,而值本身是严格类型化的。

默认实现由 Protocol 后端支持,并在以下位置提供

  • Zlikavac32\BeanstalkdLib\Client\ProtocolClient
  • Zlikavac32\BeanstalkdLib\Client\ProtocolTubeHandle
  • Zlikavac32\BeanstalkdLib\Client\ProtocolJobHandle

框架无关

库本身对任何框架无关。目前仅提供了Symfony的适配器。尽可能使库对其他库和扩展无关。例如,yaml解析、套接字访问和json序列化是通过此库所需的接口定义的,并为扩展和库提供了适配器。

各种信号处理策略

Zlikavac32\BeanstalkdLib\SignalHandlerInstaller 安装注入的 Zlikavac32\BeanstalkdLib\InterruptHandler 来处理 SIGINTSIGTERMSIGQUIT

现有处理策略包括

  • Zlikavac32\BeanstalkdLib\InterruptHandler\DoNothingInterruptHandler - 只忽略信号
  • Zlikavac32\BeanstalkdLib\InterruptHandler\GracefulExitInterruptHandler - 标记优雅退出正在进行中
  • Zlikavac32\BeanstalkdLib\InterruptHandler\HardInterruptHandler - 在第二个信号上抛出中断异常
  • Zlikavac32\BeanstalkdLib\InterruptHandler\TimeoutHardInterruptHandler - 在N秒后抛出中断异常

优雅退出支持

Zlikavac32\BeanstalkdLib\GracefulExit 可以用来检查是否正在执行优雅退出,如果是,则不应再进行任何处理。默认情况下,优雅退出检查是通过 Zlikavac32\BeanstalkdLib\InterruptHandler\GracefulExitInterruptHandler 提供的。

作业调度器和协议检查值以跳出等待。

面向装饰器

由于想法是保持类薄,更多功能是通过装饰原始服务来提供的。

例如,可以使用 Zlikavac32\BeanstalkdLib\Socket\LazySocket 使套接字变为懒加载,并使用 Zlikavac32\BeanstalkdLib\Socket\ExclusiveAccessSocket 获得独占访问(由于信号)。

自动触摸作业

Zlikavac32\BeanstalkdLib\Runner\AutoTouchRunner 是运行器装饰器,如果作业的运行时间即将结束,它将异步触摸作业。

通道特定配置

默认值在通道配置上定义,当客户端没有提供其他值时,客户端会使用这些值。这意味着不同的通道可以有不同的默认值,例如运行时间或使用的序列化程序。

安装

建议通过Composer安装。

composer require zlikavac32/beanstalkd-lib

使用

接下来,我们将探讨配置和使用。

配置

提供的协议实现(Zlikavac32\BeanstalkdLib\Protocol\ProtocolOverSocket)使用 Zlikavac32\BeanstalkdLib\Socket 与服务器建立连接。提供的适配器用于 sockets PHP 扩展。

$socket = new NativePHPSocket(60000000);

原始套接字可以被装饰,以便它例如可以懒加载。

$socket = new LazySocket($socket);

提供的协议实现还需要 Zlikavac32\BeanstalkdLib\YamlParser 进行协议解析。适配器提供了 Symfony YAML 组件。

$yamlParser = new SymfonyYamlParser();

协议还需要一个优雅退出对象(Zlikavac32\BeanstalkdLib\GracefulExit)的实例,以确定我们是否应该中断等待。

$gracefulExit = new GracefulExitInterruptHandler();

现在我们可以创建我们的协议。

$protocol = new ProtocolOverSocket(
    $socket->open('127.0.0.1', 11300),
    $gracefulExit,
    $yamlParser
);

单独的协议本身并不给我们的代码带来任何重大好处,这正是 Zlikavac32\BeanstalkdLib\Client 发挥作用的地方。

由于客户端抽象了管子访问,我们可以通过装饰协议使其具有状态感知来减少使用管子命令的数量。

$protocol = new StateAwareProtocol($protocol);

接下来,我们需要为系统了解的每个管子配置管子配置。每个管子配置都需要实现 Zlikavac32\BeanstalkdLib\Serializer 的序列化器。可以为域对象实现自定义序列化器,或者使用通用的序列化器,如 Zlikavac32\BeanstalkdLib\Adapter\PHP\Json\NativePHPJsonSerializer

$jsonSerializer = new NativePHPJsonSerializer(true);
$fooTubeConfiguration = new StaticTubeConfiguration(0, 1024, 300, 3600, $jsonSerializer)

现在我们可以创建我们的客户端。客户端需要一个协议管子清理器实例,以及一个已知管子配置映射,其中键是管子名称,值是管子配置。

$protocolTubePurger = new IterativeProtocolTubePurger();

$client = new ProtocolClient($protocol, $protocolTubePurger, new Map([
    'foo' => $fooTubeConfiguration,
]));

生产者

要将作业放入队列,我们检索正确的管子并将作业放入其中。

$fooTube = $client->tube('foo');

$fooTube->put([1, 2, 3, 4]);

工作进程

要预留作业,我们在客户端上调用 reserve()

$reservedJob = $client->reserve();

预留的作业可以进行操作。配置的管子序列化器用于反序列化有效负载。

$jobId = $reservedJob->id();
$deserializedPayload = $reservedJob->payload();

$reservedJob->delete();

为了简化操作,Zlikavac32\BeanstalkdLib\JobDispatcher\TubeMapJobDispatcher 提供了作业分配器。完整的配置,包括信号处理,可以在 examples/worker_producer 中找到。

示例

您可以在 examples 中看到带有代码注释的更多示例。