ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

springboot项目java自动打包部署到服务器上思路

2022-07-03 03:00:33  阅读:181  来源: 互联网

标签:java springboot jar maven static File new 服务器 String


以前作为后端,平时写好代码提交后就完事了,这周突然叫我做发布到开发环境的操作,每次打包的复制到服务器上又很麻烦,虽然知道Jenkins,但是这工具配置项也很多,就想着能不能自己做一个。于是就写起了代码。

想发布一个软件到服务器,先分步骤。

1.拉取代码

2.打包

3.复制到服务器

4.重启服务。

一开始,拉取代码的工作我是手动进行的,因为考虑到要合并代码。这一步还是不要给程序做了,打包的话比较简单,直接

maven package

就好,顶多加一个

maven package -P dev(看你springboot里的配置)

打包完了肯定要把包弄到服务器上,自然想到了scp命令,好在windows10是支持scp的,但是一般的scp需要密码,所以得把自己的公钥贴在服务器上。

登录到服务器

cd ~/.ssh
ls显示出
authorized_keys   id_rsa  id_rsa.pub  known_hosts
把你windows的公钥追加到authorized_keys文件里就可以

于是我的第一个脚本是这样的

windows下新建bat

call "maven路径\mvn" package -P pro
这里新建了脚本是因为maven运行完窗口不会自动关闭,没法执行下一行,新启脚本的话可以解决这个问题
start /wait copy.bat

其中copy的bat是

scp C:\你的路径\你的项目.jar root@ip地址:/实际目录

看上去非常简单

把jar包拷贝过去了后怎么让他重启呢?

一开始想到用ssh远程执行命令,结果没找到方便又合适的方案,选择了java解决。自己写了一个jar包事先丢上去。代码很简单

@Component
public class Task {

    private String lastMd5 = "";

    *//**
     * 每隔20秒执行一次
     *//*
    @Scheduled(fixedRate = 20000)
    public void testTasks() throws IOException {
        String md5 = DigestUtils.md5DigestAsHex(new FileInputStream("你的服务器上包.jar"));
        if(md5.equals(lastMd5)){
            return;
        }
        System.out.println(md5);
        lastMd5 = md5;
        String[] cmd = new String[]{"/bin/sh", "-c", "ps -ef|grep 你的.jar |grep -v grep | awk '{print $2}' | xargs -r kill -9 &&  java -Dloader.path=/目录/lib -jar /你的服务器上包.jar"};
        //05.17补充,这里有个坑,执行上面命令写java -jar时一定要把输出重定向到文件,不然可能会出现缓冲区溢出的情况,造成死锁
        Process process = null;
        try{
             process = Runtime.getRuntime().exec(cmd);
        }catch (Exception e){
            
        }

    }


}*/

首先说明下,我maven打的是只包含class文件的包,不包含依赖的,所以一个包很小(方便传输和取md5)。

上面监听程序很简单,20秒跑一次,对比正在跑的jar包的md5(旧值)与传上去的jar包md5(新值),如果不一样就认为改动了,就调用bash脚本关闭原有的程序,然后重新启动程序。

到这里,我个人的自动部署已经成功了,每次拉取代码后想要更新,点一下bat,等几秒就行了。

同事看完觉得效果很不错,不过提了个建议,你都上java了为什么不直接java把全部工作都做了,这语言我们熟。

于是又进行了改版,找了下资料后,有了几个可用包。

1.JGIT(它的作用是拉取git代码)

<dependency>
            <groupId>org.eclipse.jgit</groupId>
            <artifactId>org.eclipse.jgit</artifactId>
            <version>5.10.0.202012080955-r</version>
        </dependency>
public class JgitUtil {
    //验证
    private static CredentialsProvider credentialsProvider;
    //这个是项目拉取后的.git文件,用它来判断需要做git clone还是pull操作
    private static String localGitUrl;
    static {
        credentialsProvider = new UsernamePasswordCredentialsProvider(PropUtils.get("username"), PropUtils.get("password"));
        localGitUrl = System.getProperty("user.dir") + "/" + PropUtils.get("projectName") + "/.git";
    }

