发放奖励模块尽量独立,不要污染业务数据表和业务代码。数据表方面,建立临时表和发放记录表(可选),发布文章时用异步 event (可以投递 job 任务或者 listener) ,添加到临时表,表字段为发布时间、状态、是否已发放,crontab 按时间查这个表,发放时检查文章是否满足发放条件,成功发放后添加到发放记录表,然后临时表中删除记录。
这样做的好处是独立,event 是异步,不影响发布文章业务代码,奖励模块对于系统的影响只这个入口(添加到临时表的代码)是新增的,后续若取消奖励模块,job|listener 中删除对应的入口代码即可。
1.延迟队列 96个小时,万一遇到中间服务器或者redis崩掉的情况 会导致奖励失败 2.配置一个奖励的时间 96小时 (方便修改对应奖励时间) 3.文章表新增 reward_at(奖励时间)加索引 和 reward_status(奖励状态) 4.当发布或者审核文章成功, 然后将 当前时间+配置的时间 写入到数据表中 5.然后任务循环运行 6.这种需要考虑的特殊情况是 发布成功了,但是在奖励的时间内 又删掉了的情况
方法一:简单粗暴,使用crontab每分钟调用一次php代码,根据创建时间和发放奖励记录判定是否是发布36小时之后的文章,是的话就发放奖励。优点是实现简单,缺点是数据库压力较大。 方法二:延时队列,例如laravel自带的redis驱动队列。优点是解决了数据库压力,缺点是实现比方法一复杂一点,部分驱动延时时间不支持那么长。至于数据持久化,redis之类的驱动现在也可以支持,不用太担心。
结合业务来看。使用普通定时任务即可,一天调用一次。
假设今天就该发96小时前的文章奖励,即4天前的文章奖励。今天10/15号。数据库直接查10/11号发的所有文章,然后发放奖励。这里可以优化,记录一个flag,直接大于某个id,能优化查询性能。
延迟队列把业务整复杂了,这个业务应当不需要太高的实时性,需要定位到那么精准到几分几秒发放。按我的理解一般都是统一几天后的几小时内发放。
根据你发放的前置规则在判断里面触发一个 96 小时候下发奖励的异步任务。如果是 laravel 写的话自身就支持这样的操作,可以看看文档:队列《Laravel 9 中文文档》 如果是其他的也都一样,举一反三,看对应框架队列任务的实现文档。
发放奖励模块尽量独立,不要污染业务数据表和业务代码。数据表方面,建立临时表和发放记录表(可选),发布文章时用异步 event (可以投递 job 任务或者 listener) ,添加到临时表,表字段为发布时间、状态、是否已发放,crontab 按时间查这个表,发放时检查文章是否满足发放条件,成功发放后添加到发放记录表,然后临时表中删除记录。
这样做的好处是独立,event 是异步,不影响发布文章业务代码,奖励模块对于系统的影响只这个入口(添加到临时表的代码)是新增的,后续若取消奖励模块,job|listener 中删除对应的入口代码即可。
推荐文章: