recordonline.php 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391
  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("【警报】FOX {$date} :5分钟内在线人数下降超过50%,由{$lastNum}人下降到{$onlineNum}人",[],[],1);
  87. // oo::commonOprModel('Enwechat')->send("【警报】FOX {$date} :5分钟内在线人数下降超过50%,由{$lastNum}人下降到{$onlineNum}人",[],[],1);
  88. }else if($onlineNum < ceil($lastNum*0.7)){
  89. oo::commonOprModel('Enwechat')->send("【警报】FOX {$date} :5分钟内在线人数下降超过30%,由{$lastNum}人下降到{$onlineNum}人",[],[],1);
  90. // oo::commonOprModel('Enwechat')->send("【警报】FOX {$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("【警报】FOX {$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("【警报】{$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, $isActivite = true){
  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-0xit9qxfipdrir7mp7za3',
  125. 'port' => '8282',
  126. ],
  127. [
  128. 'instanceId' => 'lb-0xii7gpzz1yhoqwt6n54v',
  129. 'port' => '8282',
  130. ],
  131. [
  132. 'instanceId' => 'lb-0xi150md3kw771ogor7wj',
  133. 'port' => '8282',
  134. ],
  135. [
  136. 'instanceId'=>'lb-0xi6u8dr6pa36pukbilm5',
  137. 'port' => '8282',
  138. ],
  139. [
  140. 'instanceId'=>'lb-0xi6cb3w46sthz2gywxzh',
  141. 'port' => '8282',
  142. ]
  143. ];
  144. $describeMetricLastRequest = new DescribeMetricLastRequest([
  145. "namespace" => "acs_slb_dashboard",
  146. "metricName" => $isActivite ? "ActiveConnection" : 'InactiveConnection',
  147. "dimensions" => json_encode($dimensions),
  148. ]);
  149. $result = $client->describeMetricLast($describeMetricLastRequest);
  150. $json = $result->body->datapoints;
  151. }catch(\throwable $e){
  152. oo::logs()->debug3(['called location' => $method, 'tryTimes' => $tryTimes, 'time' => date('Ymd H:i', $time), 'msg' => $e->getMessage()], 'getAliMonitorError.log');
  153. if($tryTimes<10)return $this->getAliMonitor($method, $tryTimes);
  154. return 0;
  155. }
  156. // 复制代码运行请自行打印 API 的返回值
  157. $online = 0;
  158. $data = @json_decode($json, true);
  159. foreach ($data as $item){
  160. $online+=$item['Average'];
  161. }
  162. if(empty($online)){
  163. oo::logs()->debug3(['called location' => $method, 'tryTimes' => $tryTimes, 'time' => date('Ymd H:i', $time), 'response' => $result->body], 'getAliMonitor.log');
  164. }
  165. oo::logs()->debug3(['called location' => $method, 'tryTimes' => $tryTimes, 'time' => date('Ymd H:i', $time), 'online' => $online], 'getAliMonitor.log');
  166. return $online;
  167. }
  168. /**
  169. * 登录监控
  170. * Created by: Owen
  171. * Created on: 2020/4/24 19:54
  172. */
  173. public function loginMonitor(){
  174. $second = timeFuns::todaySecond();
  175. $cacheKey = okeys::LoginMonitor(1);
  176. $curKey = intval($second/5) - 1;
  177. if($curKey == -1){
  178. $curKey = 287; //读取前一天最后一个点数据,如果没有则读取当天0点数据
  179. $loginNum = oo::commonOprRedis('common')->hGet($cacheKey,$curKey);
  180. $loginNum = empty($loginNum) ? oo::commonOprRedis('common')->hGet($cacheKey, 0) : $loginNum;
  181. }else{
  182. $loginNum = oo::commonOprRedis('common')->hGet($cacheKey,$curKey);
  183. }
  184. if(!$loginNum){
  185. $date = date('Y-m-d H:i:s');
  186. !IS_DEBUF && oo::commonOprModel('Enwechat')->send("【警报】{$date} -- 安卓端:5分钟内登录人数为0",[],[],1);
  187. }
  188. }
  189. /**
  190. * 登录监控AB分组
  191. */
  192. public function loginMonitorAb(){
  193. $mkey = "MONITORABTEST";
  194. $time = (int)oo::commonOprRedis('statistics')->get($mkey);
  195. /////////////////////////////////
  196. //$time = 0;
  197. /////////////////////////////////
  198. $min = $time ? $time % 60 : 0;
  199. $hour = $time ? floor(($time) / 60) : 0;
  200. $dayTime = date('Y-m-d ', time()).sprintf('%02d', $hour).':'.sprintf('%02d', $min).':00';
  201. $day = date('Ymd');
  202. $stamp = strtotime($dayTime);
  203. $endStamp = strtotime(date('Y-m-d H:i:00', time()));
  204. /////////////////////////////////
  205. //$stamp = $stamp - 86400;
  206. //$endStamp = $endStamp + 86400;
  207. //$day = $day - 1;
  208. ////////////////////////////////
  209. $tb = otable::LoginLog($day);
  210. $sql = "SELECT uid FROM {$tb} Where ts >= {$stamp} AND ts < {$endStamp}";
  211. $tmpArr = oo::commonOprDb('statistics')->getAll($sql, 1);
  212. $uids = [];
  213. foreach($tmpArr as $val){
  214. if(!in_array($val['uid'], $uids)){
  215. $uids[] = $val['uid'];
  216. }
  217. }
  218. //ab分组数据
  219. $abGroupArr = oo::commonOprRedis('common')->hMget(okeys::UserAbTest(), $uids);
  220. $arr = [];
  221. foreach($abGroupArr as $uid => $key){
  222. if(empty($key) || $key < 1){
  223. $key = 'D';
  224. }elseif($key > 2){
  225. $key = 'C';
  226. }else{
  227. $key = $key == '1' ? 'A' : 'B';
  228. }
  229. if(empty($arr[$key])){
  230. $arr[$key] = [$uid];
  231. }
  232. $arr[$key][] = $uid;
  233. }
  234. foreach($arr as $key => $uids){
  235. $uidStr = implode(',', $uids);
  236. $sql = "UPDATE {$tb} SET ab = '{$key}' WHERE uid in ({$uidStr})";
  237. oo::commonOprDb('statistics')->query($sql);
  238. }
  239. oo::commonOprRedis('statistics')->setex($mkey, $stamp, 86400);
  240. return true;
  241. }
  242. /**
  243. * 15分钟检查一次谷歌支付是否正常
  244. */
  245. public function checkGooglePayStatus() {
  246. $tb = otable::summarylist();
  247. $time = time() - 900;
  248. $subOrders = "801,802,803";
  249. $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})";
  250. $ret = oo::commonOprDb('payment')->getOne($sql, 1);
  251. if(empty($ret['count'])){
  252. $date = date('Ymd', time());
  253. !IS_DEBUF && oo::commonOprModel('Enwechat')->send("【警报】{$date} :谷歌支付15分钟内没有成功支付订单了!",[],[],1);
  254. }
  255. }
  256. // fox 实时在线统计
  257. public function saveFoxRealTimeOnline($timestamp = 0, $onlineCnt = 0){
  258. $timestamp = empty($timestamp) ? time() : $timestamp ;
  259. $date = date('Ymd', $timestamp);
  260. // $start = $timestamp - 61;
  261. // $onlineCnt = $this->getAliMonitor(__METHOD__);//oo::commonOprRedis('common')->zCount(okeys::foxRealTimeOnlineKey(),$start, $timestamp);
  262. oo::commonOprRedis('statistics')->hSet(okeys::foxOnlineSummaryKey($date),$timestamp, $onlineCnt);
  263. $hi = date('Hi', $timestamp);
  264. if($hi == '0030'){
  265. // 上一天fox在线信息入库
  266. $yesterday = date('Ymd', $timestamp - 86400);
  267. $ret = oo::commonOprRedis('statistics')->hGetAll(okeys::foxOnlineSummaryKey($yesterday));
  268. $data['1'] = $ret;
  269. $data = json_encode($data,JSON_NUMERIC_CHECK);
  270. $tb = otable::staData();
  271. $type = 'foxOnlinePlaying';
  272. $sql = "INSERT INTO {$tb} VALUES('{$yesterday}', '{$type}' ,'{$data}')";
  273. oo::commonOprDb('statistics')->query($sql);
  274. oo::commonOprRedis('statistics')->delete(okeys::foxOnlineSummaryKey($yesterday));
  275. }
  276. }
  277. public function cardAssertSummary($timestamp, $type = 1){
  278. ini_set('memory_limit', -1);
  279. $date = date('Ymd', $timestamp - 86400);
  280. $cardInfoTbl = otable::cardinfo_config();
  281. $cardInfo = oo::commonOprDb('common')->getAll("select * from {$cardInfoTbl}",1);
  282. $cardInfo = array_column($cardInfo, null, 'ciid');
  283. $sql = "select * from ( ";
  284. for ($i = 0;$i<10;$i++){
  285. $table = otable::AssetslogNew($date, $i);
  286. $sql .= "select * from {$table} where type='card' ";
  287. if($date >= '20211109'){
  288. $sql .= " and game_version ={$type} ";
  289. }
  290. $sql .=" union all ";
  291. }
  292. $sql = rtrim($sql, 'union all ');
  293. $sql .= " ) t1 ";
  294. $result = oo::commonOprDb('statistics')->getAll($sql,1);
  295. $cardSummary = [
  296. '木质宝箱' => [
  297. 'count' => 0,
  298. 'total' => 0,
  299. 'rank1' => 0,
  300. 'rank2' => 0,
  301. 'rank3' => 0,
  302. 'rank4' => 0,
  303. 'rank5' => 0,
  304. 'golden' => 0,
  305. ],
  306. '白银宝箱' => [
  307. 'count' => 0,
  308. 'total' => 0,
  309. 'rank1' => 0,
  310. 'rank2' => 0,
  311. 'rank3' => 0,
  312. 'rank4' => 0,
  313. 'rank5' => 0,
  314. 'golden' => 0,
  315. ],
  316. '黄金宝箱' => [
  317. 'count' => 0,
  318. 'total' => 0,
  319. 'rank1' => 0,
  320. 'rank2' => 0,
  321. 'rank3' => 0,
  322. 'rank4' => 0,
  323. 'rank5' => 0,
  324. 'golden' => 0,
  325. ],
  326. '小丑宝箱获得' => [
  327. 'count' => 0,
  328. 'total' => 0,
  329. 'rank1' => 0,
  330. 'rank2' => 0,
  331. 'rank3' => 0,
  332. 'rank4' => 0,
  333. 'rank5' => 0,
  334. 'golden' => 0,
  335. ],
  336. '皮肤宝箱' => [
  337. 'count' => 0,
  338. 'total' => 0,
  339. 'rank1' => 0,
  340. 'rank2' => 0,
  341. 'rank3' => 0,
  342. 'rank4' => 0,
  343. 'rank5' => 0,
  344. 'golden' => 0,
  345. ],
  346. ];
  347. foreach ($result as $k => $item){
  348. if(!strpos($item['reason'], ':'))continue;
  349. list($chest, $cardStrs) = explode(':', $item['reason']);
  350. if(empty($cardSummary[$chest]))continue;
  351. $cardsIds = explode(',', $cardStrs);
  352. $cardSummary[$chest]['count']++;
  353. foreach ($cardsIds as $ciid){
  354. if(empty($cardInfo[$ciid]))continue;
  355. $cardSummary[$chest]['total']++;
  356. $cardSummary[$chest]['rank'.$cardInfo[$ciid]['ci_star_rank']]++;
  357. if($cardInfo[$ciid]['grade'] == 2)$cardSummary[$chest]['golden']++;
  358. }
  359. }
  360. $data = json_encode($cardSummary, JSON_UNESCAPED_UNICODE);
  361. $tb = otable::cardAssertSummary();
  362. $sql = "INSERT INTO {$tb} (`date`, `game_version`, `data`) VALUES('{$date}', '{$type}' ,'{$data}')";
  363. $res = oo::commonOprDb('statistics')->query($sql);
  364. return $res;
  365. }
  366. }