MainController.php 2.4 KB

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