    /**
     * git克隆
     * @param gitUrl
     * @param branch
     * @throws GitAPIException
     */
    public static void gitClone(String gitUrl, String branch) throws GitAPIException {
        Git.cloneRepository()
                .setURI(gitUrl)
                .setBranch(branch)
                .setCredentialsProvider(credentialsProvider)
                .setDirectory(new File(System.getProperty("user.dir") + "/" + PropUtils.get("projectName")))
                .call();
    }

    /**
     * git拉取操作
     * @throws IOException
     * @throws GitAPIException
     */
    public static void pull() throws IOException, GitAPIException {
        //判断仓库是否已经存在,不存在就clone
        File local = new File(localGitUrl);
        if(!local.exists()){
            //第一个参数是git拉取的地址,第二个参数是分支名
            gitClone(PropUtils.get("gitUrl"), PropUtils.get("branch"));
            return;
        }
        //已经存在就pull
        Repository localRepo = new FileRepository(localGitUrl);
        Git git = new Git(localRepo);
        PullCommand pullCommand = git.pull();
        pullCommand.setCredentialsProvider(credentialsProvider);
        pullCommand.call();
    }
}

2.maven-invoker(它的作用是打包项目)

<dependency>
            <groupId>org.apache.maven.shared</groupId>
            <artifactId>maven-invoker</artifactId>
            <version>3.1.0</version>
        </dependency>
    private static InvocationRequest request;
    private static Invoker invoker;
    //需要设置maven目录
    private static String mavenHome = System.getProperty("user.dir") + "/" + PropUtils.get("mavenName");

    static {
        request = new DefaultInvocationRequest();
        //配置maven的settings.xml文件,里面仓库路径要配好
        request.setUserSettingsFile(new File(mavenHome + "/conf/settings.xml"));
        String env = PropUtils.get("env");
        String packageStr = "package";
        if(!StringUtils.isEmpty(env)){
            packageStr += " -P " + env;
        }
        //这个设置maven命令,一般只用package
        request.setGoals(Collections.singletonList(packageStr));
        
        //设置项目的pom所在
        File pomFile = new File(System.getProperty("user.dir") + "/" + PropUtils.get("projectName") + "/pom.xml");
        if(!pomFile.exists()){
            pomFile = new File(PropUtils.get("pomFile"));
        }
        request.setPomFile(pomFile);
        
        //配置maven拉取的依赖所在的路径,我直接和maven放一起了
        File repo = new File(mavenHome + "/repo");
        if(!repo.exists()){
            repo.mkdir();
        }
        request.setLocalRepositoryDirectory(repo);

        invoker = new DefaultInvoker();
        invoker.setMavenHome(new File(mavenHome));
    }

    //调用一下就能做拉取的操作
    public static void mvnPackage() throws MavenInvocationException {
        invoker.execute(request);
    }

然后前端给个按钮,controller层就简单了

执行一下git拉取,执行一下maven打包

java用Runtime.getRuntime().exec(cmd)执行linux命令就可以了

linux命令包括杀死旧的java,命令在上面了, cp命令移动打好的包,这里推荐用

/cp -ruv

前面带斜杠是要使用cp本身的命令,默认的cp命令有别名,实际调用的是cp -i,每次复制时会提示要不要覆盖,加上斜杠就不会了。

复制好后重启jar包就可以了。

如果你想获取java调用linux命令后控制台的输出,可以这样

process = Runtime.getRuntime().exec(cmd);
            LineNumberReader br = null;
            br = new LineNumberReader(new InputStreamReader(
                    process.getInputStream()));
            StringBuffer sb = new StringBuffer();
            String line;
            while ((line = br.readLine()) != null) {
                sb.append(line).append("\n");
            }

但不是很推荐,打包命令很多无用的输出,这个是我以前写网页端调用linux命令时查的,这里其实不太用得上,不过我自己还是把cp结果打印到前端了,主要是看下是否成功了。

前端效果,就两个按钮,一个发布后端,一个发布前端(这个做好了,暂无两个字忘了删了)。嫌麻烦可以直接用接口请求,post man或者window直接用curl,再写个bat(笑)

点个[发布前端],可以看到把cp命令打印出来了。

标签:java,springboot,jar,maven,static,File,new,服务器,String
来源: https://www.cnblogs.com/zeenzhou/p/16439133.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有