前东家是一家游戏公司,老板很好,当时工作也留下了很多自己原创的管理脚本。现在分享一下在办公环境使用Java、Jsch登录VPN管理Linux的脚本(此处实现JAVA调用Linux上备份Mysql的shell作为示例),希望对运维的朋友有帮助,尽快从繁杂的服务器管理工作中脱离出来。

  主要的实现思路:

  如果需要先登录VPN才能连接游戏服务器,需要将游戏服务器的ssh端口(一般是22)映射到本地办公电脑的端口上(如5555),然后ssh连接本地办公电脑的5555端口,这样可以连接到游戏服务器,并可以管理游戏服务器了。

  当您学会通过VPN连接Linux服务器后,如果只在内网环境,不使用VPN,更简单了,此外不再详述。Jsch的example里也有介绍。

  代码:使用Jsch透过VPN

package com.daily.wednesday; 
import java.io.IOException; 
import java.io.InputStream; 
import java.sql.Connection; 
import java.sql.DriverManager; 
import java.sql.ResultSet; 
import java.sql.SQLException; 
import java.sql.Statement; 
import com.daily.util.DataBaseConnection; 
import com.jcraft.jsch.Channel; 
import com.jcraft.jsch.ChannelExec; 
import com.jcraft.jsch.JSch; 
import com.jcraft.jsch.JSchException; 
import com.jcraft.jsch.Session; 
public class BackUpMysql3 { 
    public static void main(String args[]) { 
        // 读取数据库配置
        DataBaseConnection dataBaseConnection = new DataBaseConnection(); 
        String dataBaseConfigForWrite[] = new String[3]; 
        dataBaseConfigForWrite = dataBaseConnection.loadDataConfig(); 

        Connection conn = null;// 数据库连接
        Statement stmt = null;// 数据库表达式
        ResultSet rs = null; // 结果集
        int rowcount = 0;// 总记录数
        String sql = "select * from servers_maint_wednesday"; 

        try { 
            conn = DriverManager.getConnection(dataBaseConfigForWrite[0], 
                    dataBaseConfigForWrite[1], dataBaseConfigForWrite[2]); 
            stmt = conn.createStatement(); 
            rs = stmt.executeQuery(sql); 
            rs.last(); 
            rowcount = rs.getRow();// 总记录数
            rs = stmt.executeQuery(sql); 
        } catch (SQLException e) { 
            e.printStackTrace(); 
        } 
        // 定义游戏服务器IP的数组,游戏服务器IP存在数据库中。
        String privateIpaddress[] = new String[rowcount]; 
        String remark[] = new String[rowcount];// 定义游戏区名称
        String programPath[] = new String[rowcount];// 定义程序路径
        String backMysqlShellPath[] = new String[rowcount];// 定义mysql备份脚本路径

        int j = 0; 
        try { 
            while (rs.next()) { 
                privateIpaddress[j] = rs.getString("privateipaddress"); 
                remark[j] = rs.getString("remarks"); 
                programPath[j] = rs.getString("programpath"); 
                backMysqlShellPath[j] = rs.getString("backmysqlshellpath"); 
                j++; 
            } 
        } catch (Exception e) { 
            e.printStackTrace(); 
        } finally { 
            try { 
                if (rs != null) { 
                    rs.close(); 
                } 
                if (stmt != null) { 
                    stmt.close(); 
                } 
                if (conn != null) { 
                    conn.close(); 
                } 
            } catch (Exception e) { 
                e.printStackTrace(); 
            } 
        } 

        // 调用mysql备份方法
        for (int n = 0; n < privateIpaddress.length; n++) { 
            try { 
                try { 
                    backUpMysql(privateIpaddress[n], backMysqlShellPath[n],remark[n]); 
                } catch (IOException e) { 
                    // TODO Auto-generated catch block
                    e.printStackTrace(); 
                } 
            } catch (JSchException e) { 
                // TODO Auto-generated catch block
                e.printStackTrace(); 
            } 
        } 

    } 
    /**
     * 备份mysql数据库的方法
     * @param privateip
     * @param backMysqlShellPath
     * @throws JSchException
     * @throws IOException
     */
    public static void backUpMysql(String privateip, String backMysqlShellPath, String remark) 
            throws JSchException, IOException { 
        // 登录到服务器
        int rport; 
        JSch jsch = new JSch(); 
        String host = "dl.dengdie.com"; //此处为VPN服务器地址
        String user = "admin"; //VPN用户名
        Session sessionForBack = jsch.getSession(user, host, 22); 
        rport = 22; 
        sessionForBack.setPassword("&*&&&&lalaflls"); //VPN密码
        java.util.Properties config = new java.util.Properties(); 
        config.put("StrictHostKeyChecking", "no"); 
        sessionForBack.setConfig(config); 
        sessionForBack.connect();//登录到VPN服务器
         
        // 建立与游戏服务器的ssh转发连接:即将游戏服务器的22号ssh端口映射的本地办公电脑的53238端口。      
        sessionForBack.setPortForwardingL(53238, privateip, rport); 

        try { 
            JSch jschToBack = new JSch(); 

            Session sessionToBack = jschToBack.getSession(user, "127.0.0.1", 
                    53238); //连接本地办公电脑的53238端口,相当于连接了游戏服务器的22号端口。
            sessionToBack.setPassword("&*&&&&lalaflls"); 
            sessionToBack.setConfig(config); 
            sessionToBack.connect(); 
            //backMysqlShellPath实际上是游戏服务器上备份Mysql数据库的一个脚本,此脚本请您自行实现,网上很多实例。
            String command = backMysqlShellPath; 
            //打开执行命令的隧道,并执行命令。
            Channel channel = sessionToBack.openChannel("exec"); 
            ((ChannelExec) channel).setCommand(command); 
            channel.setInputStream(null); 
            ((ChannelExec) channel).setErrStream(System.err); 
            InputStream in = channel.getInputStream(); 
            channel.connect(); 

            byte[] tmp = new byte[1024]; 
            while (true) { 
                while (in.available() > 0) { 
                    int i = in.read(tmp, 0, 1024); 
                    if (i < 0) 
                        break; 
                    System.out.print(new String(tmp, 0, i)); 
                } 
                if (channel.isClosed()) { 
                    System.out.println(remark + "Mysql备份完毕!"); 
                    System.out.println("exit-status: "
                            + channel.getExitStatus()); 
                    break; 
                } 
                try { 
                    Thread.sleep(1000); 
                } catch (Exception ee) { 
                } 
            } 
            channel.disconnect(); 
            sessionToBack.disconnect(); 
            sessionForBack.disconnect(); 
        } catch (Exception e) { 
            System.out.println(e); 
        } 
    } 
}