当前位置: 首页 > 后端技术 > Java

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

时间:2023-04-01 18:10:42 Java

的想法曾经是后端。我通常写代码并提交。这周突然被要求发布到开发环境。每次都要把包拷贝到服务器很麻烦。虽然知道Jenkins,但是这个工具的配置项比较多,不知道能不能自己做一个。所以我写了代码。如果要发布一个软件到服务器上,首先要分步进行。1.拉取代码2.打包3.复制到服务器4.重启服务。一开始因为需要合并代码,我是手动拉取代码的。程序还没有完成这一步。打包起来比较简单。只需使用maven包。最多加个mavenpackage-Pdev(看你springboot里的配置)。打包后,你必须在服务器上获取包。很自然地,我想到了scp命令,好在windows10支持scp,但是一般scp需要密码,所以你得把你的公钥粘贴到服务器上。登录服务器cd~/.sshls显示authorized_keysid_rsaid_rsa.pubknown_hosts将你的windows公钥添加到authorized_keys文件中,所以我的第一个脚本是这样的:在windows下新建一个batcall"mavenpath\mvn"package-Ppro这里新建一个脚本,因为maven运行后窗口不会自动关闭,无法执行下一行。如果启动一个新的脚本,这个问题就可以解决了。start/waitcopy.bat其中copy的bat是scpC:\你的路径\你的project.jarroot@ip地址:/实际目录看起来很简单。复制jar包后如何重启呢?一开始想到用ssh远程执行命令,但是一直找不到方便合适的方案,所以选择了java来解决。自己写了个jar包,提前扔了。代码很简单@ComponentpublicclassTask{privateStringlastMd5="";*//***每20秒执行一次*//*@Scheduled(fixedRate=20000)publicvoidtestTasks()throwsIOException{Stringmd5=DigestUtils.md5DigestAsHex(newFileInputStream("package.jaronyourserver"));如果(md5.equals(lastMd5)){返回;}System.out.println(md5);lastMd5=md5;String[]cmd=newString[]{"/bin/sh","-c","ps-ef|grepyour.jar|grep-vgrep|awk'{print$2}'|xargs-rkill-9&&java-Dloader.path=/directory/lib-jar/Yourserverpackage.jar"};//05.17补充,这里有一个坑,执行上面的命令写java-jar时,输出必须重定向到一个文件,否则可能会发生缓冲区溢出,导致死锁Processprocess=null;尝试{process=Runtime.getRuntime().exec(cmd);}catch(Exceptione){}}}*/首先,我输入的maven是一个只包含class文件,不包含依赖的包,所以一个包很小(便于传输和fetchmd5)。上面的监控程序很简单,每20秒运行一次,将运行的jar包的md5(旧值)与上传的jar包的md5(新值)进行比较,如果不同,则认为发生了变化,然后会调用bash脚本关闭原来的程序,然后重新启动程序。至此,我个人的自动部署就成功了。如果我每次拉取代码后都想更新,直接点bat等几秒就可以了。同事看了之后觉得效果很好,但是我提了一个建议,既然你已经用过java了,为什么不把所有的工作都用java来做呢,我们对这门语言很熟悉。于是又重新修改,找了资料,有几个可用的包。1.JGIT(其功能是拉git代码)org.eclipse.jgitorg.eclipse.jgit5.10.0.202012080955-rpublicclassJgitUtil{//验证privatestaticCredentialsProvidercredentialsProvider;//这是项目拉取后的.git文件,用它来判断是否做gitclone或拉取操作privatestaticStringlocalGitUrl;static{credentialsProvider=newUsernamePasswordCredentialsProvider(PropUtils.get("用户名"),PropUtils.get("密码"));localGitUrl=System.getProperty("user.dir")+"/"+PropUtils.get("projectName")+"/.git";}/***gitclone*@paramgitUrl*@parambranch*@throwsGitAPIException*/publicstaticvoidgitClone(StringgitUrl,Stringbranch)throwsGitAPIException{Git.cloneRepository().setURI(gitUrl).setBranch(branch).setCredentialsProvider(credentialsProvider).setDirectory(newFile(System.getProperty("user.dir")+"/"+PropUtils.get("projectName"))).call();}/***gitpull操作*@throwsIOException*@throwsGitAPIException*/publicstaticvoidpull()throwsIOException,GitAPIException{//判断仓库是否已经存在,如果不存在则cloneFilelocal=newFile(localGitUrl);if(!local.exists()){//第一个参数是git拉取的地址,第二个参数是分支名gitClone(PropUtils.get("gitUrl"),PropUtils.get("branch"));返回;}//拉取已经存在的RepositorylocalRepo=newFileRepository(localGitUrl);Gitgit=newGit(localRepo);PullCommandpullCommand=git.pull();pullCommand.setCredentialsProvider(credentialsProvider);pullCommand.call();}}2.maven-invoker(它的作用是打包项目)org.apache.maven.sharedmaven-invoker3.1.0private静态InvocationRequest请求;私人静态调用者调用者;//需要设置maven目录privatestaticStringmavenHome=System.getProperty("user.dir")+"/"+PropUtils.get("mavenName");static{request=newDefaultInvocationRequest();//配置maven的settings.xml文件,仓库路径一定要配置好request.setUserSettingsFile(newFile(mavenHome+"/conf/settings.xml"));Stringenv=PropUtils.get("env");StringpackageStr="包";if(!StringUtils.isEmpty(env)){packageStr+="-P"+env;}//这个设置maven命令,一般只packagerequest.setGoals(Collections.singletonList(packageStr));//设置项目的pom文件pomFile=newFile(System.getProperty("user.dir")+"/"+PropUtils.get("projectName")+"/pom.xml");if(!pomFile.exists()){pomFile=newFile(PropUtils.get("pomFile"));}request.setPomFile(pomFile);//配置maven拉取依赖的路径,我直接用mavenFilerepo=newFile(mavenHome+"/repo");如果(!repo.exists()){repo.mkdir();}request.setLocalRepositoryDirectory(repo);调用者=新的DefaultInvoker();invoker.setMavenHome(新文件(mavenHome));}//PublicstaticvoidmvnPackage()throwsMavenInvocationException{invoker.execute(request);}然后前端给了一个按钮,controller层简单的执行gitpull,执行就用maven打包java,用Runtime.getRuntime().exec(cmd)执行linux命令就可以了。linux命令包括杀死旧的java。命令就在上面。cp命令移动打包的包。这里推荐使用/cp-ruv前面的斜线是使用cp本身的命令。默认的cp命令有别名,实际调用是cp-i。每次复制都会提示是否覆盖,加上斜线就不行复制完成后,重启jar包。如果想在java调用linux命令后得到控制台的输出,可以这样做process=Runtime.getRuntime().exec(cmd);LineNumberReaderbr=null;br=newLineNumberReader(newInputStreamReader(process.getInputStream()));StringBuffersb=newStringBuffer();弦线;while((line=br.readLine())!=null){sb.append(line).append("\n");}但是不是很推荐,packingcommand很多无用的输出,这个是我之前在网页调用linux命令的时候查的,这里用处不大,但是我还是把cp结果打印到前端,主要看是否成功。前端效果,只有两个按钮,一个释放后端,一个释放前端(这个就搞定了,没话说忘记删了)。如果嫌麻烦可以直接用接口request,postman或者window直接用curl,然后写一个bat(笑)点击【发布前端】,可以看到cp命令打印出来了。

猜你喜欢