开服失败提示

master
duhui 2021-09-09 11:25:09 +08:00
parent a76c3aad9e
commit 9e8324412e
8 changed files with 207 additions and 89 deletions

View File

@ -37,7 +37,7 @@ public class ServerInfoController {
@Resource
private CommonManager commonManager;
@Resource
private SeqUtils seqUtils;
private AutoServerManager autoServerManager;
/**
*
@ -109,30 +109,40 @@ public class ServerInfoController {
public @ResponseBody
int toServerInfoEdit(HttpServletRequest request) throws Exception {
// 服务器id
String server_id = request.getParameter("server_id");
String serveId = request.getParameter("server_id");
// 名字
String name = request.getParameter("name");
// 服务器状态
int status = Integer.parseInt(request.getParameter("status"));
String status = request.getParameter("status");
// 新服
int isnew = Integer.parseInt(request.getParameter("is_new"));
String isNew = request.getParameter("is_new");
// 注册状态
String register_state = request.getParameter("register_state");
String registerState = request.getParameter("register_state");
ServerInfo info = serverInfoDao.getServerinfo(server_id);
ServerInfo info = serverInfoDao.getServerinfo(serveId);
// 未运营状态的服务器需要进行清库处理
if (info != null && Integer.parseInt(info.getStatus()) == ServerStatusEnum.NOT_OPERATE.getId()){
// 未运营状态需要验证自动开服状态
boolean open = AutoServerManager.getInstance().isOpen();
if (open){
return 3;
if (info != null){
// 未运营状态需要清库
if (Integer.parseInt(info.getStatus()) == ServerStatusEnum.NOT_OPERATE.getId()){
// 验证自动开服状态
if (AutoServerManager.isOpen()){
return 3;
}
ServerInfo clone = info.clone();
clone.setName(name);
clone.setStatus(status);
clone.setIs_new(isNew);
clone.setRegister_state(registerState);
// 清库操作
ThreadPoolManager.getInstance().execute(() -> autoServerManager.manualStartServer(info,clone));
}else {
// 修改服务器状态
serverInfoDao.updateServerInfo(serveId, Integer.valueOf(status), 0, Integer.valueOf(isNew), name,registerState);
}
// 清库操作
ThreadPoolManager.getInstance().execute(() -> AutoServerManager.getInstance().delUser(info));
return 1;
}else {
return 0;
}
// 修改服务器状态
serverInfoDao.updateServerInfo(server_id, status, 0, isnew, name,register_state);
return 1;
}
/**

View File

@ -49,7 +49,7 @@ public class DingTalkLogic {
* @param serverInfo
* @param debug
*/
public void sendDingTalk(ServerInfo serverInfo, boolean debug){
public void sendDingTalk(ServerInfo serverInfo, String cont, boolean debug){
try {
//是否通知所有人
boolean isAtAll = false;
@ -59,14 +59,14 @@ public class DingTalkLogic {
//钉钉机器人消息内容
String content;
if (debug){
content = "开服提醒, hello world!";
content = "测试开服提醒, hello world!";
}else {
content = "开服提醒," +
"\n自动开服报错,服务器id" + serverInfo.getServer_id() +
"\n服务器id" + serverInfo.getServer_id() +
"\n服务器名字" + serverInfo.getName() +
"\n服务器当前状态:" + serverInfo.getStatus() +
"\n" +
"\n服务器全部信息:" + serverInfo.toString();
"\n服务器状态:" + serverInfo.getStatus() +
"\n\n服务器全部信息" + serverInfo.toString() +
"\n\n服务器报错详情" + cont;
}
//组装请求内容
String reqStr = buildReqStr(content, isAtAll, mobileList);

View File

@ -12,7 +12,7 @@ import org.springframework.data.mongodb.core.mapping.Field;
*/
@Document(collection = "server_info")
public class ServerInfo implements Comparable {
public class ServerInfo implements Comparable,Cloneable {
@Id
private int _id;
@ -240,4 +240,9 @@ public class ServerInfo implements Comparable {
return -1;
}
}
@Override
public ServerInfo clone() throws CloneNotSupportedException {
return (ServerInfo) super.clone();
}
}

View File

@ -7,12 +7,14 @@ import com.jmfy.model.CServerOpenTime;
import com.jmfy.model.ServerInfo;
import com.jmfy.model.vo.ServerStatusEnum;
import com.jmfy.redisProperties.RedisUserKey;
import com.jmfy.thrift.idl.Result;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.io.*;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.stream.Stream;
@ -27,7 +29,8 @@ import java.util.stream.Stream;
public class AutoServerManager {
private static final Logger LOGGER = LoggerFactory.getLogger(AutoServerManager.class);
private AutoServerManager(){}
private AutoServerManager() {
}
public static class Instance {
public final static AutoServerManager instance = new AutoServerManager();
@ -39,7 +42,7 @@ public class AutoServerManager {
private static long date = 0;
private static final long TIME = DateUtil.ONE_MINUTE*3;
private static final long TIME = DateUtil.ONE_MINUTE * 3;
public static final String REGISTER = "1";
public static final String AUTOTIME = "2";
@ -51,9 +54,10 @@ public class AutoServerManager {
/**
*
*
* @return
*/
public boolean isOpen(){
public static boolean isOpen() {
AutoServerSetting autoServerSetting = RedisUtil.getInstence().getMapValue(RedisUserKey.AUTO_START_SERVER_SETTING, "1", "1", AutoServerSetting.class, -1);
return autoServerSetting != null && "1".equals(autoServerSetting.getState());
}
@ -62,7 +66,7 @@ public class AutoServerManager {
*
*/
public void startServer() throws Exception {
if (isOpen()){
if (isOpen()) {
// 当前时间
long now = DateUtil.now();
// 获取全部服务器列表,排除非未运营和准备中的服务器,正序排列
@ -70,7 +74,7 @@ public class AutoServerManager {
allServerInfo.removeIf(v -> Integer.parseInt(v.getStatus()) != ServerStatusEnum.NOT_OPERATE.getId());
Stream<ServerInfo> sorted = allServerInfo.stream().sorted();
Optional<ServerInfo> first = sorted.findFirst();
if (!first.isPresent()){
if (!first.isPresent()) {
LOGGER.error("自动开服,服务器列表获取为空");
return;
}
@ -80,13 +84,13 @@ public class AutoServerManager {
// 注册人数
if (REGISTER.equals(setting.getChoose())) {
// 注册人数3分钟检查一次
if (now >= (date + TIME)){
if (now >= (date + TIME)) {
// 获取服务器id
String serverId = String.valueOf(Integer.valueOf(newServer.getServer_id())-1);
String serverId = String.valueOf(Integer.valueOf(newServer.getServer_id()) - 1);
// 注册人数
long registerNum = serverInfoDao.getRegisterNum(serverId);
LOGGER.info("自动开服,注册人数判断,条件值:{},当前服务器人数:{}{}",setting.getNum(),serverId,registerNum);
if (registerNum >= Integer.parseInt(setting.getNum())){
LOGGER.info("自动开服,注册人数判断,条件值:{},当前服务器人数:{}{}", setting.getNum(), serverId, registerNum);
if (registerNum >= Integer.parseInt(setting.getNum())) {
startServers(newServer);
}
// 更新时间
@ -94,11 +98,11 @@ public class AutoServerManager {
}
}
// 时间开服,每分钟
else if (AUTOTIME.equals(setting.getChoose())){
else if (AUTOTIME.equals(setting.getChoose())) {
// 比较时间是否一致,精确到分
boolean compareTime = DateUtil.compareTime(setting.getTime());
LOGGER.info("自动开服,时间判断,条件值:{},当前时间:{},结果:{}",setting.getTime(),DateUtil.nowString(),compareTime);
if (compareTime){
LOGGER.info("自动开服,时间判断,条件值:{},当前时间:{},结果:{}", setting.getTime(), DateUtil.nowString(), compareTime);
if (compareTime) {
startServers(newServer);
}
}
@ -106,65 +110,144 @@ public class AutoServerManager {
}
/**
*
* @param newServer
*
* @param serverInfo
* @throws Exception
*/
private void startServers(ServerInfo newServer) throws Exception {
// 脚本,重启服务器
AutoServerManager.getInstance().delUser(newServer);
public void startServers(ServerInfo serverInfo) throws Exception {
// 停服脚本
AutoServerManager.getInstance().delUser(serverInfo);
// 间隔30秒再获取开服数据
Thread.sleep(DateUtil.ONE_SECOND*30);
// 验证新服状态
CServerOpenTime cServerOpenTime = serverInfoDao.getOpenServerTime(newServer.getServer_id());
if (null == cServerOpenTime || cServerOpenTime.getOpenTime() == null || "".equals(cServerOpenTime.getOpenTime()) || cServerOpenTime.getVersion() <= 0){
LOGGER.error("新服自动开服失败================={}",newServer.toString());
// 通知钉钉
dingTalkLogic.sendDingTalk(newServer,false);
return;
Thread.sleep(DateUtil.ONE_SECOND * 30);
// 验证
boolean serverStatus = verifyServerStatus(serverInfo);
if (serverStatus){
// 旧服务器状态更新
String serverId = String.valueOf(Integer.valueOf(serverInfo.getServer_id()) - 1);
ServerInfo oldServer = serverInfoDao.getServerinfo(serverId);
updateServer(oldServer, ServerStatusEnum.CROWDING.getId(), 0, serverId);
// 新服务器状态更新
updateServer(serverInfo, ServerStatusEnum.FLUENT.getId(), 1, serverInfo.getServer_id());
}
// 旧服务器状态更新
String serverId = String.valueOf(Integer.valueOf(newServer.getServer_id())-1);
ServerInfo oldServer = serverInfoDao.getServerinfo(serverId);
updateServer(oldServer,ServerStatusEnum.CROWDING.getId(),0,serverId);
// 新服务器状态更新
updateServer(newServer,ServerStatusEnum.FLUENT.getId(),1,newServer.getServer_id());
}
/**
*
*/
private boolean verifyServerStatus(ServerInfo serverInfo) {
String serverId = serverInfo.getServer_id();
// 错误信息
String cont;
try {
int i = 0;
do {
// 发送rpc到游戏服
Result result1 = RPCClient.sendCmd(Integer.parseInt(serverId), "serverstatus " + serverId);
if (result1 == null) {
// result1为空表示rpc发送失败最多重复三次
LOGGER.error("服务器验证状态异常,报null第{}次重试",i+1);
cont = "服务器验证状态异常,三次重试失败,游戏服未启动";
i++;
continue;
}
// rpc通信成功游戏端返回错误码
if (result1.getResultCode() != 0 || StringUtil.isEmpty(result1.getResultMsg())) {
cont = "服务器验证状态异常,code异常,游戏服可能未重启:{"+result1.getResultCode()+"}";
break;
}
// 返回值长度错误
String[] split = result1.getResultMsg().split("_");
if (split.length < 3) {
cont = "服务器验证状态异常,msg异常,游戏服可能未重启:{"+result1.getResultMsg()+"}";
break;
}
// 读库失败
CServerOpenTime serverTime = serverInfoDao.getOpenServerTime(serverId);
if (serverTime == null) {
cont = "服务器验证状态异常,读库失败,游戏服未启动或进程错误:{"+serverId+"}";
break;
}
// 返回参数 result1 版本号_开服时间_重启时间
String version = split[0];
String openTime = split[1];
String restartTime = split[2];
// 验证版本号是否相等,开服时间是否同一天,重启时间是否同一天
boolean ver = version.equals(String.valueOf(serverTime.getVersion()));
boolean open = DateUtil.isSameDay(DateUtil.timeToStamp(openTime), DateUtil.timeToStamp(serverTime.getOpenTime()));
boolean restart = DateUtil.isSameDay(DateUtil.timeToStamp(restartTime), DateUtil.timeToStamp(serverTime.getRestartTime()));
if (ver && open && restart){
return true;
}
cont = "服务器验证状态异常,参数验证失败:读库参数:{"+serverTime.toString()+"},游戏服参数:{"
+ Arrays.toString(split)+"}, \n验证结果版本号:{"+ver+"},开服时间:{"+open+"},重启时间:{"
+ restart+"}";
} while (i < 3);
} catch (Exception e) {
cont = "服务器验证状态异常:{"+e.getMessage()+"}";
e.printStackTrace();
}
// 发送钉钉
dingTalkLogic.sendDingTalk(serverInfo,cont,false);
return false;
}
/**
*
*
* @param serverInfo
* @param status
* @param news
*/
private void updateServer(ServerInfo serverInfo, int status, int news, String serverId) throws Exception {
if (serverInfo == null){
LOGGER.error("自动开服,服务器不存在:{}",serverId);
if (serverInfo == null) {
LOGGER.error("自动开服,服务器不存在:{}", serverId);
return;
}
serverInfo.setStatus(String.valueOf(status));
serverInfo.setIs_new(String.valueOf(news));
serverInfoDao.updateServerInfo(serverInfo);
LOGGER.info("自动开服,修改服务器信息:{}",serverInfo.toString());
}
/**
*
* @param serverInfo
* @param clone
*/
public void manualStartServer(ServerInfo serverInfo, ServerInfo clone){
try {
// 停服脚本
AutoServerManager.getInstance().delUser(serverInfo);
// 间隔30秒再获取开服数据
Thread.sleep(DateUtil.ONE_SECOND * 30);
// 验证
boolean serverStatus = verifyServerStatus(serverInfo);
if (serverStatus){
// 入库
serverInfoDao.updateServerInfo(clone);
}
} catch (Exception e) {
e.printStackTrace();
}
}
/**
*
*
* @param serverInfo
* @return
*/
public void delUser(ServerInfo serverInfo){
private void delUser(ServerInfo serverInfo) {
String path = "/data/jieling/deluser.sh";
if (serverInfo.getIp() == null || "".equals(serverInfo.getIp())
|| serverInfo.getServer_id() == null || "".equals(serverInfo.getServer_id())
|| serverInfo.getCoreName() == null || "".equals(serverInfo.getCoreName())){
LOGGER.error("删除操作参数不全,执行失败:参数:{}",serverInfo.toString());
|| serverInfo.getServer_id() == null || "".equals(serverInfo.getServer_id())
|| serverInfo.getCoreName() == null || "".equals(serverInfo.getCoreName())) {
LOGGER.error("删除操作参数不全,执行失败:参数:{}", serverInfo.toString());
return;
}
String command = "sh " + path + " 500 " + serverInfo.getIp() + " " + serverInfo.getServer_id() + " " + serverInfo.getCoreName();
LOGGER.info("=================清库命令:{}",command);
LOGGER.info("=================清库命令:{}", command);
Process exec = null;
try {
@ -185,6 +268,7 @@ public class AutoServerManager {
/**
*
*
* @param process
*/
private static void readProcessOutput(final Process process) {
@ -196,6 +280,7 @@ public class AutoServerManager {
/**
*
*
* @param inputStream
* @param out
*/

View File

@ -77,7 +77,7 @@ public class DateUtil {
try {
Date now = sf.parse(sf.format(new Date()));
Date time = sf.parse(timers);
return isSameDay(now.getTime(),time.getTime());
return isSameDayToMinute(now.getTime(),time.getTime());
} catch (ParseException e) {
e.printStackTrace();
}
@ -91,7 +91,7 @@ public class DateUtil {
* @return
*/
@SuppressWarnings("Duplicates")
public static boolean isSameDay(long r1, long r2) {
public static boolean isSameDayToMinute(long r1, long r2) {
Calendar c1 = Calendar.getInstance();
c1.setTimeInMillis(r1);
int y1 = c1.get(Calendar.YEAR);
@ -111,6 +111,29 @@ public class DateUtil {
return (y1 == y2) && (m1 == m2) && (d1 == d2) && (h1 == h2) && (min1 == min2) ;
}
/**
*
*
* @param r1
* @param r2
* @return
*/
public static boolean isSameDay(long r1, long r2) {
Calendar c1 = Calendar.getInstance();
c1.setTimeInMillis(r1);
int y1 = c1.get(Calendar.YEAR);
int m1 = c1.get(Calendar.MONTH) + 1;
int d1 = c1.get(Calendar.DAY_OF_MONTH);
Calendar c2 = Calendar.getInstance();
c2.setTimeInMillis(r2);
int y2 = c2.get(Calendar.YEAR);
int m2 = c2.get(Calendar.MONTH) + 1;
int d2 = c2.get(Calendar.DAY_OF_MONTH);
return (y1 == y2) && (m1 == m2) && (d1 == d2);
}
/**
*
* @return

View File

@ -14,10 +14,10 @@ public class RPCClient {
private static final Logger LOGGER = LoggerFactory.getLogger(RPCClient.class);
public static Result gmSend(String cmd, String ip, String port) throws Exception {
public static Result gmSend(String cmd, String ip, String port){
Result result = null;
ClientAdapterPo<RPCRequestGMIFace.Client> rPCClient = null;
String serviceKey = RPCClient.getServiceKey(ServiceKey.RPCCore, ip, port);
String serviceKey = ServiceKey.RPCCore + "|" + ip + "|" + port;
try {
rPCClient = ClientAdapterPo.getClientAdapterPo(serviceKey);
result = rPCClient.getClient().idipGm("", cmd);
@ -31,39 +31,34 @@ public class RPCClient {
return null == result ? new Result().setResultCode(-1).setResultMsg("应用不存在") : result;
}
public static String getServiceKey(String serviceName, String host, String port) {
StringBuilder sb = new StringBuilder();
return sb.append(serviceName).append("|")
.append(host).append("|")
.append(port).toString();
}
public static int sendWithServerId(int serverId,String cmd) {
public static Result sendCmd(int serverId,String cmd) {
try {
String rpcString = RedisUtil.getInstence().getObject(RedisUserKey.LOGIC_SERVER_INFO, String.valueOf(serverId), String.class, -1);
if (null == rpcString) {
throw new Exception("serverAddress not exist");
LOGGER.error("发送gm报错获取rpc参数serverId:{}cmd:{}",serverId,cmd);
return null;
}
String thriftIp = rpcString.split(":")[0];
String thriftPort = rpcString.split(":")[1];
if (thriftIp == null || thriftIp.isEmpty() || null == thriftPort || thriftPort.isEmpty()) {
return -1;
if (StringUtil.isEmpty(thriftIp) || StringUtil.isEmpty(thriftPort)) {
LOGGER.error("发送gm报错rpc参数不全serverId:{}cmd:{}",serverId,cmd);
return null;
} else {
Result result = RPCClient.gmSend(cmd, thriftIp, thriftPort);
//异常或者错误
if (result.getResultCode() != 0) {
return -1;
}
return RPCClient.gmSend(cmd, thriftIp, thriftPort);
}
} catch (Exception e) {
LOGGER.error("发送gm报错rpc发送serverId:{}cmd:{}",serverId,cmd);
e.printStackTrace();
return 1;
return null;
}
}
public static int sendWithServerId(int serverId,String cmd) {
Result result = sendCmd(serverId, cmd);
if (result == null || result.getResultCode() != 0){
return -1;
}
return 0;
}
}

View File

@ -151,7 +151,7 @@ public class StringUtil {
}
public static boolean isEmpty(String source){
if( source == null || source.isEmpty()){
if(source == null || source.isEmpty()){
return true;
}
return false;

View File

@ -166,7 +166,7 @@
url: "/serverEdit",
success: function (data) {
if (data === 1) {
alert("修改成功");
alert("修改完成,信息会在一分钟后刷新,请于一分钟后刷新界面查看数据是否正常");
window.location.href="/findServerInfo";
}
if (data === 0) {