From 951219b8dfa0fb45a45e26b8bf502d34194d2159 Mon Sep 17 00:00:00 2001 From: grimm <1769111741@qq.com> Date: Mon, 6 May 2024 16:13:53 +0800 Subject: [PATCH] =?UTF-8?q?=E7=94=A8=E6=88=B7=E7=BC=93=E5=AD=98=E4=BF=AE?= =?UTF-8?q?=E6=94=B9=EF=BC=8C=E6=94=B9=E4=B8=BA=E7=BA=BF=E7=A8=8B=E5=AE=89?= =?UTF-8?q?=E5=85=A8=E5=BE=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit (cherry picked from commit ddca7dfd7f64c1588ede3e34071cd03e89fede6b) --- .../ljsd/jieling/logic/dao/UserManager.java | 64 ++++++++++++------- .../com/ljsd/jieling/logic/dao/root/User.java | 15 ++++- .../ljsd/jieling/thread/ThreadManager.java | 2 +- 3 files changed, 55 insertions(+), 26 deletions(-) diff --git a/serverlogic/src/main/java/com/ljsd/jieling/logic/dao/UserManager.java b/serverlogic/src/main/java/com/ljsd/jieling/logic/dao/UserManager.java index b5e3f71e4..cbcc4a832 100644 --- a/serverlogic/src/main/java/com/ljsd/jieling/logic/dao/UserManager.java +++ b/serverlogic/src/main/java/com/ljsd/jieling/logic/dao/UserManager.java @@ -22,7 +22,6 @@ import com.ljsd.jieling.logic.mission.GameEvent; import com.ljsd.jieling.logic.mission.MissionType; import com.ljsd.jieling.logic.player.PlayerLogic; import com.ljsd.jieling.logic.store.newRechargeInfo.NewRechargeInfo; -import com.ljsd.jieling.util.DynamicLRUCache; import com.ljsd.jieling.util.ItemUtil; import com.ljsd.jieling.util.SysUtil; import config.SGameSetting; @@ -37,18 +36,21 @@ import java.io.IOException; import java.util.ArrayList; import java.util.List; import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; import java.util.concurrent.atomic.AtomicInteger; public class UserManager { private static final Logger LOGGER = LoggerFactory.getLogger(UserManager.class); // 玩家数据缓存 - private static final int maxMemoryLimit = 1000; // 最大内存限制,实际应由您的服务器规格决定 - private static final long LIVE_TIME = 60 * 60 * 1000L;// 离线玩家缓存保留时间(毫秒) - private static final DynamicLRUCache userMap = new DynamicLRUCache<>(600, LIVE_TIME); + private static volatile int maxMemoryLimit = 1000; // 最大内存限制,实际应由您的服务器规格决定 + private static final int LIVE_TIME = 60 * 60 * 1000;// 离线玩家缓存保留时间(毫秒) + private static final Map userMap = new ConcurrentHashMap<>(); private static final AtomicInteger login_f_num = new AtomicInteger(0);//登陆计数 public static void addUser(User user) { + user.setExpireTime(TimeUtils.now()); userMap.put(user.getId(), user); } @@ -69,27 +71,43 @@ public class UserManager { return OnlineUserManager.sessionMap.size(); } - // 这个方法可能由定时任务或某种监控服务调用 - public static void adjustCacheBasedOnCurrentLoad() { - // 调用缓存的调整方法来根据在线玩家数量调整缓存大小 + /** + * 离线清除逻辑 + * 这个方法可能由定时任务或某种监控服务调用 + */ + /** + * 离线清除逻辑 + * 这个方法可能由定时任务或某种监控服务调用 + */ + public static void checkOffline(){ Thread.currentThread().setName("user_cache_clean"); - userMap.shrinkToFit(); - } + long now = TimeUtils.now(); + List usersToRemove = new ArrayList<>(); - //离线清除逻辑 -// public static void checkOffline(){ -// try { -// long now = TimeUtils.now(); -// for (User user : userMap.getAll()) { -// if (OnlineUserManager.checkUidOnline(user.getId())){ -// continue; -// } -// } -// LOGGER.info("checkOffline left count={}", getUserMapSize()); -// }catch (Exception e){ -// LOGGER.error("Exception离线清除逻辑err={}",e.toString()); -// } -// } + try { + synchronized (userMap) { // 同步userMap以防止并发修改 + for (User user : userMap.values()) { + if (OnlineUserManager.checkUidOnline(user.getId())){ + continue; + } + + // 修正逻辑错误:检查用户是否已过期 + if (now - user.getExpireTime() >= LIVE_TIME){ + usersToRemove.add(user); + } + } + } + + // 移除过期的用户 + for (User user : usersToRemove) { + removeUser(user.getId()); + } + } catch (Exception e){ + LOGGER.error("Exception in offline cleanup logic", e); // 记录完整的异常信息 + } + + LOGGER.info("checkOffline last_count={}, consumer_time:{}ms", getUserMapSize(), TimeUtils.now()-now); + } public static User userLogin(int uid,String openId,String channel,int pid,int gid,String platform,String ip,String channle_id,String bundle_id,String ccId,String pack_Id) throws Exception { User user; diff --git a/serverlogic/src/main/java/com/ljsd/jieling/logic/dao/root/User.java b/serverlogic/src/main/java/com/ljsd/jieling/logic/dao/root/User.java index 38a613dae..23b4725d7 100644 --- a/serverlogic/src/main/java/com/ljsd/jieling/logic/dao/root/User.java +++ b/serverlogic/src/main/java/com/ljsd/jieling/logic/dao/root/User.java @@ -6,6 +6,7 @@ import com.ljsd.jieling.handler.map.MapManager; import com.ljsd.jieling.jbean.ActivityManager; import com.ljsd.jieling.jbean.gm.GmActivityManager; import com.ljsd.jieling.logic.dao.*; +import org.springframework.data.annotation.Transient; import org.springframework.data.mongodb.core.index.CompoundIndex; import org.springframework.data.mongodb.core.mapping.Document; @@ -17,6 +18,9 @@ public class User { private int id; + @Transient + private long expireTime;//缓存时间 + private PlayerManager playerManager; private ItemManager itemManager; @@ -60,9 +64,8 @@ public class User { private MagicSoldierManager magicSoldierManager; //TODO 新增manager 需要兼容旧的数据 提前判null - - //构造函数必须要声明,否则从mongodb读出来反编译成类不通过 public User(){ + //构造函数必须要声明,否则从mongodb读出来反编译成类不通过 } public User(int uid){ @@ -293,4 +296,12 @@ public class User { public MainLevelManager getMainLevelManager() { return mainLevelManager; } + + public long getExpireTime() { + return expireTime; + } + + public void setExpireTime(long expireTime) { + this.expireTime = expireTime; + } } diff --git a/serverlogic/src/main/java/com/ljsd/jieling/thread/ThreadManager.java b/serverlogic/src/main/java/com/ljsd/jieling/thread/ThreadManager.java index a51ec010b..e04176fb3 100644 --- a/serverlogic/src/main/java/com/ljsd/jieling/thread/ThreadManager.java +++ b/serverlogic/src/main/java/com/ljsd/jieling/thread/ThreadManager.java @@ -121,7 +121,7 @@ public class ThreadManager implements IManager { // 战力任务 TaskKit.scheduleAtFixedRate(new ForceRankTask(), 60,5, TimeUnit.SECONDS); // 每小时减容用户缓存 - TaskKit.scheduleAtFixedRate(UserManager::adjustCacheBasedOnCurrentLoad, 3, 1, TimeUnit.HOURS); + TaskKit.scheduleAtFixedRate(UserManager::checkOffline, 2, 1, TimeUnit.HOURS); // 定时重启线程池 scheduledFutureSets.add(scheduledExecutor.scheduleAtFixedRate(new Thread(() -> { long lastMilis = System.currentTimeMillis();