使用Beanstalk搭建队列服务
Beanstalkd介绍
一个高性能、轻量级的分布式内存队列系统。高性能离不开异步,异步离不开队列,而其内部都是Producer-Consumer模式的原理。
组成部分
组件 | 说明 |
---|---|
管道(tube) | 一个有名称的任务队列,用来存储统一类型的job,是producer和consumer的操作对象 |
任务(job) | 一个需要异步处理的任务,需要放在tube中 |
生产者(producer) | job的生产者,通过put命令来将一个job放到一个tube中 |
消费者(consumer) | job的消费者,通过reserve、release、bury、delete命令来获取job或改变job的状态 |
特性
- 优先级: 可以设置任务的优先级
- 延迟: 设置任务多少秒后才允许被消费者使用
- 持久化: 定时刷新数据到文件,服务器挂掉后数据依旧存在
- 超时控制: 消费者必须在指定时间内完成任务,否则就会重新放入管道任务预留:消费者先暂时跳过任务不处理
- 分布式容错: 分布式设计和Memcached类似,beanstalkd各个server之间并不知道彼此的存在,都是通过client来实现分布式以及根据tube名称去特定server获取job。
任务状态
状态 | 说明 |
---|---|
ready | 已经准备好的任务,可以给消费者获取 |
delayed | 延迟执行的任务,设置时候设置了延迟时间 |
reserved | 已被消费者获取,正在执行的任务,Beanstalkd服务负责检查任务是否 在TTR(time-to-run)内完成 |
buried | 保留的任务,任务不会被执行,也不会消失 |
delete | 消息被彻底删除,Beanstalkd不再维护这些消息 |
适用场景
- 用作延时队列: 比如可以用于如果用户30分钟内不操作,任务关闭。
- 用作循环队列: 用release命令可以循环执行任务,比如可以做负载均衡任务分发。
- 用作兜底机制: 比如一个请求有失败的概率,可以用Beanstalk不断重试,设定超时时间,时间内尝试到成功为止。
- 用作定时任务: 比如可以用于专门的后台任务。
- 用作异步操作: 这是所有消息队列都最常用的,先将任务仍进去,顺序执行。
服务安装
- 下载beanstalkd-1.11
wget https://codeload.github.com/beanstalkd/beanstalkd/tar.gz/v1.11
- 安装
tar xzvf beanstalkd-1.11.tar.gz
cd beanstalkd-1.11
make & make install
beanstalkd -v
- 启动服务
beanstalkd -l 0.0.0.0 -p 11300 -b /log/beanstalkd/binlog -F
队列应用(PHP)
composer安装 Pheanstalk 类库
//PHP版本要求 7.1+
composer require pda/pheanstalk:~4.0
执行composer后,在项目composer.json配置文件中将增加pda/pheanstalk依赖包
"require": {
"pda/pheanstalk": "~4.0"
}
Producer添加任务
//创建实例
$client = Pheanstalk::create($host, $port, $timeout);
//设置使用的tube,添加任务数据
//$data 任务数据
//$priority 任务优先级.小优先级数值的job将会排在大优先级 数值的job前面执行。
//最高优先级是0,最低优先级是4,294,967,295
//$delay 任务延迟执行秒数
//$ttr 允许一个消费者执行该job的秒数
$client->useTube($tube)->put($data, $priority, $delay, $ttr);
Consumer消费任务
ini_set('default_socket_timeout', 24*60*60);
$client = Pheanstalk::create($host, $port, $timeout);
$client->watchOnly($tube);