从零构建可视化jar包部署平台JarManage

简介: 在java项目部署过程中,由于内外部各种因素,可能会遇到一些感觉操作不便捷的场景,例如jar包未随系统自动启动需要每次手动重启

项目背景

在java项目部署过程中,由于内外部各种因素,可能会遇到一些感觉操作不便捷的场景,例如

  • jar包未随系统自动启动需要每次手动重启
  • 系统vpn堡垒机多重防御更新繁琐
  • 系统无图形化界面命令行操作复杂
  • 等等......

在工作中之前也总结了windows的Jar包部署工具linux下的jar包自动化部署脚本,这次就想着否能将二者统一结合,本着简单/高效/功能专一的原则,做出一

个可视化jar包部署平台,JarManage应运而生

功能介绍

项目地址:https://gitee.com/code2roc/jar-manage

支持在线创建项目,上传Jar包,自动备份,配置启动参数,注册系统服务,查看启动日志等功能,具有以下优点

  • 基于servlet开发,依赖简洁,部署包10MB左右
  • 结合嵌入式tomcat一键部署,无外部容器依赖
  • 使用h2db存储数据,无外部数据库依赖
  • 适配windows/linux平台,满足多种环境
  • 具体项目经平台部署后自动注册系统服务,无需担心服务器重启

系统架构图如下

系统截图展示

技术分析

平台识别

首先通过系统os识别是windows平台还是linux平台

String os = System.getProperty("os.name").toLowerCase();
if (os.startsWith("win")) {
   
   
   platform = DepolyPlatform.Windows;
}

通过system-release文件识别部分基于CentOS开发的Linux系统

String command = "cat /etc/system-release";
String result = CMDUtil.executeLinuxCommand(command);
if (result.startsWith("Red Hat")) {
   
   
   platform = DepolyPlatform.LinuxRedHat;
} else if (result.startsWith("CentOS")) {
   
   
   platform = DepolyPlatform.LinuxCentOS;
} else if (result.startsWith("openEuler")) {
   
   
   platform = DepolyPlatform.LinuxOpenEuler;
}

通过issue文件识别部分基于Ubuntu/Debian开发的Linux系统

command = "cat /etc/issue";
result = CMDUtil.executeLinuxCommand(command);
if (!StringUtil.isEmpty(result)) {
   
   
  if (result.startsWith("Ubuntu")) {
   
   
     platform = DepolyPlatform.LinuxUbuntu;
} else if (result.startsWith("Debian")) {
   
   
      platform = DepolyPlatform.LinuxDebian;
   }
}

windows注册服务

通过sc query命令判断服务状态

    public String getStatus(String serviceName) {
   
   
        String status = DepolyStatus.UnInstall;
        try {
   
   
            String command = "sc query " + serviceName;
            String commandResultFilePath = CMDUtil.executeWindowCommandStoreFile(command);
            BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(commandResultFilePath)));
            String line = reader.readLine();
            while (line != null) {
   
   
                if (line.trim().startsWith("STATE")) {
   
   
                    if (line.trim().substring(line.trim().indexOf(":") + 1, line.trim().indexOf(":") + 4).trim().equals("1"))
                        status = DepolyStatus.Stopped;
                    else if (line.trim().substring(line.trim().indexOf(":") + 1, line.trim().indexOf(":") + 4).trim().equals("2"))
                        status = DepolyStatus.Startting;
                    else if (line.trim().substring(line.trim().indexOf(":") + 1, line.trim().indexOf(":") + 4).trim().equals("3"))
                        status = DepolyStatus.Stopping;
                    else if (line.trim().substring(line.trim().indexOf(":") + 1, line.trim().indexOf(":") + 4).trim().equals("4"))
                        status = DepolyStatus.Running;
                }
                line = reader.readLine();
            }
        } catch (IOException e) {
   
   
            LogUtil.error(e);
        }
        return status;
    }

通过winsw这个开源项目配置exe和xml文件将jar包注册为windows服务,项目地址:https://github.com/winsw/winsw/

linux注册服务

通过systemctl status命令判断服务状态

    public String getStatus(String serviceName) {
   
   
        String status = DepolyStatus.UnInstall;
        try {
   
   
            String command = "systemctl status " + serviceName;
            String commandResultFilePath = CMDUtil.executeLinuxCommandWithStore(command);
            BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(commandResultFilePath)));
            String line = reader.readLine();
            while (line != null) {
   
   
                if (line.trim().startsWith("Active")) {
   
   
                    if (line.trim().indexOf("inactive (dead)") > 0)
                        status = DepolyStatus.Stopped;
                    else if (line.trim().indexOf("active (running)") > 0)
                        status = DepolyStatus.Running;
                    else if (line.trim().indexOf("failed") > 0)
                        status = DepolyStatus.Stopped;
                }
                line = reader.readLine();
            }
        } catch (IOException e) {
   
   
            LogUtil.error(e);
        }
        return status;
    }

