Addition of precautionary restart manager.

This commit is contained in:
MobiusDevelopment
2020-12-19 22:30:07 +00:00
parent c3f1d2b407
commit 66ea8f6540
105 changed files with 5380 additions and 0 deletions

View File

@ -1162,6 +1162,12 @@ public class Config
public static int SERVER_RESTART_SCHEDULE_COUNTDOWN;
public static String[] SERVER_RESTART_SCHEDULE;
public static List<Integer> SERVER_RESTART_DAYS;
public static boolean PRECAUTIONARY_RESTART_ENABLED;
public static boolean PRECAUTIONARY_RESTART_CPU;
public static boolean PRECAUTIONARY_RESTART_MEMORY;
public static boolean PRECAUTIONARY_RESTART_CHECKS;
public static int PRECAUTIONARY_RESTART_PERCENTAGE;
public static int PRECAUTIONARY_RESTART_DELAY;
public static int IP_UPDATE_TIME;
public static boolean SHOW_LICENCE;
@ -1263,6 +1269,12 @@ public class Config
SERVER_RESTART_DAYS.add(Integer.parseInt(day));
}
}
PRECAUTIONARY_RESTART_ENABLED = serverConfig.getBoolean("PrecautionaryRestartEnabled", false);
PRECAUTIONARY_RESTART_CPU = serverConfig.getBoolean("PrecautionaryRestartCpu", true);
PRECAUTIONARY_RESTART_MEMORY = serverConfig.getBoolean("PrecautionaryRestartMemory", false);
PRECAUTIONARY_RESTART_CHECKS = serverConfig.getBoolean("PrecautionaryRestartChecks", true);
PRECAUTIONARY_RESTART_PERCENTAGE = serverConfig.getInt("PrecautionaryRestartPercentage", 95);
PRECAUTIONARY_RESTART_DELAY = serverConfig.getInt("PrecautionaryRestartDelay", 60) * 1000;
}
public static void loadTelnetConfig()

View File

@ -104,6 +104,7 @@ import org.l2jmobius.gameserver.instancemanager.IdManager;
import org.l2jmobius.gameserver.instancemanager.ItemsOnGroundManager;
import org.l2jmobius.gameserver.instancemanager.MercTicketManager;
import org.l2jmobius.gameserver.instancemanager.PetitionManager;
import org.l2jmobius.gameserver.instancemanager.PrecautionaryRestartManager;
import org.l2jmobius.gameserver.instancemanager.QuestManager;
import org.l2jmobius.gameserver.instancemanager.RaidBossPointsManager;
import org.l2jmobius.gameserver.instancemanager.RaidBossSpawnManager;
@ -483,6 +484,11 @@ public class GameServer
ServerRestartManager.getInstance();
}
if (Config.PRECAUTIONARY_RESTART_ENABLED)
{
PrecautionaryRestartManager.getInstance();
}
System.gc();
Util.printSection("Info");

View File

