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