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