Basepop.php 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. <?php
  2. namespace app\monitor\controller;
  3. use app\common\service\MailService;
  4. use think\Cache;
  5. use think\Controller;
  6. use think\Log;
  7. /**
  8. * 请求出队
  9. * Class RequestPop
  10. */
  11. class Basepop extends Controller
  12. {
  13. private $redisClient = null;
  14. /**
  15. * 队列主进程
  16. * @param type $redisKey
  17. * @param type $alertNum
  18. * @param type $alertName
  19. */
  20. protected function main($redisKey,$alertNum,$alertName){
  21. try{
  22. $date = date('Y-m-d H:i:s');
  23. //切换当前用户,以免root权限日志
  24. $this->setUser();
  25. $pid = posix_getpid();
  26. //连接redis
  27. $this->connectionRedis();
  28. $remainNum = $this->redisClient->lLen("$redisKey");
  29. if($remainNum >$alertNum){
  30. $mailService = new MailService();
  31. $res = $mailService->send('leo',"{$alertName}自动升级进程数","剩余数量$remainNum,主动清理程序",[],[['mail'=>'2990412861@qq.com','name'=>'leo.xie']]);
  32. //自动升级进程数
  33. $normalPidList = Cache::get("{$redisKey}_pop_program");
  34. is_array($normalPidList)?$normalPidList[] = $pid:$normalPidList = [$pid];
  35. Cache::set("{$redisKey}_pop_program",$normalPidList);
  36. }else{
  37. $normalPidList = Cache::get("{$redisKey}_pop_program");
  38. if(is_array($normalPidList) && count($normalPidList) > 1){
  39. //自动降级进程数
  40. foreach($normalPidList as $itemPid){
  41. Log::record("进程kill:".$itemPid."\n");
  42. posix_kill($itemPid, SIGKILL);
  43. }
  44. Cache::rm("{$redisKey}_pop_program");
  45. $mailService = new MailService();
  46. $res = $mailService->send('leo',"{$alertName}自动降级进程数","剩余数量$remainNum,主动清理程序",[],[['mail'=>'2990412861@qq.com','name'=>'leo.xie']]);
  47. }elseif(!empty($normalPidList) ){
  48. die('['.$date.']有正在执行中的程序');
  49. }
  50. Cache::set("{$redisKey}_pop_program",[$pid]);
  51. }
  52. while(true){
  53. //有时候进程没有杀掉,做一次自我修复机制
  54. $curPid = posix_getpid();
  55. $normalPidList = Cache::get("{$redisKey}_pop_program");
  56. if(!is_array($normalPidList) || !in_array($curPid, $normalPidList)){
  57. Log::record('异常中断'.$curPid);
  58. exit(0);
  59. }
  60. $requestJson = $this->redisClient->lPop("$redisKey");
  61. if(empty($requestJson)){
  62. sleep(10);
  63. try{
  64. $this->redisClient->close();
  65. }catch (\Exception $ex){
  66. //nothing to do...
  67. }
  68. $this->connectionRedis();
  69. continue;
  70. }
  71. $requestArr = @json_decode($requestJson,true);
  72. if(empty($requestArr)){
  73. continue;
  74. }
  75. try{
  76. $return = $this->mainFunc($requestArr);
  77. if($return === false){
  78. //给三次重试机会
  79. $requestArr['__times__'] = isset($requestArr['__times__'])?$requestArr['__times__']+1:1;
  80. $requestArr['__times__'] < 4?$this->redisClient->lpush("$redisKey", json_encode($requestArr)):"";
  81. }
  82. } catch (\Exception $ex){
  83. $mailService = new MailService();
  84. $mailService->send('leo',"{$alertName}出队异常","",$ex->getMessage(),[['mail'=>'2990412861@qq.com','name'=>'leo.xie']]);
  85. }
  86. }
  87. }catch(\Exception $ex){
  88. //自动降级进程数
  89. echo $ex->getMessage()."\n";
  90. echo "cache\n";
  91. Cache::rm("{$redisKey}_pop_program");
  92. exit(0);
  93. }
  94. }
  95. /**
  96. * 连接远程的redis
  97. */
  98. private function connectionRedis(){
  99. $this->redisClient = new \Redis();
  100. $this->redisClient->connect('47.97.187.118', 6379);
  101. $this->redisClient->auth('gudong-hz');
  102. }
  103. //设置运行的用户
  104. private function setUser($name='www') {
  105. $maxPid = posix_getpid();
  106. $pid = pcntl_fork();
  107. if ($pid != 0) {
  108. posix_kill($maxPid, SIGKILL);
  109. }
  110. if (empty($name)) {
  111. return false;
  112. }
  113. $user = posix_getpwnam($name);
  114. if ($user) {
  115. $uid = $user['uid'];
  116. $gid = $user['gid'];
  117. $result = posix_setuid($uid);
  118. posix_setgid($gid);
  119. }
  120. return $result;
  121. }
  122. }