==> 學習彙總(持續更新)
==> 從零搭建後端基礎設施系列(一)-- 背景介紹
首先,說一下大概的思路
- 在服務器上部署服務的時候,是不是用的本地打包好的jar包呢?答案是的,所以這種就是手動部署的方式,特別的繁瑣。那麼如何能在服務器上完成這一步呢?
- 得先拿到代碼吧?怎麼拿?本地傳上去嗎?當然不是,那多low啊。我們直接從git上拉下來不就好了。
- 有了代碼,我們是不是就可以像在本地一樣使用mvn命令打包成jar包?想一想打包過程中還需要什麼?會不會報錯?答案是肯定的,在本地打包的時候,我們有本地maven倉庫,裏面放着我們的thrift服務的jar包,所以本地打包的時候是不會報錯的。所以我們的思路就來了,能不能把依賴的jar包放到一個自己搭建的私服中,然後配置好一切,打包就沒問題了吧?答案是YES!
- 打成jar包後,還需要自己手動運行?那這個自動化部署,也只是自動化打包了而已啊。。。所以接下來的思路,如何讓它自動運行。辦法還是有很多的,比如我在項目裏面寫一個運行腳本,到時候代碼拉下來,打完包之後,直接運行就完事了。沒錯就是這麼簡單,但是我們回到第一步,我們怎麼不上服務器,讓它自己就能完成這一切?
- OK,來到了我們的第四步,需要一個第三方服務,姑且叫它自動化發佈服務,這個服務的功能暫且就只有一個,那就是和服務器上的代理進程通信,告訴它,運行xxx腳本,這樣就能完成一個自動化發佈的過程了。
好了,思路有了,接下來,開幹!
一、配置git環境
爲了方便,直接使用yum安裝吧
yum install git.x86_64
測試一下
將代碼拉下來
可以拉取指定分支
git clone -b 你想要拉的分支 git地址
二、配置maven環境
在web服務器和thrift服務器上,配置maven環境
直接使用yum安裝,圖方便
如果沒有指定maven後面的名字,它會安裝有關maven的依賴、插件,我比較懶,就不選了
yum install maven
測試一下
接下來,讓你們看看打包的時候的報錯信息
記住,不要在父project那裏打包
mvn clean install -Dmaven.test.skip=true
報錯
和預測的一樣,找不到core包
三、搭建nexus私服
接下來,搭建一個私服,將我們的jar包deploy上去
可以參考這篇文章搭建私服 第8章 私服nexus
我這裏主要說一下坑和一些配置信息
首先,需要去下載nexus,但是坑爹的是官網下不下來。。。所以我從其它渠道下載下來了。可以百度雲上下,可以CSDN上下,都有資源。
然後按照步驟操作,都挺順暢的
接着就是配置settings.xml文件
這個需要在服務器、本地都配置
<?xml version="1.0"?>
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 http://maven.apache.org/xsd/settings-1.0.0.xsd">
<!--http://maven.apache.org/ref/3.5.0/maven-settings/settings.html-->
<profiles>
<profile>
<id>nexus</id>
<repositories>
<repository>
<id>nexus</id>
<name>crop-nexus</name>
<url>http://192.168.0.103:8081/nexus/content/groups/public/</url>
<releases>
<!-- true表示開啓倉庫發佈版本下載,false表示禁止 -->
<enabled>true</enabled>
</releases>
<snapshots>
<!-- true表示開啓倉庫快照版本下載,false表示禁止 -->
<enabled>true</enabled>
</snapshots>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>nexus</id>
<url> http://192.168.0.103:8081/nexus/content/groups/public/</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<!-- 禁止快照版本,防止不穩定的插件影響項目構建 -->
<enabled>false</enabled>
</snapshots>
</pluginRepository>
</pluginRepositories>
</profile>
</profiles>
<!-- 激活nexus私服 -->
<activeProfiles>
<activeProfile>nexus</activeProfile>
</activeProfiles>
<mirrors>
<mirror>
<id>nexus</id>
<mirrorOf>*</mirrorOf>
<name>crop-nexus</name>
<url>http://192.168.0.103:8081/nexus/content/groups/public/</url>
</mirror>
</mirrors>
<servers>
<!-- 發佈Releases版的賬號,ID要與distributionManagement中的Releases ID一致 -->
<server>
<id>nexus-releases</id>
<username>admin</username>
<password>你的密碼</password>
</server>
<!-- 發佈snapshot版的賬號,ID要與distributionManagement中的snapshot ID一致 -->
<server>
<id>nexus-snapshot</id>
<username>admin</username>
<password>你的密碼</password>
</server>
</servers>
</settings>
接着代碼裏面,配置一下
<distributionManagement>
<repository>
<id>nexus-releases</id>
<name>corp nexus-releases</name>
<url>http://192.168.0.103:8081/nexus/content/repositories/releases/</url>
</repository>
<snapshotRepository>
<id>nexus-snapshot</id>
<name>corp nexus-snapshot</name>
<url>http://192.168.0.103:8081/nexus/content/repositories/snapshots/</url>
</snapshotRepository>
</distributionManagement>
然後點擊deploy,即可把jar包發佈到私服倉庫中
PS:第一次deploy的時候和第一次在服務上打包的時候,會非常的慢,耐心等待即可
好了,私服倉庫搭建起來了,我們再回過頭來打包一遍項目看看
哈哈,看,是不是打包成功了,接下來,運行看看,是不是能運行成功
OK,運行成功,現在就差搭建一個自動化發佈服務,讓它幫我們把這整個流程自己走一遍,就達到自動化發佈的效果了。
四、搭建自動化發佈服務
首先,我們先模擬自動化發佈服務的操作,寫一個自動化腳本,然後手動執行它,看看效果如何?
完美,沒報錯,哈哈,run.sh腳本如下
#!/bin/bash
echo '【INFO】正在拉取代碼……'
git clone https://github.com/coderxj/min-system-web-service.git
echo '【INFO】拉取代碼完成,目錄:' `pwd`
echo '\n\n\n'
cd ./min-system-web-service/min-system-service/
echo '【INFO】正在打包……'
mvn clean install -Dmaven.test.skip=true
cd ./target
echo '【INFO】打包完成,目錄:' `pwd`
echo '\n\n\n'
echo '【INFO】開始啓動服務……'
java -jar min-system-service-*.jar
到了這一步,思路已經非常清晰了吧?無非就是,在服務器上運行一個代理進程,然後自動化發佈服務通過socket跟這個代理進程通信,告訴它,你要運行這個腳本了。但是這還不夠,我們應該還能夠指定它發佈哪個分支。
因爲時間不夠,先暫時寫個超級簡單的demo
(PS:完整的自動化發佈服務代碼,等有時間寫了,會傳到github上)
服務端:
@RestController
@RequestMapping("/publish")
public class AutoPublishController {
private ServerSocket serverSocket;
private Socket socket;
{
new Thread(new Runnable() {
@Override
public void run() {
try {
serverSocket = new ServerSocket(9999);
socket = serverSocket.accept();
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
}
@PostMapping
public Object publish(@RequestBody PublishParamVo publishParamVo){
try {
socket.getOutputStream().write("run".getBytes());
} catch (IOException e) {
return new HashMap<Object, Object>(){{put("error", e.getMessage());}};
}
return new HashMap<Object, Object>(){{put("success", "發佈成功");}};
}
}
客戶端(代理進程)
public class Main {
public static void main(String[] args) {
try {
Socket socket = new Socket("192.168.0.101", 9999);
if(socket.isConnected()){
byte[] buf = new byte[32];
socket.getInputStream().read(buf);
if((new String(buf).trim()).equalsIgnoreCase("run")){
exec("sh /root/run.sh");
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
public static void exec(String cmd) {
Process process = null;
try {
process = Runtime.getRuntime().exec(cmd);
InputStream in = process.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(in));
for(String line = br.readLine(); line != null; line = br.readLine()) {
System.out.println(line);
}
} catch (IOException e) {
System.out.println(e);
} finally {
if (process != null){
process.destroy();
}
}
}
}
大概就是,部署自動化發佈服務,接着在各個服務器上運行客戶端,最後使用postman模擬發佈請求操作。
結果如圖
五、總結
自動化發佈的必要條件
- 每個服務器上都需要配置好git、maven等環境,用於拉取代碼,打包項目。
- 需要自己搭建一個私服倉庫,用於將自己的jar包deploy上去,之後供其它服務器拉取。
- 需要有一個自動化發佈服務,只需要選擇想發佈的項目和分支,即可遠程自動發佈。
- 項目裏面必須配置好發佈腳本,或者可以配置參數,讓自動化發佈服務來組裝都行。
改進的地方(可以說非常多了,這個例子,非常的簡單和粗糙。。。)
- 環境的搭建,可以寫腳本自動化搭建。
- 私服倉庫的配置,可以更定製化一些。
- 自動化發佈服務,應該支持和每個服務器的長連接,以及掉線重連,那麼就要保證服務器上的代理進程不能被kill,準確的說,就算kill了,或者機器重啓了,也要自動重啓這個進程,並且無限重連自動化發佈服務。這裏面涉及到的點很多(PS:我對java的socket不熟悉,所以這次纔沒將這個服務的代碼寫好,待我研究一番,再上代碼)。
- 發佈腳本如何更通用,如何約定更好?
……
==> CODE