MainController.php 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. <?php
  2. namespace console\controllers;
  3. use backend\models\WorkerScript;
  4. use yii\console\Controller;
  5. /**
  6. * 主进程:保持运行
  7. * Class MainController
  8. * @package console\controllers
  9. * @author: libingke
  10. *
  11. * @note 必须将主进程添加到crontab脚本里,最好间隔时间内运行
  12. * 如=> 1 * * * * php /项目路径/yii main >/dev/null 2>&1 &
  13. */
  14. class MainController extends Controller
  15. {
  16. const DURATION = 30; //主进程检查间隔时间
  17. /**
  18. * [init]
  19. */
  20. public function actionIndex()
  21. {
  22. //如果Main进程已经在运行了,则不启动,保持主进程只有一个
  23. if ($this->checkMainProcess()) {
  24. echo "Main process is running. Please check it."; exit;
  25. }
  26. //每N秒检查一次任务列表
  27. while (1) {
  28. $this->checkTasks();
  29. sleep(self::DURATION);
  30. };
  31. }
  32. /**
  33. * 扫描所有任务
  34. */
  35. public function checkTasks()
  36. {
  37. echo "\n Checking tasks......";
  38. $list = WorkerScript::getRunScriptList();
  39. foreach ($list as $task) {
  40. if (!is_string($task['controller']) || !is_string($task['action'])) {
  41. echo "\n this task has error!";
  42. continue;
  43. }
  44. $program = $task['controller'] . '/' . $task['action'];
  45. $this->execTask($program);
  46. }
  47. }
  48. /**
  49. * 执行任务
  50. * @param $program
  51. * @return bool
  52. */
  53. public function execTask($program)
  54. {
  55. //现在只支持单进程,如果以后支持多个进程同时运行,需要修改这里的逻辑
  56. if ($this->checkProcess($program)) {
  57. return false;
  58. }
  59. $dir = dirname(\Yii::$app->getBasePath());
  60. //将任务放到后台执行
  61. $cmd = "nohup php ".$dir."/yii " . $program." >/dev/null 2>&1 &";
  62. echo "\n ".$cmd;
  63. exec($cmd);
  64. }
  65. /**
  66. * 杀掉任务
  67. * @param $program
  68. */
  69. public function killTask($program)
  70. {
  71. //避免误杀到其它(短字符的)进程
  72. if (strlen($program) < 4)
  73. return false;
  74. $cmd = "ps -ef | grep " . $program . " | awk '{print $2}' | xargs kill -9";
  75. exec($cmd);
  76. return !$this->checkProcess($program);
  77. }
  78. /**
  79. * 检查是否进程中已经有别的主进程
  80. * @param $process
  81. * @return bool
  82. */
  83. public function checkMainProcess()
  84. {
  85. $cmd = "ps -ef |grep -v grep|grep -v 'sh -c' | grep main";
  86. exec($cmd, $output);
  87. return count($output) > 1;
  88. }
  89. public function checkProcess($process)
  90. {
  91. $cmd = "ps -ef |grep -v grep|grep -v 'sh -c' | grep " . $process;
  92. exec($cmd, $output);
  93. return count($output) > 0;
  94. }
  95. }