有人能指导我gearman在出现异常时如何重试吗抛出还是出现错误?
我在Django应用程序中使用python gearman客户端,我的工作人员作为Django命令启动。我从这篇博客文章中读到,重试来自错误的条件不是直接的,它需要sys.exit。
是否已将此问题修复为使用sendFail或sendException重试?gearman还支持使用指数算法重试吗?比如如果SMTP失败在2、4、8、16秒后重试,等等?
据我所知,Gearman采用了一种非常"这不是我的事"的方法——例如,除非工人崩溃,否则它不会干预所执行的工作。任何成功/失败消息都应该由客户端处理,而不是Gearman服务器本身。
在前台作业中,这意味着所有sendFail()
/sendException()
和其他send*()
都指向客户端,由客户端决定是否重试该作业。这是有道理的,因为有时您可能不需要重试。
在后台作业中,所有send*()
函数都失去了意义,因为没有客户端会监听回调。因此,Gearman将忽略发送的消息。作业将被重试的唯一条件是工作程序崩溃时(可以用exit(XX)
命令模拟,其中XX
是非零值)。当然,这不是你想做的事情,因为工人通常应该是长时间运行的流程,而不是在每次作业失败后必须重新启动的流程。
就我个人而言,我已经通过扩展默认的GearmanJob类解决了这个问题,在这里我拦截对send*()
函数的调用,然后自己实现重试机制。从本质上讲,我将所有与重试相关的数据(最大重试次数、已重试次数)与工作负载一起传递,然后自己处理所有事情。这有点麻烦,但我理解Gearman为什么以这种方式工作——它只允许您处理所有的应用程序逻辑。
最后,关于使用指数超时(或任何超时)重试作业的能力。Gearman有一个添加延迟作业的功能(在协议文档中查找SUBMIT_JOB_EPOCH
),但我不确定它的状态——PHP扩展,我认为Python模块不支持它,文档说它将来可以删除。但我知道它目前是有效的——你只需要向Gearman提交原始套接字请求就可以实现(指数部分也应该在你这边实现)。
然而,这篇博客文章认为SUBMIT_JOB_EPOCH的实现并没有很好地扩展。他使用node.js和setTimeout()
使其工作,我见过其他人使用unix实用程序at
也这样做。无论如何,Gearman不会为你做这件事。它将专注于可靠性,但会让你专注于所有的逻辑。