通过拷贝service文件到systemd/system目录下注册linux服务

yml配置文件识别

  • maven配置
        <dependency>
            <groupId>org.yaml</groupId>
            <artifactId>snakeyaml</artifactId>
            <version>1.26</version>
        </dependency>
  • 配置文件
jarmanage:
  port: 8555
  username: admin
  password: abcd@1234
  backupcount: 5
  • 工具类
    public static String getConfigValue(String configName){
   
   
        String configValue = "";
        try{
   
   
            Yaml yaml = new Yaml();
            InputStream resourceAsStream = new FileInputStream(new File("resources"+File.separator+"application.yml"));
            Map obj = yaml.load(resourceAsStream);
            Map<String,Object> param = (Map) obj.get("jarmanage");
            configValue = ConvertUtil.convert2String(param.get(configName));
        }catch (Exception e){
   
   
            LogUtil.error(e);
        }
        return configValue;
    }

h2database使用

  • maven引用
        <dependency>
            <groupId>com.h2database</groupId>
            <artifactId>h2</artifactId>
            <version>2.1.214</version>
        </dependency>
  • 工具类
    public static Connection getConnection() throws Exception {
   
   
        File file = new File("database");
        Connection conn = DriverManager.getConnection("jdbc:h2:file:" + file.getAbsolutePath() + File.separator + "manage", "root", "abcd@1234");
        return conn;
    }

    public static void executeSQL(String sql) {
   
   
        try {
   
   
            Connection conn = getConnection();
            Statement stmt = conn.createStatement();
            stmt.execute(sql);
            stmt.close();
            conn.close();
        } catch (Exception e) {
   
   
            LogUtil.error(e);
        }
    }

servelt内置tomcat打包

  • maven引用
        <dependency>
            <groupId>org.apache.tomcat.embed</groupId>
            <artifactId>tomcat-embed-core</artifactId>
            <version>9.0.35</version>
        </dependency>
        <dependency>
            <groupId>org.apache.tomcat.embed</groupId>
            <artifactId>tomcat-embed-el</artifactId>
            <version>9.0.35</version>
        </dependency>
        <dependency>
            <groupId>org.apache.tomcat.embed</groupId>
            <artifactId>tomcat-embed-jasper</artifactId>
            <version>9.0.35</version>
        </dependency>
  • 手动启动
            //启动tomcat服务
            // 1.创建一个内嵌的Tomcat
            Tomcat tomcat = new Tomcat();
            // 2.设置Tomcat端口
            tomcat.setPort(8555);
            // 3.设置工作目录,tomcat需要使用这个目录进行写一些东西
            final String baseDir = "workspace" + File.separator;
            tomcat.setBaseDir(baseDir);
            tomcat.getHost().setAutoDeploy(false);
            // 4. 设置webapp资源路径
            String webappDirLocation = "webapp" + File.separator;
            StandardContext ctx = (StandardContext) tomcat.addWebapp("/", new File(webappDirLocation).getAbsolutePath());
            // 5. 设置上下文路每径
            String contextPath = "";
            ctx.setPath(contextPath);
            ctx.addLifecycleListener(new Tomcat.FixContextListener());
            ctx.setName("jar-manage");
            tomcat.getHost().addChild(ctx);
            //6.启动
            tomcat.getConnector();
            tomcat.start();
            tomcat.getServer().await();
  • 打包包含引用类库,自定义配置xml,指定运行class
        <plugins>
            <plugin>
                <!-- 打包包含引用 -->
                <artifactId>maven-assembly-plugin</artifactId>
                <configuration>
                    <descriptors>
                        <!-- 自定义配置 -->
                        <descriptor>package.xml</descriptor>
                    </descriptors>
                    <archive>
                        <manifest>
                            <!-- 运行类 -->
                            <mainClass>com.code2roc.jarmanage.Application</mainClass>
                        </manifest>
                    </archive>
                </configuration>
                <executions>
                    <execution>
                        <id>make-assembly</id>
                        <phase>package</phase>
                        <goals>
                            <goal>single</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>8</source>
                    <target>8</target>
                </configuration>
            </plugin>
        </plugins>
<assembly xmlns="http://maven.apache.org/ASSEMBLY/2.1.1"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://maven.apache.org/ASSEMBLY/2.1.1 https://maven.apache.org/xsd/assembly-2.1.1.xsd">
    <!-- TODO: a jarjar format would be better -->
    <id>depoly</id>
    <formats>
        <format>jar</format>
    </formats>
    <includeBaseDirectory>false</includeBaseDirectory>
    <dependencySets>
        <dependencySet>
            <outputDirectory>/</outputDirectory>
            <useProjectArtifact>true</useProjectArtifact>
            <unpack>true</unpack>
            <scope>runtime</scope>
        </dependencySet>
    </dependencySets>
    <fileSets>
        <fileSet>
            <directory>src/main/webapp/</directory>
            <outputDirectory>/webapp</outputDirectory>
            <includes>
                <include>**/**</include>
            </includes>
        </fileSet>
        <fileSet>
            <directory>src/main/resources/</directory>
            <outputDirectory>/resources</outputDirectory>
            <includes>
                <include>**/**</include>
            </includes>
        </fileSet>
    </fileSets>
