Java打包、上傳服務器、部署springboot應用簡單腳本

一.應用場景:

本地開發java應用程序,當部署時,要打包java應用,上傳jar包到遠程服務器,登錄遠程服務器並執行指令進行重啓java服務。

有時候需要頻繁反覆進行該操作,每次都這樣一步一步的做,有些繁瑣並且浪費時間,因此寫了一份shell腳本,只需要執行一個腳本指令,便自動做了上述所有的事情,節省了許多事。

二.環境

1.springboot的應用,java -jar跑服務,linux服務器使用賬號密碼登錄(使用私鑰等只需要修改對應的scp,ssh命令即可)

2.shell腳本,需要shell運行環境支持。mac下默認支持,windows需要使用powershell,區別於cmd,該程序支持shell腳本運行。當使用密鑰時,需要修改id_rsa文件的讀寫權限,設置爲當前用戶權限就好,具體百度即可。

三.思路

重現步驟,第一步,mvn打包java應用,第二步,上傳jar包和對應的配置文件到服務器,第三步,登錄服務器,執行部署腳本

四.實現

1.首先新建打包腳本 package.sh

#!/bin/bash

mvn clean package -Dmaven.test.skip=true

該腳本進行打包指令,需要依賴maven環境,具體需要配置MAVEN_HOME還有PATH,也不多說了

2.寫好上傳服務器腳本 scp.sh

#! /usr/bin/expect
#目標服務器ip,接收第一個參數
set target_ip [lindex $argv 0]
#目標服務器端口,接收第二個參數
set target_port [lindex $argv 1]
#目標服務器用戶名,接收第三個參數
set scpUser [lindex $argv 2]
#目標服務器密碼,接收第四個參數
set scpPwd [lindex $argv 3]
#傳輸到目標服務器的路徑
set target_path [lindex $argv 4]
#打印接收到的參數
for {set i 0} {$i < $argc} {incr i} {
 #打印參數
  puts "arg $i: [lindex $argv $i]"
}
#從第六個參數開始,作爲發送的文件參數,通配符時,會把匹配到的所有文件依次傳進
for {set i 5} {$i < $argc} {incr i} {
 #scp指令  -P是端口,默認ssh端口是22, -r是發送的文件路徑, :後面是目標地址,如果使用私鑰,可以用 scp -i xxx/id_rsa -P ,把-i放在最前面
  spawn scp -P $target_port -r [lindex $argv $i] $scpUser@$target_ip:$target_path
 #使用expect的功能,當交互出現,匹配到password時,幫我們輸入密碼值
  expect "*password:"
  send "$scpPwd\n"
 #交互出現,如果沒有interact,則文件傳輸過程會被打斷
  interact
}

該腳本是expect腳本,需要使用expect來執行,而不是sh

3.在服務器上運行的部署腳本deploy.sh

#!/bin/bash
#當前路徑,使用第一個參數
currentPath=$1
#如果第一個參數爲空,則pwd(運行腳本的當前目錄)作爲當前路徑
if [ ! -n "$currentPath" ]; then
  currentPath=$PWD
fi
#打印當前路徑
echo $currentPath
#存放pid的文件路徑配置
pidFile="$currentPath/test.pid" 
#jar包的路徑配置
jarPath="$currentPath/test/target/test.jar"
#target jar包路徑配置
targetPath="$currentPath/test.jar"
#當pid文件存在時,讀出pid文件的內容,kill掉該pid的進程
if [ -f $pidFile ]; then
    echo "pid file exists!"
    PID=$(cat $pidFile)           # 將PID從文件中讀取,並作爲一個變量
   #殺掉該進程
    kill -9 $PID
    echo "exec kill $PID success!"
fi
#判斷jarPath的文件路徑存不存在,如果存在,則用jarPath路徑部署,不存在,則用默認的targetPath部署
if [ -f $jarPath ]; then
  echo "jarPath exists"
    targetPath=$jarPath
fi
echo "執行啓動java程序指令"
#cd進去currentPath目錄,在該目錄下執行java -jar指令
cd $currentPath
#部署jar包的指令,nohup是指忽略掛起  > /dev/null是把nohup的輸入丟到一個空設備,即直接丟棄的意思, 2>&1 即所有類型日誌的輸出 &表示後臺運行,後面>表示把pid保存到當前目錄的test.pid文件中
#便於後續殺進程重啓
nohup java -jar $targetPath --spring.profiles.active=qa > /dev/null 2>&1 & echo $! >"$currentPath/test.pid"
echo "執行啓動java程序指令完成!"

4.遠程ssh執行指令腳本

