This commit is contained in:
wangw 2025-08-06 11:08:02 +08:00
parent 546540bbf1
commit 1d30708270
1 changed files with 122 additions and 122 deletions

View File

@ -1,42 +1,82 @@
package com.sqx.common.aspect;
import lombok.extern.slf4j.Slf4j;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
/**
* @author GYJoker
*/
@Slf4j
public class IpAccessCounter {
// 记录 IP 及其每次访问的时间列表
private static final Map<String, List<Long>> IP_ACCESS_TIMES = new ConcurrentHashMap<>();
// 黑名单记录 IP 及其加入黑名单的时间
private static final Map<String, Long> BLACKLIST = new ConcurrentHashMap<>();
// 一分钟的毫秒数
private static final long ONE_MINUTE = 60 * 1000;
// 十分钟的毫秒数
private static final long TEN_MINUTES = 3 * 10 * ONE_MINUTE;
private static AtomicInteger removeCount = new AtomicInteger(0);
// static {
// // 定时任务每分钟清理一次访问记录
// ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);
// executor.scheduleAtFixedRate(() -> {
//package com.sqx.common.aspect;
//
//import lombok.extern.slf4j.Slf4j;
//
//import java.util.*;
//import java.util.concurrent.ConcurrentHashMap;
//import java.util.concurrent.Executors;
//import java.util.concurrent.ScheduledExecutorService;
//import java.util.concurrent.TimeUnit;
//import java.util.concurrent.atomic.AtomicInteger;
//
///**
// * @author GYJoker
// */
//@Slf4j
//public class IpAccessCounter {
// // 记录 IP 及其每次访问的时间列表
// private static final Map<String, List<Long>> IP_ACCESS_TIMES = new ConcurrentHashMap<>();
// // 黑名单记录 IP 及其加入黑名单的时间
// private static final Map<String, Long> BLACKLIST = new ConcurrentHashMap<>();
// // 一分钟的毫秒数
// private static final long ONE_MINUTE = 60 * 1000;
// // 十分钟的毫秒数
// private static final long TEN_MINUTES = 3 * 10 * ONE_MINUTE;
//
// private static AtomicInteger removeCount = new AtomicInteger(0);
//
//// static {
//// // 定时任务每分钟清理一次访问记录
//// ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);
//// executor.scheduleAtFixedRate(() -> {
//// try {
//// long currentTime = System.currentTimeMillis();
//// Set<String> removedIps = new HashSet<>();
//// IP_ACCESS_TIMES.forEach((ip, accessTimes) -> {
//// accessTimes.removeIf(time -> currentTime - time > ONE_MINUTE);
//// if (accessTimes.isEmpty()) {
//// removedIps.add(ip);
//// }
//// });
//// removedIps.forEach(IP_ACCESS_TIMES::remove);
////
//// Set<String> removedBlacklistIps = new HashSet<>();
//// BLACKLIST.entrySet().removeIf(entry -> {
//// boolean shouldRemove = currentTime - entry.getValue() > TEN_MINUTES;
//// if (shouldRemove) {
//// removedBlacklistIps.add(entry.getKey());
//// }
//// return shouldRemove;
//// });
////
//// log.info("IpAccessCounter 清理完成,移除了 {} 个 IP 的黑名单记录,当前 BLACKLIST 大小: {}, IP_ACCESS_TIMES 大小: {}",
//// removedBlacklistIps.size(), BLACKLIST.size(), IP_ACCESS_TIMES.size());
//// } catch (Exception e) {
//// log.error("定时任务异常", e);
//// }
//// }, ONE_MINUTE, 20000, TimeUnit.MINUTES);
//// }
//
// public static void removeOldInfo() {
// synchronized (IpAccessCounter.class) {
// try {
// removeCount.set(0);
// long currentTime = System.currentTimeMillis();
// Set<String> removedIps = new HashSet<>();
//// for (Map.Entry<String, List<Long>> entry : IP_ACCESS_TIMES.entrySet()) {
//// List<Long> accessTimes = entry.getValue();
//// accessTimes.removeIf(time -> currentTime - time > ONE_MINUTE);
//// if (accessTimes.isEmpty()) {
//// removedIps.add(entry.getKey());
//// }
//// }
// IP_ACCESS_TIMES.forEach((ip, accessTimes) -> {
// if (accessTimes != null && !accessTimes.isEmpty()) {
// accessTimes.removeIf(time -> currentTime - time > ONE_MINUTE);
// if (accessTimes.isEmpty()) {
// removedIps.add(ip);
// }
// }
// });
// removedIps.forEach(IP_ACCESS_TIMES::remove);
//
@ -54,92 +94,52 @@ public class IpAccessCounter {
// } catch (Exception e) {
// log.error("定时任务异常", e);
// }
// }, ONE_MINUTE, 20000, TimeUnit.MINUTES);
// }
public static void removeOldInfo() {
synchronized (IpAccessCounter.class) {
try {
removeCount.set(0);
long currentTime = System.currentTimeMillis();
Set<String> removedIps = new HashSet<>();
// for (Map.Entry<String, List<Long>> entry : IP_ACCESS_TIMES.entrySet()) {
// List<Long> accessTimes = entry.getValue();
// accessTimes.removeIf(time -> currentTime - time > ONE_MINUTE);
// if (accessTimes.isEmpty()) {
// removedIps.add(entry.getKey());
// }
// }
IP_ACCESS_TIMES.forEach((ip, accessTimes) -> {
if (accessTimes != null && !accessTimes.isEmpty()) {
accessTimes.removeIf(time -> currentTime - time > ONE_MINUTE);
if (accessTimes.isEmpty()) {
removedIps.add(ip);
}
}
});
removedIps.forEach(IP_ACCESS_TIMES::remove);
Set<String> removedBlacklistIps = new HashSet<>();
BLACKLIST.entrySet().removeIf(entry -> {
boolean shouldRemove = currentTime - entry.getValue() > TEN_MINUTES;
if (shouldRemove) {
removedBlacklistIps.add(entry.getKey());
}
return shouldRemove;
});
log.info("IpAccessCounter 清理完成,移除了 {} 个 IP 的黑名单记录,当前 BLACKLIST 大小: {}, IP_ACCESS_TIMES 大小: {}",
removedBlacklistIps.size(), BLACKLIST.size(), IP_ACCESS_TIMES.size());
} catch (Exception e) {
log.error("定时任务异常", e);
}
}
}
// 检查 IP 是否可以访问
public static boolean canAccess(String ip, Integer maxAccessCount) {
removeCount.getAndIncrement();
if (removeCount.get() > 400) {
removeOldInfo();
}
if (isBlacklisted(ip)) {
return false;
}
long currentTime = System.currentTimeMillis();
List<Long> accessTimes = IP_ACCESS_TIMES.computeIfAbsent(ip, k -> new ArrayList<>());
// 移除超过一分钟的访问时间记录
if (accessTimes.size() + 1 > maxAccessCount) {
addToBlacklist(ip);
log.info("IP {} 因一分钟内访问次数超过 {} 次,被加入黑名单, BLACKLIST 大小: {}, IP_ACCESS_TIMES 大小: {}", ip, maxAccessCount, BLACKLIST.size(), IP_ACCESS_TIMES.size());
return false;
}
accessTimes.add(currentTime);
return true;
}
// 检查 IP 是否在黑名单中
private static boolean isBlacklisted(String ip) {
return BLACKLIST.containsKey(ip) && System.currentTimeMillis() - BLACKLIST.get(ip) <= TEN_MINUTES;
}
// IP 加入黑名单
private static void addToBlacklist(String ip) {
BLACKLIST.put(ip, System.currentTimeMillis());
IP_ACCESS_TIMES.remove(ip);
}
public static void main(String[] args) throws InterruptedException {
String testIp = "192.168.1.1";
for (int i = 0; i < 150; i++) {
System.out.println("Attempt " + (i + 1) + ": " + (canAccess(testIp, 120) ? "Allowed" : "Blocked"));
}
Thread.sleep(60 * 1000);
for (int i = 0; i < 150; i++) {
System.out.println("Attempt " + (i + 1) + ": " + (canAccess(testIp, 120) ? "Allowed" : "Blocked"));
}
}
}
//
// // 检查 IP 是否可以访问
// public static boolean canAccess(String ip, Integer maxAccessCount) {
// removeCount.getAndIncrement();
// if (removeCount.get() > 400) {
// removeOldInfo();
// }
// if (isBlacklisted(ip)) {
// return false;
// }
// long currentTime = System.currentTimeMillis();
// List<Long> accessTimes = IP_ACCESS_TIMES.computeIfAbsent(ip, k -> new ArrayList<>());
// // 移除超过一分钟的访问时间记录
// if (accessTimes.size() + 1 > maxAccessCount) {
// addToBlacklist(ip);
// log.info("IP {} 因一分钟内访问次数超过 {} 次,被加入黑名单, BLACKLIST 大小: {}, IP_ACCESS_TIMES 大小: {}", ip, maxAccessCount, BLACKLIST.size(), IP_ACCESS_TIMES.size());
// return false;
// }
//
// accessTimes.add(currentTime);
// return true;
// }
//
// // 检查 IP 是否在黑名单中
// private static boolean isBlacklisted(String ip) {
// return BLACKLIST.containsKey(ip) && System.currentTimeMillis() - BLACKLIST.get(ip) <= TEN_MINUTES;
// }
//
// // IP 加入黑名单
// private static void addToBlacklist(String ip) {
// BLACKLIST.put(ip, System.currentTimeMillis());
// IP_ACCESS_TIMES.remove(ip);
// }
//
// public static void main(String[] args) throws InterruptedException {
// String testIp = "192.168.1.1";
// for (int i = 0; i < 150; i++) {
// System.out.println("Attempt " + (i + 1) + ": " + (canAccess(testIp, 120) ? "Allowed" : "Blocked"));
// }
//
// Thread.sleep(60 * 1000);
//
// for (int i = 0; i < 150; i++) {
// System.out.println("Attempt " + (i + 1) + ": " + (canAccess(testIp, 120) ? "Allowed" : "Blocked"));
// }
// }
//}