@ -31,6 +31,7 @@ import org.l2jmobius.gameserver.instancemanager.FishingChampionshipManager;
import org.l2jmobius.gameserver.instancemanager.GlobalVariablesManager;
import org.l2jmobius.gameserver.instancemanager.GrandBossManager;
import org.l2jmobius.gameserver.instancemanager.ItemsOnGroundManager;
import org.l2jmobius.gameserver.instancemanager.PrecautionaryRestartManager;
import org.l2jmobius.gameserver.instancemanager.QuestManager;
import org.l2jmobius.gameserver.instancemanager.RaidBossSpawnManager;
import org.l2jmobius.gameserver.model.World;
@ -195,6 +196,11 @@ public class Shutdown extends Thread
_counterInstance._abort();
}
if (Config.PRECAUTIONARY_RESTART_ENABLED)
{
PrecautionaryRestartManager.getInstance().restartEnabled();
}
// the main instance should only run for shutdown hook, so we start a new instance
_counterInstance = new Shutdown(seconds, restart);
_counterInstance.start();
@ -221,6 +227,11 @@ public class Shutdown extends Thread
{
_counterInstance._abort();
}
if (Config.PRECAUTIONARY_RESTART_ENABLED)
{
PrecautionaryRestartManager.getInstance().restartAborted();
}
}
/**

View File

@ -0,0 +1,198 @@
/*
* This file is part of the L2J Mobius project.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.l2jmobius.gameserver.instancemanager;
import java.lang.management.ManagementFactory;
import java.util.logging.Logger;
import javax.management.Attribute;
import javax.management.AttributeList;
import javax.management.MBeanServer;
import javax.management.ObjectName;
import org.l2jmobius.Config;
import org.l2jmobius.commons.concurrent.ThreadPool;
import org.l2jmobius.gameserver.Shutdown;
import org.l2jmobius.gameserver.enums.ChatType;
import org.l2jmobius.gameserver.model.World;
import org.l2jmobius.gameserver.model.WorldObject;
import org.l2jmobius.gameserver.model.actor.instance.GrandBossInstance;
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
import org.l2jmobius.gameserver.model.actor.instance.RaidBossInstance;
import org.l2jmobius.gameserver.model.siege.Castle;
import org.l2jmobius.gameserver.model.siege.Fort;
import org.l2jmobius.gameserver.network.serverpackets.CreatureSay;
import org.l2jmobius.gameserver.util.Broadcast;
/**
* @author Mobius
*/
public class PrecautionaryRestartManager
{
private static final Logger LOGGER = Logger.getLogger(PrecautionaryRestartManager.class.getName());
private static final String SYSTEM_CPU_LOAD_VAR = "SystemCpuLoad";
private static final String PROCESS_CPU_LOAD_VAR = "ProcessCpuLoad";
private static boolean _restarting = false;
protected PrecautionaryRestartManager()
{
ThreadPool.scheduleAtFixedRate(() ->
{
if (_restarting)
{
return;
}
if (Config.PRECAUTIONARY_RESTART_CPU && (getCpuLoad(SYSTEM_CPU_LOAD_VAR) > Config.PRECAUTIONARY_RESTART_PERCENTAGE))
{
if (serverBizzy())
{
return;
}
LOGGER.info("PrecautionaryRestartManager: CPU usage over " + Config.PRECAUTIONARY_RESTART_PERCENTAGE + "%.");
LOGGER.info("PrecautionaryRestartManager: Server is using " + getCpuLoad(PROCESS_CPU_LOAD_VAR) + "%.");
Broadcast.toAllOnlinePlayers(new CreatureSay(-1, ChatType.ANNOUNCEMENT, "", "Server will restart in 10 minutes."));
Shutdown.getInstance().startShutdown(null, 600, true);
}
if (Config.PRECAUTIONARY_RESTART_MEMORY && (getProcessRamLoad() > Config.PRECAUTIONARY_RESTART_PERCENTAGE))
{
if (serverBizzy())
{
return;
}
LOGGER.info("PrecautionaryRestartManager: Memory usage over " + Config.PRECAUTIONARY_RESTART_PERCENTAGE + "%.");
Broadcast.toAllOnlinePlayers(new CreatureSay(-1, ChatType.ANNOUNCEMENT, "", "Server will restart in 10 minutes."));
Shutdown.getInstance().startShutdown(null, 600, true);
}
}, Config.PRECAUTIONARY_RESTART_DELAY, Config.PRECAUTIONARY_RESTART_DELAY);
}
private static double getCpuLoad(String var)
{
try
{
final MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
final ObjectName name = ObjectName.getInstance("java.lang:type=OperatingSystem");
final AttributeList list = mbs.getAttributes(name, new String[]
{
var
});
if (list.isEmpty())
{
return 0;
}
final Attribute att = (Attribute) list.get(0);
final Double value = (Double) att.getValue();
if (value == -1)
{
return 0;
}
return (value * 1000) / 10d;
}
catch (Exception e)
{
}
return 0;
}
private static double getProcessRamLoad()
{
final Runtime runTime = Runtime.getRuntime();
final long totalMemory = runTime.maxMemory();
final long usedMemory = totalMemory - ((totalMemory - runTime.totalMemory()) + runTime.freeMemory());
return (usedMemory * 100) / totalMemory;
}
private boolean serverBizzy()
{
for (Castle castle : CastleManager.getInstance().getCastles())
{
if ((castle != null) && castle.getSiege().isInProgress())
{
return true;
}
}
for (Fort fort : FortManager.getInstance().getForts())
{
if ((fort != null) && fort.getSiege().isInProgress())
{
return true;
}
}
for (PlayerInstance player : World.getInstance().getAllPlayers())
{
if ((player == null) || player.isInOfflineMode())
{
continue;
}
if (player.isInOlympiadMode())
{
return true;
}
if (player._inEvent || player.atEvent)
{
return true;
}
if (player.getInstanceId() > 0)
{
return true;
}
final WorldObject target = player.getTarget();
if ((target instanceof RaidBossInstance) || (target instanceof GrandBossInstance))
{
return true;
}
}
return false;
}
public void restartEnabled()
{
_restarting = true;
}
public void restartAborted()
{
_restarting = false;
}
public static PrecautionaryRestartManager getInstance()
{
return SingletonHolder.INSTANCE;
}
private static class SingletonHolder
{
protected static final PrecautionaryRestartManager INSTANCE = new PrecautionaryRestartManager();
}
}