处理异步服务器端操作

时间:2016-04-29 13:04:07

标签: performance laravel asynchronous server jobs

我需要实现一个在服务器端运行异步操作的系统,在思考了很多选项之后,我不确定哪个选项最好,可扩展性更高,或者在这个场景中通常使用什么。我必须遗漏一些东西,因为没有一个解决方案可以完全解决问题。

上下文:对于某些上下文,我有一个移动应用程序,用户向其他用户发送请求以启动活动。此操作在服务器端处理,如果请求没有来自其他用户的响应,则它将在15分钟后过期并关闭。所以我在数据库中创建了一个带有此操作开始时间的记录,我需要在15分钟后更新其状态,从而进行异步操作。它需要正好15分钟才能正确通知等待用户。

可能的解决方案:

  • 我正在使用laravel,而我正在思考的解决方案是将延迟的作业推送到队列中。虽然在开始时我认为它将是完美的解决方案,但我认为它可能不具有可扩展性,因为此请求的频率可能变得太高而且太多的工作将排队。此外,队列作业不能保证在达到延迟后完全执行,并且可能解决得太晚。

  • 我想到的另一个解决方案是在每分钟运行的cron作业中处理所有这些,但是当请求量很高时它也会遇到同样的问题。在性能方面,每分钟做这件事可能有点过头了,特别是在活动不频繁的时候。

基本上,这些是小型操作,解决起来相对较快,但管理大量待处理操作的成本可能比操作本身更差。有没有其他模式(甚至没有减少到laravel或php)来延迟任务执行到未来的时间?

1 个答案:

答案 0 :(得分:1)

我认为您希望确定需要由数据库/应用程序执行的用户请求(即expires列的范围),而不是队列守护程序。但是你希望这种决心以动态的速度发生。

Laravel的一个可能的解决方案:

创建一个在启动时添加到队列中的元作业,并以动态速率重新排队。换句话说,您的队列中只有一个作业,它会评估所有挂起的用户请求。完成后,它会将自身释放回队列,其延迟取决于仍在等待的请求的数量(更多待处理请求=更短的延迟,更少的待处理请求=更长的延迟)。用户请求永远不会自己放入队列,只是由这个动态延迟的元作业处理。

此外,正如FYI一样,Laravel queue:work --daemon使用sleep()来延迟其队列检查循环,这可能比使用cron作业(或queue:listen进程更有效),每次调用时重新加载整个应用程序,但需要手动重新启动以取消您对该应用程序所做的任何更改。