</assembly>
目录
相关文章
|
3月前
|
Kubernetes Java Docker
利用(K8S)配合Docker部署jar包
通过Docker打包并部署到Kubernetes(K8S)集群的过程。首先,通过SpringBoot生成jar包,接着在K8S环境中创建并编辑Dockerfile文件。随后构建Docker镜像,并将其推送到镜像仓库。最后,通过一系列kubectl命令(如get pods、get svc、logs等),展示了如何在K8S中管理应用,包括查看Pod状态、服务信息、Pod日志以及重启Pod等操作。
203 3
|
4月前
|
敏捷开发 Java 测试技术
阿里云云效产品使用合集之如何下载流水线构建过程中生成的jar
云效作为一款全面覆盖研发全生命周期管理的云端效能平台,致力于帮助企业实现高效协同、敏捷研发和持续交付。本合集收集整理了用户在使用云效过程中遇到的常见问题,问题涉及项目创建与管理、需求规划与迭代、代码托管与版本控制、自动化测试、持续集成与发布等方面。
|
2月前
|
存储 数据可视化 Java
震惊!如何在linux下部署项目,部署/运行jar包 超详细保姆级教程!
如何在Linux系统下部署和运行Java项目jar包,包括传输文件到Linux、使用nohup命令运行jar包、查看端口状态、杀死进程和查看项目运行状态,以及如何解决“没有主清单属性”的错误。
640 1
震惊!如何在linux下部署项目,部署/运行jar包 超详细保姆级教程!
|
5月前
|
Java
[JarEditor]可直接修改jar包的IDEA插件
### 修改JAR包变得更简单:JarEditor插件简介 **背景:** 开发中常需修改JAR包中的class文件,传统方法耗时费力。JarEditor插件让你一键编辑JAR包内文件,无需解压。 **插件使用:** 1. **安装:** 在IDEA插件市场搜索JarEditor并安装。 2. **修改class:** 打开JAR文件中的class,直接编辑,保存后一键构建更新JAR。 3. **文件管理:** 右键菜单支持在JAR内新增/删除/重命名文件等操作。 4. **搜索:** 使用内置搜索功能快速定位JAR包内的字符串。
538 2
[JarEditor]可直接修改jar包的IDEA插件
|
4月前
|
Java Maven
构建Springboot项目、实现简单的输出功能、将项目打包成可以执行的JAR包(详细图解过程)
这篇文章详细介绍了构建SpringBoot项目的过程,包括新建工程、选择环境配置、添加依赖、项目结构说明,并演示了如何编写一个简单的Controller控制器实现输出功能,最后讲解了如何使用Maven将项目打包成可执行的JAR包,并提供了运行JAR包的命令和测试效果。
构建Springboot项目、实现简单的输出功能、将项目打包成可以执行的JAR包(详细图解过程)
|
5月前
|
弹性计算 Java Serverless
Serverless 应用引擎操作报错合集之上传自定义JAR包,启动时报错,是什么导致的
Serverless 应用引擎(SAE)是阿里云提供的Serverless PaaS平台,支持Spring Cloud、Dubbo、HSF等主流微服务框架,简化应用的部署、运维和弹性伸缩。在使用SAE过程中,可能会遇到各种操作报错。以下是一些常见的报错情况及其可能的原因和解决方法。
|
4月前
|
Java Linux Shell
【Azure 应用服务】部署Jar到App Service for Linux,因启动命令路径配置错误而引起:( Application Error 问题
【Azure 应用服务】部署Jar到App Service for Linux,因启动命令路径配置错误而引起:( Application Error 问题
|
4月前
|
Java Spring
【Azure 应用服务】一个 App Service 同时部署运行两个及多个 Java 应用程序(Jar包)
【Azure 应用服务】一个 App Service 同时部署运行两个及多个 Java 应用程序(Jar包)
|
4月前
|
Java Windows
【Azure 应用服务】App Service 部署txt静态文件和Jar包在不同目录中的解决办法
【Azure 应用服务】App Service 部署txt静态文件和Jar包在不同目录中的解决办法
|
4月前
|
Java Spring
【Azure 应用服务】记一次Azure Spring Cloud 的部署错误 (az spring-cloud app deploy -g dev -s testdemo -n demo -p ./hellospring-0.0.1-SNAPSHOT.jar --->>> Failed to wait for deployment instances to be ready)
【Azure 应用服务】记一次Azure Spring Cloud 的部署错误 (az spring-cloud app deploy -g dev -s testdemo -n demo -p ./hellospring-0.0.1-SNAPSHOT.jar --->>> Failed to wait for deployment instances to be ready)

热门文章

最新文章

下一篇
DataWorks