Laravel - 队列应用及踩过的坑

Laravel 自己实现了队列的机制,如果要看源码解析,这两篇文章写的很好。

  • https://laravel-china.org/articles/4169/analysis-of-laravel-message-queue
  • https://laravel-china.org/articles/7037/laravel-queue-analysis-of-message-queue-tasks-and-distribution-source-code
    注:第二篇文章因为七牛存储不再提供域名服务的原因,导致图片无法访问,我把珍藏的截图贡献出来。
    在这里插入图片描述

本篇要讲的是在应用中遇到的坑。

Laravel 常用的队列驱动
  • Redis
  • beanstalk
  • sqs
  • database
在MySQL事务中

队列一般用于比较耗时或不太重要的任务处理,如果是不太重要的任务(比如:发邮件、发消息),那就没必要在事务中进行写队列的操作,即使写入队列不成功也没什么大不了的。
但是如果是比较重要但耗时的任务,为了能快速响应用户,需要用到队列。因为任务是比较重要,所以需要保证数据入库写入队列都成功。这种情况下就有一个很重要的点,业务代码需要先写数据库后再写入队列,因为MySQL事务回滚并不会回滚队列

队列的异常、错误

无论选择哪一种队列驱动,Laravel 都会把错误的任务写入failed_jobs表中(当然,如果你设置了重试次数,那就是重试之后仍然失败后写入)。

  • 当代码异常情况下,如果捕捉就不会写入failed_jobs表中。
  • 当代码错误情况下,就一定会写入(除非mysql写入失败)。
单个任务执行时间
'redis' => [
	'driver' => 'redis',
	'connection' => env('QUEUE_REDIS_CONNECTION', 'default'),
	'queue' => 'default',
	'retry_after' => 60
]

queue.php 文件配置中(以redis 为例),retry_after代表如果单个任务在60秒内没有ack,就会把任务重新放入队列。简单的讲:如果单个任务执行时间超过60秒,就会重复执行。

数据库驱动

如果用 DB 作为驱动,队列定时回去数据库查询需要执行的任务,

select * from `nw_jobs` where `queue` = default and ((`reserved_at` is null and `available_at` <= 1548066079) or (`reserved_at` <= 1548062479)) order by `id` asc limit 1 for update

这条 SQL 会用到主键索引,所以只会锁单条记录。

其他
  • 我们为什么要使用队列,有两个比较重要的原因:异步和重试
  • 由队列就可以联想到消息服务,消息服务就需要满足以下功能
    • 消费者回调
    • 重发机制
    • 消息幂等性
  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值