workermand 4.9 KB

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