• Linux机器上实现程序自动部署以及更新


    平台化管理Linux环境的客户端程序的部署、更新、以及进程关闭

     

    平台是用SSH实现,前端是avalon,数据库mysql客户端程序(Monitor, CLientSetup)是spring boot实现平台操作界面如下:

    客户端程序访问路径为 http://ip:8034, 

    获取版本方式为 http://ip:8034/Deploy/Version

    心跳地址为 http://ip:8034/Deploy/ReturnOk

    1. 更新状态访问版本地址,返回该ip对应的版本,落入数据库,更新页面信息

    2. 部署以及更新应用所有服务器路径都在ftpuser用户目录下,即/STRESS

    应用源码放在服务器A上,为Monitor.tar,上传脚本Deploy.sh也在服务器A上,

    上传脚本如下:

    IP=$1
    
    echo "put tar to "${IP}
    ftp -n<<!
    open ${IP}
    user ftpuser ******
    binary
    prompt
    mkdir tools
    cd tools
    put Monitor.tar
    put ClientSetup.tar
    put clientDeploy.sh
    #chmod 777 clientDeploy.sh
    close
    bye
    !
    

      

    平台调用上传脚本把源码从服务器A传到目标服务器B上。

    平台再调用服务器B上脚本tools/clientDeploy.sh

    cd tools
    rm -rf Monitor
    rm -rf ClientSetup
    tar -xvf Monitor.tar
    tar -xvf ClientSetup.tar
    cd ~/tools/Monitor
    sh restart.sh
    cd ~/tools/ClientSetup
    sh restart.sh
    cd ~/tools
    rm -rf Monitor.tar
    rm -rf ClientSetup.tar
    

      

    平台调用Java代码

    public String DeployEnvAgency(String ip) throws IOException, InterruptedException
    {
    RemoteShellTool tool = new RemoteShellTool("172.16.103.126", "ftpuser", 
    "88888", "utf-8"); 
    
    String result = tool.exec("sh Deploy.sh "+ip); 
    System.out.print("result:"+result); 
    
    RemoteShellTool tool2 = new RemoteShellTool(ip, "ftpuser", 
    "******", "utf-8"); 
    
    String result2 = tool2.exec("sh tools/clientDeploy.sh"); 
    System.out.print("result2:"+result2); 
    
    return "ok";
    }
    

      

    3. 关闭进程
    java代码:

    public String killClient(String ip) throws IOException, InterruptedException
    {
    RemoteShellTool tool = new RemoteShellTool(ip,"utf-8");
    tool.loginCentos();
    tool.exec("kill -9 $(ps -ef|grep ClientSetup|gawk '$0 !~/grep/ {print $2}'|tr -s '
    ''')"); 
    tool.exec("kill -9 $(ps -ef|grep SpringMVCDemo|gawk '$0 !~/grep/ {print $2}'|tr -s '
    ''')"); 
    
    return "ok";
    }

    调用RemoteShellTool类如下:

    package com.ymt.testplatform.util;
    
    import java.io.IOException;
    import java.io.InputStream;
    import java.nio.charset.Charset;
    
    import ch.ethz.ssh2.Connection;
    import ch.ethz.ssh2.Session;
    
    public class RemoteShellTool {
    private Connection conn; 
    private String ipAddr; 
    private String charset = Charset.defaultCharset().toString(); 
    private String userName; 
    private String password; 
    
    public RemoteShellTool(String ipAddr, String charset) { 
    this.ipAddr = ipAddr; 
    if (charset != null) { 
    this.charset = charset; 
    } 
    } 
    
    public RemoteShellTool(String ipAddr, String userName, String password, 
    String charset) { 
    this.ipAddr = ipAddr; 
    this.userName = userName; 
    this.password = password; 
    if (charset != null) { 
    this.charset = charset; 
    } 
    } 
    
    public boolean login() throws IOException { 
    conn = new Connection(ipAddr); 
    conn.connect(); // 连接 
    return conn.authenticateWithPassword(userName, password); // 认证 
    } 
    
    public boolean loginCentos() throws IOException
    {
    conn = new Connection(ipAddr); 
    conn.connect(); // 连接 
    
    String [] pass = {"ymt@123","abcd@1234","root@1234","******","1234qwer"};
    
    for (String pa : pass) {
    if(conn.authenticateWithPassword("root", pa))
    {
    this.userName = "root"; 
    this.password = pa; 
    return true;
    }
    }	
    
    return false;
    
    }
    
    public boolean login(String userName,String password) throws IOException { 
    conn = new Connection(ipAddr); 
    conn.connect(); // 连接 
    this.userName = userName; 
    this.password = password; 
    return conn.authenticateWithPassword(userName, password); // 认证 
    } 
    
    public String exec(String cmds) { 
    InputStream in = null; 
    String result = ""; 
    try { 
    if (this.login()) { 
    Session session = conn.openSession(); // 打开一个会话 
    session.execCommand(cmds); 
    
    in = session.getStdout(); 
    result = this.processStdout(in, this.charset); 
    session.close(); 
    conn.close(); 
    } 
    } catch (IOException e1) { 
    e1.printStackTrace(); 
    } 
    return result; 
    } 
    
    public String processStdout(InputStream in, String charset) { 
    
    byte[] buf = new byte[1024]; 
    StringBuffer sb = new StringBuffer(); 
    try { 
    while (in.read(buf) != -1) { 
    sb.append(new String(buf, charset)); 
    } 
    } catch (IOException e) { 
    e.printStackTrace(); 
    } 
    return sb.toString(); 
    } 
    
    /** 
    * @param args 
    */ 
    public static void main(String[] args) { 
    
    RemoteShellTool tool = new RemoteShellTool("172.16.103.126", "ftpuser", 
    "******", "utf-8"); 
    
    String result = tool.exec("sh Deploy.sh 172.16.103.121"); 
    System.out.print("result:"+result); 
    
    RemoteShellTool tool2 = new RemoteShellTool("172.16.103.121", "ftpuser", 
    "******", "utf-8"); 
    
    String result2 = tool2.exec("sh tools/clientDeploy.sh"); 
    System.out.print("result2:"+result2); 
    
    } 
    
    }
    

      

     附
    html

    <!DOCTYPE html>
    <html lang="zh-CN">
    
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <link href="/css/reset.css" rel="stylesheet">
        <link href="/bootstrap/css/bootstrap.min.css" rel="stylesheet">
        <link href="/css/admin/layout.css" rel="stylesheet">
        <link href="/css/admin/envinfo.css" rel="stylesheet">
        <script type="text/javascript" src="/lib/jquery.js"></script>
        <script type="text/javascript" src="/bootstrap/js/bootstrap.min.js"></script>
        <script type="text/javascript" src="/bootstrap/js/jquery.bootpag.min.js"></script>
        <script type="text/javascript" src="/lib/avalon.js"></script>
        <script type="text/javascript" src="/js/common/util.js"></script>
        <script type="text/javascript" src="/js/admin/common/common.js"></script>
        <script type="text/javascript" src="/js/admin/monitordeploy.js"></script>
    
        <title>基础信息管理</title>
    </head>
    
    <body ms-controller="vm">
        <!-- ADMIN HEAD -->
        <div ms-include-src="'/admin/header.html'"></div>
        <!-- Content -->
        <div class="container">
            <div ms-controller="monitordeploy">
                <div class="tabbable">
                    
                    <div class="tab-content">
                        <div class="tab-pane active" id="vms">
                            <div id="vmsTab-pane">
                                <br/>
                                <div class="row" id="search1Div">
                                    <div class="col-md-2">
                                        <div class="input-group">
                                            <span class="input-group-addon">环境:</span>
                                            <select class="form-control" ms-duplex="envType">
                                                <option value="STRESS" selected>STRESS</option>
                                                <option value="ALL">全部</option>
                                                <option value="SIT1">SIT1</option>
                                                <option value="SIT2">SIT2</option>
                                                <option value="UAT">UAT</option>
                                                <option value="other">其他</option>
                                            </select>
                                        </div>
                                    </div>
                                <div class="row" id="search2Div">
                                    <div class="col-md-2">
                                        <div class="input-group">
                                            <span class="input-group-addon">类型:</span>
                                            <select class="form-control" ms-duplex="conType">
                                                <option value="" selected>请选择</option>
                                                <option value=".Net Web">.Net Web</option>
                                                <option value="Windows Service">Windows Service</option>
                                                <option value="Node">Node</option>
                                                <option value="Java App">Java App</option>
                                                <option value="Java Web">Java Web</option>
                                                <option value="其他">其他</option>
                                            </select>
                                        </div>
                                    </div>
                                    <div class="col-md-1">
                                        <button type="button" id="searchBtn" class="btn btn-primary" ms-click="listVmInfosByPage('init')" style="margin: auto;">
                                           	搜 索
                                        </button>
                                    </div>
                                   
                                     <div class="col-md-1">
                                        <button type="button" id="allCheckBtn" class="btn btn-info" ms-click="checkAll()" style="margin: auto;">
                                           	全选
                                        </button>
                                    </div>
                                    
                                    <div class="col-md-1">
                                        <button type="button" id="allUncheckBtn" class="btn btn-info" ms-click="uncheckAll()" style="margin: auto;">
                                           	全不选
                                        </button>
                                    </div>
                                    
                                     <div class="col-md-1">
                                        <button type="button" id="allStatusBtn" class="btn btn-success" ms-click="viewAllStatus()" style="margin: auto;">
                                           	update all
                                        </button>
                                    </div>
                                    
                                     <div class="col-md-1">
                                        <button type="button" id="allDeployBtn" class="btn btn-warning" ms-click="deployAll()" style="margin: auto;">
                                           	deploy all
                                        </button>
                                    </div>
                                     
                                    <div class="col-md-1">
                                        <button type="button" id="allDeployBtn" class="btn btn-danger" ms-click="killAll()" style="margin: auto;">
                                           	kill all
                                        </button>
                                    </div>
                                  
                                </div>
                                
                          
                                <div>
                                    <div id="pageSizeSelect"><a><span ms-class="{{pagesize1Cls}}"
                                                  ms-click="changePageSize(pagesize1)">{{pagesize1}}</span></a> | <a><span
                        ms-class="{{pagesize2Cls}}" ms-click="changePageSize(pagesize2)">{{pagesize2}}</span></a> |
                                        <a>
                                            <spam ms-class="{{pagesize3Cls}}" ms-click="changePageSize(pagesize3)">{{pagesize3}}</spam>
                                        </a>
                                    </div>
                                </div>
                                <table class="table table-condensed table-hover">
                                    <thead>
                                        <tr>
                                       		<td class="width-50"></td>
                                            <td class="width-50">ID</td>
                                            <td>名称</td>
                                            <td class="width-125">IP</td>
                                            <td class="width-300">操作系统</td>
                                            
                                            <td class="width-100">监控版本</td>
                                            <td class="width-100">Setup版本</td>
                                            <td class="width-100">监控状态</td>
                                            <td class="width-100">Setup状态</td>
                                            <td class="width-100">更新时间</td>
                                            <td class="width-50">状态更新</td>
                                            <td class="width-50">部署</td>
                                             <td class="width-50">kill</td>
                                        </tr>
                                    </thead>
                                    <tbody>
                                        <tr ms-repeat="vmsList">
                                       		<td><label><input type="checkbox" ms-class="check_{{el.name}}" ></label></td>
                                            <td>{{$index+jpageSize*(jpageIndex-1)+1}}</td>
                                            <td>{{el.name}}</td>
                                            <td><a ms-href="'/admin/vmdetails.html?vmid='+el.vm.id" target="_blank">{{el.ip}}</a></td>
                                            <td>{{el.os}}</td>                                     
                                            <td>{{el.version}}</td>
                                            <td>{{el.setupVersion}}</td>
                                            <td>{{el.clientOn}}</td>
                                            <td>{{el.setupOn}}</td>
                                            <td>{{el.time}}</td>
                                            <td>
                                             <div ms-class="buttonDiv_view_{{el.name}}">
                                                <i style="color:#009100;" ms-class="glyphicon glyphicon-eye-open icon-white i_view_{{el.name}}"  ms-click="postViewStatus(el.name,el.ClientOn,el.SetupOn,el.ip)"></i>
                                             </div> 
                                             <div ms-class="loadDiv_view_{{el.name}} loadDiv"  style="display:none">	
                                             	<img src="/img/load2.jpg" style="16px;height:16px;"/>
                                             </div> 
                                            </td>
                                             <td>
                                             <div ms-class="buttonDiv_{{el.name}}">
                                                <i style="color:#000066;" ms-class="glyphicon glyphicon-play icon-white i_{{el.name}}" ms-click="postDeploy(el.name,el.ip,el.os)"> </i>
                                             </div> 
                                             <div ms-class="loadDiv_{{el.name}} loadDiv"  style="display:none">	
                                             	<img src="/img/load2.jpg" style="16px;height:16px;"/>
                                             </div> 
                                              
                                            </td>
                                            <td>
                                             <div ms-class="buttonDiv_kill_{{el.name}}">
                                                <i style="color:#CE0000;" ms-class="glyphicon glyphicon-remove icon-white ikill_{{el.name}}" ms-click="postkill(el.name,el.ip,el.os)"> </i>
                                             </div> 
                                             <div ms-class="loadDiv_kill_{{el.name}} loadDiv"  style="display:none">	
                                             	<img src="/img/load2.jpg" style="16px;height:16px;"/>
                                             </div> 
                                              
                                            </td>
                                        </tr>
                                    </tbody>
                                </table>
                                <div class="text-center">
                                    <p id="pagination"></p>
                                </div>
                            </div>
                        </div>
                       
                   
                </div>
            </div>
    
        </div>
    </div>
    <!-- /.container-->
    
    </body>
    </html>
    

      js

    /**
     * Created by chenjiazhu on 2017/2/15.
     */
    var monitordeploy = avalon.define({
        $id: 'monitordeploy',
       
        //VM Start
        pagesize1: "20",
        pagesize1Cls: "pageSizeSelected",
        pagesize2: "50",
        pagesize2Cls: "",
        pagesize3: "100",
        pagesize3Cls: "",
        changePageSize: function(pgsize) {
            monitordeploy.jpageSize = pgsize;
            monitordeploy.listVmInfosByPage("init");
        },
        clearsearch: function() {
            monitordeploy.conType = "";
            monitordeploy.listVmInfosByPage("init");
        },
        jpageIndex: 1,
        jpageSize: 20,
        envType: "STRESS",
        conType: "",
        
        vmsList: [],
        
        listVmInfosByPage: function(tag) {
            if (tag) {
                monitordeploy.jpageIndex = 1;
            }
            $.ajax({
                type: "post",
                url: 'listDeployVmInfosByPageByEnvType.action',
                data: {
                    "pageindex": monitordeploy.jpageIndex,
                    "pagesize": monitordeploy.jpageSize,
                    "type": monitordeploy.conType,
                    "envType": monitordeploy.envType
                },
                dataType: "json",
                success: function(data) {
                    if (tag) {
                        $('#pagination').bootpag({
                            total: data.pagenum,
                            page: monitordeploy.jpageIndex
                        });
                    }
                    if (data.retCode == "1000") {
                        monitordeploy.vmsList = data.vms;
                    } else {
                        alert(data.retMSG);
                    }
                },
                error: function (XMLHttpRequest, textStatus, errorThrown) {
                    alert("请求数据异常,状态码:" + XMLHttpRequest.status+",Error:"+errorThrown+",textStatus:"+textStatus);
                }
            });
        },
        
        postViewStatus: function(name, status1,status2,ip) {
           if(status1==null || status1=="")
           {
        	   status1=0;
           }
           
           if(status2==null || status2=="")
           {
        	   status2=0;
           }
           
           $(".loadDiv_view_"+name).show();
           $(".buttonDiv_view_"+name).hide();
           
           // 检查Monitor状态    	
        	$.ajax({
                type: "GET",
                dataType : 'jsonp',  
                jsonp:"jsoncallback",  
                url: "http://"+ip+":8034/Deploy/ReturnOk",
    
                success: function (data) {
                	  if(data.data=="ok")
      			    {
      			    	if(status1!="ok")
      			    	{
      			    		monitordeploy.updateMonitorStatus(ip,"ok");
      			    	}
      			    }
      			    else
      			    {
      			    	if(status1!="fail")
      			    	{
      			    		monitordeploy.updateMonitorStatus(ip,"fail");
      			    	}
      			    }
                	  
                	  $(".loadDiv_view_"+name).hide();
                      $(".buttonDiv_view_"+name).show();
                },
                error: function (XMLHttpRequest, textStatus, errorThrown) {
                    alert("请求数据异常,状态码:" + XMLHttpRequest.status+",Error:"+errorThrown+",textStatus:"+textStatus);
                    $(".loadDiv_view_"+name).hide();
                    $(".buttonDiv_view_"+name).show();
                }
            });
        	
        	// 检查ClientSetup状态    	
        	$.ajax({
                type: "GET",
                dataType : 'jsonp',  
                jsonp:"jsoncallback",  
                url: "http://"+ip+":8035/Deploy/ReturnOk",
    
                success: function (data) {
                	if(data.data="ok")
      			    {
      			    	if(status1!="ok")
      			    	{
      			    		monitordeploy.updateClientSetupStatus(ip,"ok");
      			    	}
      			    }
      			    else
      			    {
      			    	if(status1!="fail")
      			    	{
      			    		monitordeploy.updateClientSetupStatus(ip,"fail");
      			    	}
      			    }
                	
                	 
                	$(".loadDiv_view_"+name).hide();
                    $(".buttonDiv_view_"+name).show();
                },
                error: function (XMLHttpRequest, textStatus, errorThrown) {
                    alert("请求数据异常,状态码:" + XMLHttpRequest.status+",Error:"+errorThrown+",textStatus:"+textStatus);
                    
                    $(".loadDiv_view_"+name).hide();
                    $(".buttonDiv_view_"+name).show();
                }
            });
        },
        
        updateMonitorStatus: function(ip,status) {
            
            $.ajax({
                type: "post",
                url: 'updateMonitorStatus.action',
                data: {
                    "ip": ip,
                    "status1": status,
                },
                dataType: "json",
                success: function(data) {
                   
                    if (data.retCode != "1000") {
                    	 alert("更新"+ip+"Monitor状态失败!");
                    } 
                },
                error: function (XMLHttpRequest, textStatus, errorThrown) {
                    alert("请求数据异常,状态码:" + XMLHttpRequest.status+ ",<br/>"+XMLHttpRequest.readyState+  ",<br/>"+XMLHttpRequest.responseText+",<br/>Error:"+errorThrown+",<br/>textStatus:"+textStatus);
                }
            });
        },
        
        updateClientSetupStatus: function(ip,status) {
            
            $.ajax({
                type: "post",
                url: 'updateClientSetupStatus.action',
                data: {
                    "ip": ip,
                    "status2": status,
                },
                dataType: "json",
                success: function(data) {
                   
                    if (data.retCode != "1000") {
                    	 alert("更新"+ip+"ClientSetupStatus!");
                    } 
                },
                error: function (XMLHttpRequest, textStatus, errorThrown) {
                    alert("请求数据异常,状态码:" + XMLHttpRequest.status+ ",<br/>"+XMLHttpRequest.readyState+  ",<br/>"+XMLHttpRequest.responseText+",<br/>Error:"+errorThrown+",<br/>textStatus:"+textStatus);
                }
            });
        },
        
        postDeploy: function(name,ip,os) {
            
            $(".loadDiv_"+name).show();
            $(".buttonDiv_"+name).hide();
            
            $.ajax({
                type: "post",
                url: 'deploy.action',
                data: {
                    "ip": ip,
                    "os": os
                },
                dataType: "json",
                success: function(data) {
                	$(".loadDiv_"+name).hide();
                    $(".buttonDiv_"+name).show();
                    
                	if(data.data=="false")
     			    {
     			    	alert("更新"+ip+"客户端失败!");
     			    } 
                	else
                		{
                		monitordeploy.listVmInfosByPage();
                		}
                	
                },
                error: function (XMLHttpRequest, textStatus, errorThrown) {
                	$(".loadDiv_"+name).hide();
    	            $(".buttonDiv_"+name).show();
                    alert("请求数据异常,状态码:" + XMLHttpRequest.status+ ",<br/>"+XMLHttpRequest.readyState+  ",<br/>"+XMLHttpRequest.responseText+",<br/>Error:"+errorThrown+",<br/>textStatus:"+textStatus);
                }
            });
         },
         
         postkill: function(name,ip,os) {
             
             $(".loadDiv_kill_"+name).show();
             $(".buttonDiv_kill_"+name).hide();
             
             $.ajax({
                 type: "post",
                 url: 'kill.action',
                 data: {
                     "ip": ip,
                     "os": os
                 },
                 dataType: "json",
                 success: function(data) {
                 	$(".loadDiv_kill_"+name).hide();
                     $(".buttonDiv_kill_"+name).show();
                     
                 	if(data.data=="false")
      			    {
      			    	alert("杀死"+ip+"监控进程失败!");
      			    } 
                 	             	
                 },
                 error: function (XMLHttpRequest, textStatus, errorThrown) {
                 	$(".loadDiv_kill_"+name).hide();
     	            $(".buttonDiv_kill_"+name).show();
                     alert("请求数据异常,状态码:" + XMLHttpRequest.status+ ",<br/>"+XMLHttpRequest.readyState+  ",<br/>"+XMLHttpRequest.responseText+",<br/>Error:"+errorThrown+",<br/>textStatus:"+textStatus);
                 }
             });
          },
         
         viewAllStatus:function() {
        	 $("input[type='checkbox']").each(
        			 function(){
        				 if($(this).get(0).checked)
        					 {
        					
        					 var name = $(this).attr("class").substr(6);
        					 //alert(name);
        					 $(".i_view_"+name).click();
        					 }
        				 
        			 }
        	 );
         },
         
         deployAll:function() {
        	 $("input[type='checkbox']").each(
        			 function(){
        				 if($(this).get(0).checked)
        					 {
        					
        					 var name = $(this).attr("class").substr(6);
        					 //alert(name);
        					 $(".i_"+name).click();
        					 }
        				 
        			 }
        	 );
         },
         
         killAll:function() {
        	 $("input[type='checkbox']").each(
        			 function(){
        				 if($(this).get(0).checked)
        					 {
        					
        					 var name = $(this).attr("class").substr(6);
        					 //alert(name);
        					 $(".ikill_"+name).click();
        					 }
        				 
        			 }
        	 );
         },
         
        checkAll:function(){
        	$("input[type='checkbox']").each(
       			 function(){
       				 $(this).attr("checked","true");  
       			 }
       	 );
        },
        
        uncheckAll:function(){
        	 $("input[type='checkbox']").each(
        			 function(){
        				 $(this).removeAttr("checked"); 
        			 }
        	 );
        },
        
        loadVmTAB: function() {
            monitordeploy.listVmInfosByPage("init");
            $('#vms').tab('show');
        },
        //VM END
        userOps: ops(4),
        bootpagFuc: function() {
        	 
            $('#pagination').bootpag({
                total: 1,
                maxVisible: 10
            }).on('page', function(event, num) {
                monitordeploy.jpageIndex = num;
                monitordeploy.listVmInfosByPage();
            });
        }
    });
    
    avalon.ready(function() {
        if (monitordeploy.userOps) {
            monitordeploy.loadVmTAB();
           
        } else {
            redirectAdminIndexPage();
        }
        monitordeploy.bootpagFuc();
    //    $(".loadDiv").hide();
    });
    
    
    monitordeploy.$watch("jpageSize", function(newValue) {
        monitordeploy.pagesize1Cls = "";
        monitordeploy.pagesize2Cls = "";
        monitordeploy.pagesize3Cls = "";
        if (newValue == monitordeploy.pagesize1) {
            monitordeploy.pagesize1Cls = "pageSizeSelected";
        } else if (newValue == monitordeploy.pagesize2) {
            monitordeploy.pagesize2Cls = "pageSizeSelected";
        } else if (newValue == monitordeploy.pagesize3) {
            monitordeploy.pagesize3Cls = "pageSizeSelected";
        }
    })
    

      

     
  • 相关阅读:
    http参数传递方式
    Api接口管理工具推荐
    IntelliJ IDEA 插件推荐
    spring服务器接收参数格式
    SSM框架的常用注解整理
    Java map 详解
    遍历Map集合四中方法
    bean对应mapper.xml字段
    Java简历与面试
    SQL的case when then else end语句的用法
  • 原文地址:https://www.cnblogs.com/chenjiazhu/p/7423680.html
Copyright © 2020-2023  润新知