很好地阻止齿轮工人

Kar*_*ite 43 php gearman

我有许多Gearman工作人员不断运行,保存用户页面视图记录等内容.偶尔,我会更新Gearman工作人员使用的PHP代码.为了让工作人员切换到新代码,我杀死并重新启动工作人员的PHP进程.

有什么更好的方法呢?据推测,当我杀死其中一个工作进程时,我有时会丢失数据(尽管不是非常重要的数据).

编辑:我找到了一个适合我的答案,并在下面发布.

小智 12

解决方案1


通常我使用带-r标志的unix守护程序实用程序运行我的worker,让它们在一个作业后过期.每次迭代后,您的脚本将正常结束,守护程序将自动重启.

你的工人对于一份工作来说是陈旧的,但这对你来说可能不像丢失数据那么大

该解决方案还具有释放内存的优点.如果你正在做大型工作,你可能会遇到内存问题,因为PHP pre 5.3有令人难以置信的GC.

解决方案2


您还可以向退出脚本的所有工作人员添加退出功能.当您想要重新启动时,只需给予齿轮调用以高优先级退出.

  • 解决方案2不起作用,如果从函数中退出脚本,作业将无法完成并在下次再次启动:kill,respawn,kill,respwan,kill,... (3认同)

小智 8

function AutoRestart() {
   static $startTime = time();

   if (filemtime(__FILE__) > $startTime) {
      exit();
   }
}

AutoRestart();  
Run Code Online (Sandbox Code Playgroud)


Kar*_*ite 7

好吧,我发布了这个问题,现在我觉得我找到了一个很好的答案.

如果你查看Net_Gearman_Worker的代码,你会发现在工作循环中,监视函数stopWork,如果它返回true,它将退出函数.

我做了以下操作:
使用memcache,我创建了一个缓存值,gearman_restarttime,每当我更新站点时,我都会使用一个单独的脚本将其设置为当前时间戳.(我使用了Memcache,但这可以存储在任何地方 - 数据库,文件或任何东西).

我将Worker类扩展为Net_Gearman_Worker_Foo,并让我的所有worker都实例化了.在Foo类中,我重写了stopWork函数以执行以下操作:首先,它检查gearman_restarttime; 第一次通过时,它将值保存在全局变量中.从那时起,每次都将缓存值与全局值进行比较.如果已更改,则stopWork返回true,然后工作程序退出.cron每分钟检查一次,看看每个工作者是否仍在运行,并重新启动任何已退出的工作人员.

将计时器放在stopWork中也是值得的,并且每隔x分钟只检查一次缓存.在我们的例子中,Memcache足够快,每次检查值似乎都不是问题,但如果你使用其他系统来存储当前时间戳,那么检查频率会更好.