BaseSwooleServer.php 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248
  1. <?php
  2. /**
  3. * rabbitMq 消费者
  4. */
  5. namespace console\controllers\swoole_server;
  6. use common\helpers\ArrayHelper;
  7. use common\helpers\FileHelper;
  8. use common\helpers\StringHelper;
  9. use Exception;
  10. use Yii;
  11. use yii\base\DynamicModel;
  12. use yii\console\Controller;
  13. class BaseSwooleServer extends Controller
  14. {
  15. public $option;
  16. /**
  17. * 自定义选项
  18. * @Author bing
  19. * @DateTime 2021-10-15 10:43:18
  20. * @copyright: Copyright (c) 2020 广东七件事集团
  21. * @param [type] $actionID
  22. * @return void
  23. */
  24. public function options($actionID)
  25. {
  26. $options = parent::options($actionID);
  27. return array_merge($options, [
  28. 'option'
  29. ]);
  30. }
  31. /**
  32. * 自定义命令别名
  33. * @Author bing
  34. * @DateTime 2021-10-15 10:42:50
  35. * @copyright: Copyright (c) 2020 广东七件事集团
  36. * @return void
  37. */
  38. public function optionAliases()
  39. {
  40. $optionAliases = parent::optionAliases();
  41. return array_merge($optionAliases, [
  42. ]);
  43. }
  44. /**
  45. * 验证服务启动命令
  46. * @Author bing
  47. * @DateTime 2021-10-15 10:45:13
  48. * @copyright: Copyright (c) 2020 广东七件事集团
  49. * @param [type] $action
  50. * @return void
  51. */
  52. public function beforeAction($action)
  53. {
  54. $params = Yii::$app->request->getParams();
  55. $model = new DynamicModel([
  56. 'option' => $params[1] ?? null
  57. ]);
  58. $model->addRule('option', 'default', ['value' => 'start'])
  59. ->addRule('option', 'required')
  60. ->addRule('option', 'string')
  61. ->addRule('option', 'in', ['range' => ['start', 'stop', 'restart']])
  62. ->validate();
  63. if ($model->hasErrors()) {
  64. throw new Exception($model->getFirstError('option'), 500);
  65. }
  66. $attributes = $model->getAttributes();
  67. $this->option = $attributes['option'];
  68. return parent::beforeAction($action);
  69. }
  70. /**
  71. * 获取当前进程id
  72. * @Author bing
  73. * @DateTime 2021-10-15 11:01:31
  74. * @copyright: Copyright (c) 2020 广东七件事集团
  75. * @return void
  76. */
  77. public function getPid()
  78. {
  79. return posix_getpid();
  80. }
  81. /**
  82. * 创建pid保存文件
  83. * @Author bing
  84. * @DateTime 2021-10-15 11:06:16
  85. * @copyright: Copyright (c) 2020 广东七件事集团
  86. * @return string
  87. */
  88. public function getPidFile()
  89. {
  90. $uniqueId = $this->action->getUniqueId();
  91. $pidPath = Yii::$app->getRuntimePath() . '/pid/';
  92. FileHelper::createDirectory($pidPath);
  93. return $pidPath . StringHelper::replace('/', '_', $uniqueId) . '.pid';
  94. }
  95. /**
  96. * 把pid写入文件内
  97. * @Author bing
  98. * @DateTime 2021-10-15 11:11:52
  99. * @copyright: Copyright (c) 2020 广东七件事集团
  100. * @param [type] $pid
  101. * @return void
  102. */
  103. public function writePid($pid = null)
  104. {
  105. if (empty($pid)) {
  106. $pid = $this->getPid();
  107. }
  108. $pidFile = $this->getPidFile();
  109. file_put_contents($pidFile, $pid . PHP_EOL, FILE_APPEND);
  110. }
  111. /**
  112. * 获取运行中的进程
  113. * @Author bing
  114. * @DateTime 2021-10-15 11:13:33
  115. * @copyright: Copyright (c) 2020 广东七件事集团
  116. * @return array
  117. */
  118. public function getPids()
  119. {
  120. $pidFile = $this->getPidFile();
  121. @$pidString = file_get_contents($pidFile);
  122. $pids = array_filter(StringHelper::explode($pidString, PHP_EOL));
  123. return $pids;
  124. }
  125. /**
  126. * 终止进程
  127. * @Author bing
  128. * @DateTime 2021-10-15 11:16:49
  129. * @copyright: Copyright (c) 2020 广东七件事集团
  130. * @return void
  131. */
  132. public function killPids(){
  133. $pidFile = $this->getPidFile();
  134. $pids = $this->getPids();
  135. array_map(function ($value) {
  136. // 终止信号
  137. posix_kill($value, SIGTERM);
  138. }, $pids);
  139. file_put_contents($pidFile, '');
  140. }
  141. /**
  142. * 检查进程是否在运行中
  143. * @Author bing
  144. * @DateTime 2021-10-15 11:20:14
  145. * @copyright: Copyright (c) 2020 广东七件事集团
  146. * @return void
  147. */
  148. public function processRunningCheck(){
  149. $pidFile = $this->getPidFile();
  150. $pids = $this->getPids();
  151. foreach ($pids as $pid) {
  152. if (file_exists('/proc/' . $pid)) {
  153. return true;
  154. }
  155. }
  156. file_put_contents($pidFile, '');
  157. return false;
  158. }
  159. /**
  160. * 服务启动时处理进程管理
  161. * @Author bing
  162. * @DateTime 2021-10-15 16:22:01
  163. * @copyright: Copyright (c) 2020 广东七件事集团
  164. * @param [type] $serv
  165. * @return void
  166. */
  167. public function onStart($serv)
  168. {
  169. //管理master_id和manager_id
  170. $this->writePid($serv->master_pid);
  171. $this->writePid($serv->manager_pid);
  172. swoole_set_process_name("swoole:master {$serv->master_pid}");
  173. echo "server start".PHP_EOL;
  174. }
  175. /**
  176. * 运行选项
  177. * @Author bing
  178. * @DateTime 2021-10-15 11:22:58
  179. * @copyright: Copyright (c) 2020 广东七件事集团
  180. * @return void
  181. */
  182. public function beforeRun(){
  183. switch ($this->option) {
  184. case 'start':
  185. if ($this->processRunningCheck()) throw new Exception('pid 文件运行中,服务正在运行中', 500);
  186. break;
  187. case 'stop':
  188. $this->killPids();
  189. break;
  190. case 'restart':
  191. $this->killPids();
  192. // 等待旧进程终止
  193. sleep(1);
  194. break;
  195. }
  196. return $this->option;
  197. }
  198. /**
  199. * 数据签名
  200. * @Author bing
  201. * @DateTime 2021-10-18 13:20:34
  202. * @copyright: Copyright (c) 2020 广东七件事集团
  203. * @param [type] $data
  204. * @return void
  205. */
  206. public function addSign(&$data)
  207. {
  208. asort($data);
  209. $tmpSign = serialize($data);
  210. $sign = md5($tmpSign . $this->sign);
  211. $data['sign'] = $sign;
  212. }
  213. /**
  214. * 验证签名
  215. * @Author bing
  216. * @DateTime 2021-10-18 13:21:14
  217. * @copyright: Copyright (c) 2020 广东七件事集团
  218. * @param [type] $data
  219. * @return void
  220. */
  221. public function checkSign($data)
  222. {
  223. $data = json_decode($data, true);
  224. if (!isset($data['sign'])) return false;
  225. $sign = $data['sign'];
  226. unset($data['sign']);
  227. asort($data);
  228. $tmpSign = serialize($data);
  229. $checkSign = md5($tmpSign . $this->sign);
  230. if ($checkSign == $sign) return true;
  231. return false;
  232. }
  233. }