【從零搭建後端基礎設施系列(八)】-- 自動化部署服務

==> 學習彙總(持續更新)
==> 從零搭建後端基礎設施系列(一)-- 背景介紹


首先,說一下大概的思路

  • 在服務器上部署服務的時候,是不是用的本地打包好的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
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章