【从零搭建后端基础设施系列(八)】-- 自动化部署服务

==> 学习汇总(持续更新)
==> 从零搭建后端基础设施系列(一)-- 背景介绍


首先,说一下大概的思路

  • 在服务器上部署服务的时候,是不是用的本地打包好的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
原创文章 257 获赞 277 访问量 69万+

猜你喜欢

转载自blog.csdn.net/qq_18297675/article/details/99481420