本实例为用Java执行shell脚本启动或关闭远程Mysql数据库,需求原因:游戏服务器合服后,为了节省内存消耗,需要关闭合服后的服务器不必要的数据库(一台服务器主机存在多个MySql数据库),以提高服务器性能,但有时需要查询历史游戏玩家信息,又需要开启数据库,为了节省运维人员的人力和时间,游戏后台就提供非运维人员都可操作开关数据库的操作。
功能实现步骤:
第一:服务器后台提供参数,发送异步请求,请求方法如下
<script type="text/javascript"> function shutdownDatabase(param,operate){ var arr=param.replace(/\s+/g," ").split(" "); if(arr.length!=3){ alert("数据库脚本参数个数不正确,请编辑好再操作!"); return false; } param = param + " " + operate; $.ajax({ url:'XXXAction!databaseSwitch.action', type:"post", data:{"param":param}, dataType:"json", async:true, success:function(data){ $("#progressImgage").hide();//进度条隐藏 $("#maskOfProgressImage").hide();//蒙版隐藏 alert("执行结果:"+data.result); }, error:function(data){ $("#progressImgage").hide(); $("#maskOfProgressImage").hide(); alert("执行结果:"+data.result); }, beforeSend:function(xhr){ $("#progressImgage").show().css({ "position": "fixed", "top": "50%", "left": "50%", "margin-top": function () { return -1 * $("#progressImgage").height() / 2; }, "margin-left": function () { return -1 * $("#progressImgage").width() / 2; } }); $("#maskOfProgressImage").show().css("opacity", "0.1"); } }); } </script>
其中param为shell脚本参数,根据具体业务而不同。
请求等待提示代码
<img id="progressImgage" class="progress hide" alt="数据库操作中" src="./images/loading.jpg" width="250" height="200"/> <div id="maskOfProgressImage" class="mask hide"></div> <style type="text/css"> .hide{display:none } .progress{z-index: 2000} .mask{position: fixed;top: 0;right: 0;bottom: 0;left: 0; z-index: 1000; background-color: #000000} </style>
第二,后台java代码,发送异步请求到后台java方法,java方法操作执行shell脚本,执行代码如下
/** * 服务器数据库开关 */ public void databaseSwitch() { logger.info("服务器数据库开关 start"); PrintWriter out = null; try { ActionContext context = ActionContext.getContext(); HttpServletRequest request = (HttpServletRequest)context.get(ServletActionContext.HTTP_REQUEST); HttpServletResponse response = (HttpServletResponse)context.get(ServletActionContext.HTTP_RESPONSE); request.setCharacterEncoding("UTF-8"); response.setCharacterEncoding("UTF-8"); out= getServletResponse().getWriter(); String param= request.getParameter("param"); if (null == param || "".equals(param)) { out.write("{\"result\":\"脚本参数不能为空"+"\"}"); return; } String shellStr = "sh /data0/mysql_actions.sh "+param; logger.info("执行脚本:"+shellStr); List<String> result = new ArrayList<String>(); result = execShell(shellStr); out.write("{\"result\":\""+result.toString()+"\"}"); logger.info("执行结果:"+result); } catch (UnsupportedEncodingException e1) { out.write("{\"result\":\"操作数据库时不支持字符编码出错!\"}"); logger.error("execShell方法异常"+e1); e1.printStackTrace(); } catch (Exception e) { out.write("{\"result\":\"操作数据库出错!\"}"); logger.error("execShell方法异常"); e.printStackTrace(); } logger.info("服务器数据库开关 end"); } /** * 运行shell * @param shStr * 需要执行的shell * @return * @throws IOException */ public static List<String> execShell(String shStr) throws Exception { List<String> strList = new ArrayList<String>(); Process process; process = Runtime.getRuntime().exec(new String[]{"/bin/sh","-c",shStr},null,null); ////执行shell命令 InputStreamReader ir = new InputStreamReader(process.getInputStream()); LineNumberReader input = new LineNumberReader(ir); //脚本输出 String line; int extValue = process.waitFor(); //执行结果 strList.add("extValue="+extValue); while ((line = input.readLine()) != null){ strList.add(line); } process.destroy();//杀掉进程 return strList; }
执行脚本的主要方法为:execShell(String shStr),其中shStr参数为要执行的shell脚本,本实例的脚本写成文件直接调用,这样可读性,可移植性强。
第三,关闭远程服务器数据库
主要是在shell脚本中通过ssh,连接远程服务器,通过脚本判断数据库是否开启并执行开关操作,最后返回结果
关键代码为:
ssh="ssh -c arcfour128 -o [email protected] -o StrictHostKeyChecking=no -o GSSAPIAuthentication=no -p 22"
$ssh $1 "ps -ef |grep mysql |grep \`cat /data/${3}/mysql/port\`" &> /dev/null if [ $? -eq 0 ];then echo "主库目前已经处于运行状态" else $ssh $1 "sh /data0/${3}/mysql/start-mysql.sh &> /dev/null" if [ $? -eq 0 ];then echo "成功开启主库" else echo "开启主库失败" fi fi
其中$1参数为远程服务器ip
详细代码就不贴出来了,详解请私信我。这个功能做出来是非常耗时的,但做出来后,别人就很省时了,含金量比较大。
如果脚本不熟,需要运维人员提供。一个人写需要懂的技术很多,深度很深。
问题1:我执行脚本期间遇到一个问题就是没有在root用户下执行,导致失败,执行脚本需在管理员权限下执行才能成功。
问题2:后台需要远程服务器的无密码登录权限,通过key设置,ssh还要设置为“ForwardAgent yes”。
一切就绪后台即可执行,祝读者好运!
版权声明:本文为博主原创文章,未经博主允许不得转载。
时间: 2024-10-14 21:56:27