mirror of
https://github.com/lkddi/nexusphp.git
synced 2026-04-03 14:10:57 +08:00
88 lines
3.1 KiB
PHP
88 lines
3.1 KiB
PHP
|
|
<?php
|
||
|
|
|
||
|
|
namespace App\Repositories;
|
||
|
|
|
||
|
|
use App\Models\IpLog;
|
||
|
|
use Carbon\Carbon;
|
||
|
|
use Nexus\Database\NexusDB;
|
||
|
|
|
||
|
|
class IpLogRepository extends BaseRepository
|
||
|
|
{
|
||
|
|
const CACHE_KEY_PREFIX = 'nexus_ip_logs';
|
||
|
|
|
||
|
|
private const CACHE_TIME = 72 * 3600;
|
||
|
|
|
||
|
|
public static function saveToCache($userId, $uri = null, $ipArr = null): void
|
||
|
|
{
|
||
|
|
if (!is_numeric($userId) || $userId <= 0) {
|
||
|
|
do_log("invalid userId: $userId", "error");
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
$redis = NexusDB::redis();
|
||
|
|
if (is_null($uri)) {
|
||
|
|
$parsed_uri = parse_url($_SERVER['REQUEST_URI']);
|
||
|
|
$uri = $parsed_uri['path'];
|
||
|
|
}
|
||
|
|
if (is_null($ipArr)) {
|
||
|
|
$ipArr = [getip()];
|
||
|
|
}
|
||
|
|
$key = sprintf("%s:%s", self::CACHE_KEY_PREFIX, date('Y-m-d-H'));
|
||
|
|
foreach ($ipArr as $ip) {
|
||
|
|
$field = sprintf("%s|%s|%s", $userId, $ip, $uri);
|
||
|
|
$result = $redis->hincrby($key, $field, 1);
|
||
|
|
do_log("success hincrby $key $field, result: $result", "debug");
|
||
|
|
if ($result === 1) {
|
||
|
|
$redis->expire($key, self::CACHE_TIME);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
public static function saveToDB(): void
|
||
|
|
{
|
||
|
|
$beginTimestamp = microtime(true);
|
||
|
|
$redis = NexusDB::redis();
|
||
|
|
$begin = Carbon::now()->subSeconds(self::CACHE_TIME);
|
||
|
|
$end = Carbon::now()->subHours(1);
|
||
|
|
$interval =\DateInterval::createFromDateString("1 hour");
|
||
|
|
$period = new \DatePeriod($begin->clone(), $interval, $end);
|
||
|
|
$size = 2000;
|
||
|
|
do_log(sprintf("begin: %s, end: %s, size: %s", $begin->toDateTimeString(), $end->toDateTimeString(), $size));
|
||
|
|
$redis->setOption(\Redis::OPT_SCAN, \Redis::SCAN_RETRY);
|
||
|
|
foreach ($period as $dt) {
|
||
|
|
$key = sprintf("%s:%s", self::CACHE_KEY_PREFIX, $dt->format('Y-m-d-H'));
|
||
|
|
if (!$redis->exists($key)) {
|
||
|
|
do_log("key: $key not found", "debug");
|
||
|
|
continue;
|
||
|
|
}
|
||
|
|
if ($redis->hlen($key) == 0) {
|
||
|
|
do_log("key: $key length = 0", "debug");
|
||
|
|
$redis->unlink($key);
|
||
|
|
}
|
||
|
|
do_log("handing key: $key");
|
||
|
|
//遍历hash
|
||
|
|
$it = NULL;
|
||
|
|
while($arr_keys = $redis->hScan($key, $it, "*", $size)) {
|
||
|
|
$insert = [];
|
||
|
|
foreach ($arr_keys as $field => $value) {
|
||
|
|
list($userId, $ip, $uri) = explode("|", $field);
|
||
|
|
$insert[] = [
|
||
|
|
'userid' => $userId,
|
||
|
|
'ip' => $ip,
|
||
|
|
'uri' => $uri,
|
||
|
|
'access' => date("Y-m-d H:i:s"),
|
||
|
|
'count' => intval($value),
|
||
|
|
];
|
||
|
|
}
|
||
|
|
if (!empty($insert)) {
|
||
|
|
IpLog::query()->insert($insert);
|
||
|
|
}
|
||
|
|
do_log("key: $key, it: $it, count: " . count($insert));
|
||
|
|
}
|
||
|
|
$redis->unlink($key);
|
||
|
|
do_log("handle key: $key done!");
|
||
|
|
}
|
||
|
|
do_log(sprintf("all done! cost time: %.3f sec.", microtime(true) - $beginTimestamp));
|
||
|
|
}
|
||
|
|
|
||
|
|
}
|