workermand 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. #!/usr/bin/env php
  2. <?php
  3. if(empty($argv[1]))
  4. {
  5. echo "Usage: serverd {start|stop|restart|reload|kill|status}\n";
  6. exit;
  7. }
  8. $cmd = $argv[1];
  9. define('WORKERMAN_ROOT_DIR', realpath(__DIR__."/../")."/");
  10. // ==pid-file==
  11. require_once WORKERMAN_ROOT_DIR . 'Core/Lib/Config.php';
  12. if(!($pid_file = WORKERMAN\Core\Lib\Config::get('pid_file')))
  13. {
  14. $pid_file = '/var/run/php-server.pid';
  15. }
  16. define('WORKERMAN_PID_FILE', $pid_file);
  17. // ==log-dir==
  18. if(!($log_dir = WORKERMAN\Core\Lib\Config::get('log_dir')))
  19. {
  20. $log_dir = WORKERMAN_ROOT_DIR . 'logs/';
  21. }
  22. define('WORKERMAN_LOG_DIR', $log_dir . '/');
  23. // ==ipc-key==
  24. if(!($ipc_key = WORKERMAN\Core\Lib\Config::get('ipc_key')))
  25. {
  26. $ipc_key = 0x70010a2e;
  27. }
  28. define('IPC_KEY', $ipc_key);
  29. // ==shm-size==
  30. if(!($shm_size = WORKERMAN\Core\Lib\Config::get('shm_size')))
  31. {
  32. $shm_size = 393216;
  33. }
  34. define('DEFAULT_SHM_SIZE', $shm_size);
  35. require_once WORKERMAN_ROOT_DIR . "Core/Master.php";
  36. chdir(WORKERMAN_ROOT_DIR."Core");
  37. //检查pid对应的进程是否存在,不存在删除PID文件
  38. if($cmd != 'status' && is_file(WORKERMAN_PID_FILE))
  39. {
  40. //检查权限
  41. if(!posix_access(WORKERMAN_PID_FILE, POSIX_W_OK))
  42. {
  43. if($stat = stat(WORKERMAN_PID_FILE))
  44. {
  45. if(($start_pwuid = posix_getpwuid($stat['uid'])) && ($current_pwuid = posix_getpwuid(posix_getuid())))
  46. {
  47. exit("\n\033[31;40mServer is started by user {$start_pwuid['name']}, {$current_pwuid['name']} can not $cmd Server, Permission denied\033[0m\n\n\033[31;40mServer $cmd failed\033[0m\n\n");
  48. }
  49. }
  50. exit("Can not $cmd Server, Permission denied\n");
  51. }
  52. //检查pid进程是否存在
  53. if($pid = @file_get_contents(WORKERMAN_PID_FILE))
  54. {
  55. if(false === posix_kill($pid, 0))
  56. {
  57. if(!unlink(WORKERMAN_PID_FILE))
  58. {
  59. exit("Can not $cmd Server\n\n");
  60. }
  61. }
  62. }
  63. }
  64. switch($cmd)
  65. {
  66. case 'start':
  67. $worker_user = isset($argv[2]) ? $argv[2] : '';
  68. WORKERMAN\Core\Master::run($worker_user);
  69. break;
  70. case 'stop':
  71. $pid = @file_get_contents(WORKERMAN_PID_FILE);
  72. if(empty($pid))
  73. {
  74. exit("Server not running?\n");
  75. }
  76. stop_and_wait();
  77. break;
  78. case 'restart':
  79. stop_and_wait();
  80. $worker_user = isset($argv[2]) ? $argv[2] : '';
  81. WORKERMAN\Core\Master::run();
  82. break;
  83. case 'reload':
  84. $pid = @file_get_contents(WORKERMAN_PID_FILE);
  85. if(empty($pid))
  86. {
  87. exit("server not running?\n");
  88. }
  89. posix_kill($pid, SIGHUP);
  90. echo "reload PHP-Server\n";
  91. break;
  92. case 'kill':
  93. force_kill();
  94. force_kill();
  95. break;
  96. case 'status':
  97. $ip = '127.0.0.1';
  98. $port = WORKERMAN\Core\Lib\Config::get('workers.Monitor.socket.port');
  99. $port = $port ? $port : 10101;
  100. $address = "$ip:$port";
  101. $sock = @stream_socket_client($address);
  102. if(!$sock)
  103. {
  104. exit("\n\033[31;40mcan not connect to $address \033[0m\n\n\033[31;40mServer not running\033[0m\n\n");
  105. }
  106. fwrite($sock, 'status');
  107. $read_fds = array($sock);
  108. $write_fds = $except_fds = array();
  109. while($ret = stream_select($read_fds, $write_fds, $except_fds, 1))
  110. {
  111. if(!$ret)break;
  112. foreach($read_fds as $fd)
  113. {
  114. if($ret_str = fread($fd, 8192))
  115. {
  116. echo $ret_str;
  117. }
  118. else
  119. {
  120. exit;
  121. }
  122. }
  123. }
  124. break;
  125. default:
  126. echo "Usage: serverd {start|stop|restart|reload|kill|status}\n";
  127. exit;
  128. }
  129. function force_kill()
  130. {
  131. $ret = $match = array();
  132. exec("ps aux | grep -E '".WORKERMAN\Core\Master::NAME.":|serverd' | grep -v grep", $ret);
  133. $this_pid = posix_getpid();
  134. $this_ppid = posix_getppid();
  135. foreach($ret as $line)
  136. {
  137. if(preg_match("/^[\S]+\s+(\d+)\s+/", $line, $match))
  138. {
  139. $tmp_pid = $match[1];
  140. if($this_pid != $tmp_pid && $this_ppid != $tmp_pid)
  141. {
  142. posix_kill($tmp_pid, SIGKILL);
  143. }
  144. }
  145. }
  146. }
  147. function stop_and_wait($wait_time = 6)
  148. {
  149. $pid = @file_get_contents(WORKERMAN_PID_FILE);
  150. if(empty($pid))
  151. {
  152. //exit("server not running?\n");
  153. }
  154. else
  155. {
  156. $start_time = time();
  157. posix_kill($pid, SIGINT);
  158. while(is_file(WORKERMAN_PID_FILE))
  159. {
  160. clearstatcache();
  161. usleep(1000);
  162. if(time()-$start_time >= $wait_time)
  163. {
  164. force_kill();
  165. force_kill();
  166. unlink(WORKERMAN_PID_FILE);
  167. usleep(500000);
  168. break;
  169. }
  170. }
  171. echo "PHP-Server stoped\n";
  172. }
  173. }