recordonline.php 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378
  1. <?php
  2. use AlibabaCloud\SDK\Cms\V20190101\Cms;
  3. use AlibabaCloud\SDK\Cms\V20190101\Models\DescribeMetricLastRequest;
  4. use Darabonba\OpenApi\Models\Config;
  5. defined('IN_WEB') or die('Include Error!');
  6. /**
  7. * 统计在线在玩
  8. */
  9. class ModelRecordonline
  10. {
  11. protected $gameidList = array(1, 2, 3, 4);//0代表在线不在玩
  12. private $_onlineLoopTime = 12;//查看在线用户循环的时间
  13. /**
  14. * Notes:每分钟记录在线数
  15. * User: wsc
  16. * Time: 2020/12/10 17:07
  17. */
  18. public function setOnlenCount($ts = 0, $online = 0){
  19. // $onlines = oo::commonOprModel('workerman')->getAllUidList();
  20. // $online = $this->getAliMonitor(__METHOD__);//count($onlines);
  21. $key = okeys::onlineCountLog();
  22. $first =false;
  23. if(!oo::commonOprRedis('statistics')->exists($key)){
  24. $first =true;
  25. }
  26. $ts = empty($ts) ? timeFuns::todaySecond() : $ts;
  27. oo::commonOprRedis('statistics')->hSet($key,$ts,$online);
  28. if($first){
  29. oo::commonOprRedis('statistics')->expire($key,oo::redisRandomExpire(86400*7));
  30. }
  31. // $this->crazyAbRecord($ts, $onlines);
  32. return $online;
  33. }
  34. /**
  35. * ab分组在线统计(wsc-2021.10.23弃用)
  36. * @param int $ts
  37. * @return bool
  38. */
  39. public function crazyAbRecord($ts, $onlines = []){
  40. $onlines = empty($onlines) ? oo::commonOprModel('workerman')->getAllUidList() : $onlines;
  41. //玩家在线人数加入redis
  42. $arr = [];
  43. //ab分组数据
  44. $abGroupArr = oo::commonOprRedis('common')->hMget(okeys::UserAbTest(), array_values($onlines));
  45. foreach($abGroupArr as $uid => $key){
  46. if(empty($key) || $key < 1){
  47. $key = 'D';
  48. }elseif($key > 2){
  49. $key = 'C';
  50. }else{
  51. $key = $key == '1' ? 'A' : 'B';
  52. }
  53. $arr[$key] = empty($arr[$key]) ? 1 : $arr[$key] + 1;
  54. }
  55. $ts = empty($ts) ? timeFuns::todaySecond() : $ts;
  56. foreach($arr as $key => $v){
  57. $key = date('Ymd', time()).'-'.$key;
  58. $first = !oo::commonOprRedis('statistics')->exists($key) ? true : false;
  59. oo::commonOprRedis('statistics')->hSet(okeys::onlineplaying($key),$ts,$v);
  60. if($first){ //保留7天数据
  61. oo::commonOprRedis('statistics')->expire(okeys::onlineplaying($key), 86400*7);
  62. }
  63. }
  64. return true;
  65. }
  66. public function crazyRecord($now, $onlineNum){
  67. //获取在线玩家
  68. // $online = oo::commonOprModel('workerman')->getAllUidList();
  69. // $onlineNum = $this->getAliMonitor(__METHOD__);//count($online);
  70. //玩家在线人数加入redis
  71. $lastNum = intval(oo::commonOprRedis('statistics')->get(okeys::onlineusernum()));
  72. if(empty($onlineNum))$onlineNum = $lastNum;
  73. oo::commonOprRedis('statistics')->hSet(okeys::onlineplaying(1),$now,$onlineNum);
  74. oo::commonOprRedis('statistics')->set(okeys::onlineusernum(), $onlineNum);
  75. // return;
  76. //获取当天的最大在线数
  77. $date = date('Ymd', $now);
  78. $maxnumKey = okeys::onlineusermaxnum($date);
  79. $maxnum = intval(oo::commonOprRedis('statistics')->get($maxnumKey));
  80. if($onlineNum > $maxnum) {//记录当天的最大在线数
  81. oo::commonOprRedis('statistics')->set($maxnumKey, $onlineNum);
  82. oo::commonOprRedis('statistics')->expireAt($maxnumKey, oo::redisRandomExpire(strtotime("+2 days 23:59:59")));
  83. }
  84. $date = date('Y-m-d H:i');
  85. if($onlineNum < ceil($lastNum*0.5)){
  86. oo::commonOprModel('Enwechat')->send("【警报】Coin {$date} :5分钟内在线人数下降超过50%,由{$lastNum}人下降到{$onlineNum}人",[],[],1);
  87. // oo::commonOprModel('Enwechat')->send("【警报】Coin {$date} :5分钟内在线人数下降超过50%,由{$lastNum}人下降到{$onlineNum}人",[],[],1);
  88. }else if($onlineNum < ceil($lastNum*0.7)){
  89. oo::commonOprModel('Enwechat')->send("【警报】Coin {$date} :5分钟内在线人数下降超过30%,由{$lastNum}人下降到{$onlineNum}人",[],[],1);
  90. // oo::commonOprModel('Enwechat')->send("【警报】Coin {$date} :5分钟内在线人数下降超过30%,由{$lastNum}人下降到{$onlineNum}人",[],[],1);
  91. }else if($onlineNum < ceil($lastNum*0.9)){
  92. // if(($lastNum - $onlineNum) > 200){ //下滑超过200人才报警
  93. oo::commonOprModel('Enwechat')->send("【警报】Coin {$date} :5分钟内在线人数下降超过10%,由{$lastNum}人下降到{$onlineNum}人",[],[],1);
  94. // }
  95. }
  96. // elseif($lastNum - $onlineNum > 400){
  97. // $date = date('Y-m-d H:i');
  98. // oo::commonOprModel('Enwechat')->send("【警报】Coin {$date} :5分钟内在线人数下降超过300人,由{$lastNum}人下降到{$onlineNum}人",[],[],1);
  99. // }
  100. /*
  101. $table = otable::onlineplaying();
  102. $sql = " INSERT INTO {$table}(ol_total, recordtime, gameid) VALUES({$onlineNum},{$now}, 1) ";
  103. oo::commonOprDb('common')->query($sql);
  104. */
  105. //玩家在线人数加入redis
  106. oo::commonOprRedis('statistics')->hSet(okeys::onlineplaying(1),$now,$onlineNum);
  107. // self::loginMonitor();
  108. }
  109. public function getAliMonitor($method = '', $tryTimes = 0){
  110. $tryTimes++;
  111. try{
  112. $time = time();
  113. $accessKeyId = 'LTAI5tANQSEUhQE9JAfwwHEY';
  114. $accessKeySecret = 'b0FXaWdgUbWTm2cED0nhKfQAZhgrVN';
  115. $config = new Config([
  116. "accessKeyId" => $accessKeyId,
  117. "accessKeySecret" => $accessKeySecret
  118. ]);
  119. // 访问的域名
  120. $config->endpoint = "metrics.cn-hangzhou.aliyuncs.com";
  121. $client = new Cms($config);
  122. $dimensions = [
  123. [
  124. 'instanceId' => 'lb-0xiip5heqh8hu52cmt5dr',
  125. 'port' => '8282',
  126. ],
  127. // [
  128. // 'instanceId' => 'lb-0xii7gpzz1yhoqwt6n54v',
  129. // 'port' => '8282',
  130. // ],
  131. ];
  132. $describeMetricLastRequest = new DescribeMetricLastRequest([
  133. "namespace" => "acs_slb_dashboard",
  134. "metricName" => "ActiveConnection",
  135. "dimensions" => json_encode($dimensions),
  136. ]);
  137. $result = $client->describeMetricLast($describeMetricLastRequest);
  138. $json = $result->body->datapoints;
  139. }catch(\throwable $e){
  140. oo::logs()->debug3(['called location' => $method, 'tryTimes' => $tryTimes, 'time' => date('Ymd H:i', $time), 'msg' => $e->getMessage()], 'getAliMonitorError.log');
  141. if($tryTimes<10)return $this->getAliMonitor($method, $tryTimes);
  142. return 0;
  143. }
  144. // 复制代码运行请自行打印 API 的返回值
  145. $online = 0;
  146. $data = @json_decode($json, true);
  147. foreach ($data as $item){
  148. $online+=$item['Average'];
  149. }
  150. if(empty($online)){
  151. oo::logs()->debug3(['called location' => $method, 'tryTimes' => $tryTimes, 'time' => date('Ymd H:i', $time), 'response' => $result->body], 'getAliMonitor.log');
  152. }
  153. oo::logs()->debug3(['called location' => $method, 'tryTimes' => $tryTimes, 'time' => date('Ymd H:i', $time), 'online' => $online], 'getAliMonitor.log');
  154. return $online;
  155. }
  156. /**
  157. * 登录监控
  158. * Created by: Owen
  159. * Created on: 2020/4/24 19:54
  160. */
  161. public function loginMonitor(){
  162. $second = timeFuns::todaySecond();
  163. $cacheKey = okeys::LoginMonitor(1);
  164. $curKey = intval($second/5) - 1;
  165. if($curKey == -1){
  166. $curKey = 287; //读取前一天最后一个点数据,如果没有则读取当天0点数据
  167. $loginNum = oo::commonOprRedis('common')->hGet($cacheKey,$curKey);
  168. $loginNum = empty($loginNum) ? oo::commonOprRedis('common')->hGet($cacheKey, 0) : $loginNum;
  169. }else{
  170. $loginNum = oo::commonOprRedis('common')->hGet($cacheKey,$curKey);
  171. }
  172. if(!$loginNum){
  173. $date = date('Y-m-d H:i:s');
  174. !IS_DEBUF && oo::commonOprModel('Enwechat')->send("【警报】{$date} -- 安卓端:5分钟内登录人数为0",[],[],1);
  175. }
  176. }
  177. /**
  178. * 登录监控AB分组
  179. */
  180. public function loginMonitorAb(){
  181. $mkey = "MONITORABTEST";
  182. $time = (int)oo::commonOprRedis('statistics')->get($mkey);
  183. /////////////////////////////////
  184. //$time = 0;
  185. /////////////////////////////////
  186. $min = $time ? $time % 60 : 0;
  187. $hour = $time ? floor(($time) / 60) : 0;
  188. $dayTime = date('Y-m-d ', time()).sprintf('%02d', $hour).':'.sprintf('%02d', $min).':00';
  189. $day = date('Ymd');
  190. $stamp = strtotime($dayTime);
  191. $endStamp = strtotime(date('Y-m-d H:i:00', time()));
  192. /////////////////////////////////
  193. //$stamp = $stamp - 86400;
  194. //$endStamp = $endStamp + 86400;
  195. //$day = $day - 1;
  196. ////////////////////////////////
  197. $tb = otable::LoginLog($day);
  198. $sql = "SELECT uid FROM {$tb} Where ts >= {$stamp} AND ts < {$endStamp}";
  199. $tmpArr = oo::commonOprDb('statistics')->getAll($sql, 1);
  200. $uids = [];
  201. foreach($tmpArr as $val){
  202. if(!in_array($val['uid'], $uids)){
  203. $uids[] = $val['uid'];
  204. }
  205. }
  206. //ab分组数据
  207. $abGroupArr = oo::commonOprRedis('common')->hMget(okeys::UserAbTest(), $uids);
  208. $arr = [];
  209. foreach($abGroupArr as $uid => $key){
  210. if(empty($key) || $key < 1){
  211. $key = 'D';
  212. }elseif($key > 2){
  213. $key = 'C';
  214. }else{
  215. $key = $key == '1' ? 'A' : 'B';
  216. }
  217. if(empty($arr[$key])){
  218. $arr[$key] = [$uid];
  219. }
  220. $arr[$key][] = $uid;
  221. }
  222. foreach($arr as $key => $uids){
  223. $uidStr = implode(',', $uids);
  224. $sql = "UPDATE {$tb} SET ab = '{$key}' WHERE uid in ({$uidStr})";
  225. oo::commonOprDb('statistics')->query($sql);
  226. }
  227. oo::commonOprRedis('statistics')->setex($mkey, $stamp, 86400);
  228. return true;
  229. }
  230. /**
  231. * 15分钟检查一次谷歌支付是否正常
  232. */
  233. public function checkGooglePayStatus() {
  234. $tb = otable::summarylist();
  235. $time = time() - 900;
  236. $subOrders = "801,802,803";
  237. $sql = "SELECT COUNT(*) as count FROM {$tb} WHERE sl_sid = 1 AND sl_status = 2 AND sl_pay_time >= {$time} AND sl_gid NOT IN({$subOrders})";
  238. $ret = oo::commonOprDb('payment')->getOne($sql, 1);
  239. if(empty($ret['count'])){
  240. $date = date('Ymd', time());
  241. !IS_DEBUF && oo::commonOprModel('Enwechat')->send("【警报】{$date} :谷歌支付15分钟内没有成功支付订单了!",[],[],1);
  242. }
  243. }
  244. // fox 实时在线统计
  245. public function saveFoxRealTimeOnline($timestamp = 0, $onlineCnt = 0){
  246. $timestamp = empty($timestamp) ? time() : $timestamp ;
  247. $date = date('Ymd', $timestamp);
  248. // $start = $timestamp - 61;
  249. // $onlineCnt = $this->getAliMonitor(__METHOD__);//oo::commonOprRedis('common')->zCount(okeys::foxRealTimeOnlineKey(),$start, $timestamp);
  250. oo::commonOprRedis('statistics')->hSet(okeys::foxOnlineSummaryKey($date),$timestamp, $onlineCnt);
  251. $hi = date('Hi', $timestamp);
  252. if($hi == '0030'){
  253. // 上一天fox在线信息入库
  254. $yesterday = date('Ymd', $timestamp - 86400);
  255. $ret = oo::commonOprRedis('statistics')->hGetAll(okeys::foxOnlineSummaryKey($yesterday));
  256. $data['1'] = $ret;
  257. $data = json_encode($data,JSON_NUMERIC_CHECK);
  258. $tb = otable::staData();
  259. $type = 'foxOnlinePlaying';
  260. $sql = "INSERT INTO {$tb} VALUES('{$yesterday}', '{$type}' ,'{$data}')";
  261. oo::commonOprDb('statistics')->query($sql);
  262. oo::commonOprRedis('statistics')->delete(okeys::foxOnlineSummaryKey($yesterday));
  263. }
  264. }
  265. public function cardAssertSummary($timestamp, $type = 1){
  266. ini_set('memory_limit', -1);
  267. $date = date('Ymd', $timestamp - 86400);
  268. $cardInfoTbl = otable::cardinfo_config();
  269. $cardInfo = oo::commonOprDb('common')->getAll("select * from {$cardInfoTbl}",1);
  270. $cardInfo = array_column($cardInfo, null, 'ciid');
  271. $sql = "select * from ( ";
  272. for ($i = 0;$i<10;$i++){
  273. $table = otable::AssetslogNew($date, $i);
  274. $sql .= "select * from {$table} where type='card' ";
  275. if($date >= '20211109'){
  276. $sql .= " and game_version ={$type} ";
  277. }
  278. $sql .=" union all ";
  279. }
  280. $sql = rtrim($sql, 'union all ');
  281. $sql .= " ) t1 ";
  282. $result = oo::commonOprDb('statistics')->getAll($sql,1);
  283. $cardSummary = [
  284. '木质宝箱' => [
  285. 'count' => 0,
  286. 'total' => 0,
  287. 'rank1' => 0,
  288. 'rank2' => 0,
  289. 'rank3' => 0,
  290. 'rank4' => 0,
  291. 'rank5' => 0,
  292. 'golden' => 0,
  293. ],
  294. '白银宝箱' => [
  295. 'count' => 0,
  296. 'total' => 0,
  297. 'rank1' => 0,
  298. 'rank2' => 0,
  299. 'rank3' => 0,
  300. 'rank4' => 0,
  301. 'rank5' => 0,
  302. 'golden' => 0,
  303. ],
  304. '黄金宝箱' => [
  305. 'count' => 0,
  306. 'total' => 0,
  307. 'rank1' => 0,
  308. 'rank2' => 0,
  309. 'rank3' => 0,
  310. 'rank4' => 0,
  311. 'rank5' => 0,
  312. 'golden' => 0,
  313. ],
  314. '小丑宝箱获得' => [
  315. 'count' => 0,
  316. 'total' => 0,
  317. 'rank1' => 0,
  318. 'rank2' => 0,
  319. 'rank3' => 0,
  320. 'rank4' => 0,
  321. 'rank5' => 0,
  322. 'golden' => 0,
  323. ],
  324. '皮肤宝箱' => [
  325. 'count' => 0,
  326. 'total' => 0,
  327. 'rank1' => 0,
  328. 'rank2' => 0,
  329. 'rank3' => 0,
  330. 'rank4' => 0,
  331. 'rank5' => 0,
  332. 'golden' => 0,
  333. ],
  334. ];
  335. foreach ($result as $k => $item){
  336. if(!strpos($item['reason'], ':'))continue;
  337. list($chest, $cardStrs) = explode(':', $item['reason']);
  338. if(empty($cardSummary[$chest]))continue;
  339. $cardsIds = explode(',', $cardStrs);
  340. $cardSummary[$chest]['count']++;
  341. foreach ($cardsIds as $ciid){
  342. if(empty($cardInfo[$ciid]))continue;
  343. $cardSummary[$chest]['total']++;
  344. $cardSummary[$chest]['rank'.$cardInfo[$ciid]['ci_star_rank']]++;
  345. if($cardInfo[$ciid]['grade'] == 2)$cardSummary[$chest]['golden']++;
  346. }
  347. }
  348. $data = json_encode($cardSummary, JSON_UNESCAPED_UNICODE);
  349. $tb = otable::cardAssertSummary();
  350. $sql = "INSERT INTO {$tb} (`date`, `game_version`, `data`) VALUES('{$date}', '{$type}' ,'{$data}')";
  351. $res = oo::commonOprDb('statistics')->query($sql);
  352. return $res;
  353. }
  354. }