#! /usr/bin/expect
set sshIp [lindex $argv 0]
set sshPort [lindex $argv 1]
set sshUser [lindex $argv 2]
set sshPwd [lindex $argv 3]
set cmd [lindex $argv 4]
set currentPath [lindex $argv 5]
#打印所有參數
for {set i 0} {$i < $argc} {incr i} {
puts "arg $i: [lindex $argv $i]"
}
#ssh執行遠程指令,如果使用私鑰,使用ssh -i xxx/id_rsa
spawn ssh -p $sshPort $sshUser@$sshIp $cmd $currentPath
expect {
  "yes/no" {send "yes\r";exp_continue}
  "*password" {send "$sshPwd\r"}
}
#結束expect
expect eof

 

5.最終一鍵打包上傳部署腳本auto.sh

#!/bin/bash
#獲取當前路徑
currentPath=$PWD
echo "====================開始打包===================="
#調用前面的打包腳本package.sh,所有的腳本放在同級目錄下,方便調用
sh $currentPath/package.sh
echo "====================打包成功!===================="
#配置遠程服務器的賬號
scpUser='test'
#遠程服務器的密碼
scpPwd="test123456"
#遠程服務器的ip
target_ip="192.168.1.1"
#遠程服務器的端口
target_port="22"
#發送的jar包路徑
from_path="$currentPath/test/target/test.jar"
#服務器部署的目錄,發送到服務器的目錄,需要在服務器先建好,不會自動創建目錄
target_path="/data/my_project"
#需要發送部署腳本,部署腳本deploy.sh的路徑
from_deploy_path="$currentPath/deploy.sh"
#發送配置文件,配置文件application.properties的路徑
from_properties_path="$currentPath/bggw/src/main/resources/application.properties"
#發送所有的配置文件,配置文件通配
from_all_properties_path="$currentPath/bggw/src/main/resources/*.properties"
#遠程服務器存放配置文件的路徑,需要在遠程服務器先創建好
target_properties_path="$target_path/config"
#如果配置文件路徑application.properties存在,就把配置文件路徑所有的properties發送到遠程服務器(如果不需要發送配置文件,直接註釋該段落即可)
if [ -f $from_properties_path ]; then
    echo "====================發送配置文件===================="
    #調用我們寫的scp.sh腳本文件,傳輸文件,expect腳本需要用expect調用
    expect $currentPath/scp.sh $target_ip $target_port $scpUser $scpPwd $target_properties_path $from_all_properties_path
    echo "====================發送配置文件完成===================="
fi
echo "====================發送配置文件到${target_ip}成功!===================="
echo "====================發送jar包到${target_ip}===================="
#調用我們寫的scp.sh腳本,發送jar包到遠程服務器
expect $currentPath/scp.sh $target_ip $target_port $scpUser $scpPwd $target_path $from_path
echo "====================發送jar包到${target_ip}成功!===================="
echo "====================發送部署腳本===================="
#調用我們寫的scp.sh腳本,發送部署腳本deploy.sh到遠程服務器
expect $currentPath/scp.sh $target_ip $target_port $scpUser $scpPwd $target_path $from_deploy_path
echo "====================發送部署腳本成功!===================="
#調用deploy.sh的指令配置
sshCmd="sh $target_path/deploy.sh"
echo "====================ssh服務器執行腳本===================="
#調用我們寫的ssh.sh腳本,遠程執行 sshCmd指令,即調用deploy.sh,即讓遠程服務器調用部署腳本
expect $currentPath/ssh.sh $target_ip $target_port $scpUser $scpPwd "$sshCmd" "$target_path"
echo "====================ssh服務器執行腳本結束===================="
echo "腳本執行結束"

 

到此所有的腳本已經寫完了,只需要在本地執行

 sh ./auto.sh

即可,調用自動部署腳本,把所有的腳本串聯起來,自動化部署。

五.最後

之所以拆分成這麼多腳本,也是爲了每個腳本都可以重新利用,不用重複寫scp和ssh的那一串指令,最主要是實驗覺得expect腳本和bash腳本貌似不能在同個文件同時使用,會有問題。

如果自己有其他的需求,進行自己的定製即可,裏面的一些參數需要自己修改,如遠程服務器的信息,文件的路徑信息等

java服務器部署一般不會如此簡單,會提前配置JAVA_HOME等其他信息,還有JVM運行的一些參數,該腳本僅作爲簡單的一個部署腳本,不作爲生產環境的使用,不過作爲測試環境,或者自己的服務器玩玩,還是可以的,生產環境如果沒有比較複雜的配置,當然也是沒有任何問題

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章