前面已经完成了一个简单的项目,项目开发完成后,进入测试,然后发布到生产环境。这章的目标就是一次编译,就可以部署到测试环境和生产环境。
SpringBoot项目编译
调整项目
首先调整一下HelloApplication类中的"/hello" api移到com.biboheart.demos.api包中(有点强迫症,不喜欢在入中类中放API)。
在com.biboheart.demos.api包中创建一个类"HelloController"
内容如下:
package com.biboheart.demos.api;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class HelloController {
@Value("${custom.name:default}")
private String customName;
@RequestMapping(value = "/hello")
public String hello(String name) {
System.out.println("配置文件自定义配置的值是: " + customName);
return "hello " + name + " with " + customName;
}
}
原来HelloApplication的内容
package com.biboheart.demos;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@SpringBootApplication
@RestController
public class HelloApplication {
@Value("${custom.name:default}")
private String customName;
public static void main( String[] args ) {
SpringApplication.run(HelloApplication.class, args);
}
@RequestMapping(value = "/hello")
public String hello(String name) {
System.out.println("配置文件自定义配置的值是: " + customName);
return "hello " + name;
}
}
改为
package com.biboheart.demos;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class HelloApplication {
public static void main( String[] args ) {
SpringApplication.run(HelloApplication.class, args);
}
}
启动项目,看看当前效果

控制台打印

回顾
回顾下这个API,代码
@RestController
public class HelloController {
@Value("${custom.name:default}")
private String customName;
@RequestMapping(value = "/hello")
public String hello(String name) {
System.out.println("配置文件自定义配置的值是: " + customName);
return "hello " + name + " with " + customName;
}
}
通过@Value,从配置文件中获取custom.name的值,如果没有配置这个值,则值为default。
当访问api “/hello”是,控制台打印这个值,返回"hello" + [传入参数的值] + " with " + [配置的值]
配置文件是这样的
server:
port: 80
custom:
name: bhhello
停止运行,改下配置文件
server:
port: 80
custom:
name: bhhello-app
运行项目,查看访问结果


当前目录

编译项目
完成项目之后需要编译(打包)后发布。点击IDEA下方的“Terminal”,打开命令行窗口


输入
cd bhhello
进入项目目录

执行maven打包命令
mvn package

显示"BUILD SUCCESS" 表示打包成功,可以在target目录中看到编译完成的jar文件。

部署项目
项目编译完成后。开始部署项目。首先部署到测试服务器,供测试人员测试。SpringBoot的项目适合部署到linux服务器,windows中也是可以运行这个项目,但是做系统服务似乎比较麻烦。我们这里不讲windows环境的部署,只讲linux环境中的部署。这个环境要自行想办法了,可以安装虚拟机(前面已经安装过docker,那时候已经安装了虚拟机)。我就远程到自己的阿里云服务器部署。
在windows中执行项目
打开cmd,进入target目录。

执行
java -jar bhhello-1.0.0-SNAPSHOT.jar
出错了,显示bhhello-1.0.0-SNAPSHOT.jar中没有主清单属性

可以进入项目的pom.xml文件,加上一个spring-boot-maven-plugin插件。
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<executable>true</executable>
</configuration>
</plugin>
</plugins>
</build>
这里我们不加在本项目的pom.xml文件中,我们加在bhparent(即bhhello项目的父项目)的pom.xml中。

加这里的好处,后面开发的子项目中都不需要再加这个plugin。
下面是/bhparent/pom.xml文件的内容
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.biboheart.demos</groupId>
<artifactId>bhparent</artifactId>
<packaging>pom</packaging>
<version>1.0.0-SNAPSHOT</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.3.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-undertow</artifactId>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
</dependency>
<!-- 我常用的一些工具写在这个包里,源码地址:https://gitee.com/biboheart/brick 已经在maven中央仓库发布 -->
<dependency>
<groupId>com.biboheart</groupId>
<artifactId>bh-brick</artifactId>
<version>0.0.6</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<executable>true</executable>
</configuration>
</plugin>
</plugins>
</build>
<modules>
<module>bhhello</module>
</modules>
</project>
重新编译项目

编译完成后,再次执行

启动完成,访问api

控制台中打印出相应字符串

发布到服务器
服务器需要安装java。
用xshell连接服务器,打开服务器操作界面。服务器是centos7的环境。域名www.blueheart.cn已经解析到这台服务器。后面的访问会通过域名访问。

进入/opt目录,把项目部署到这个目录中。

上传文件到/opt,我用xftp上传

ls命令查看目录中的文件

改下文件名称,这个名称有点不方便使用,而且在升级版本之后,版本号变化会导致文件名变化,会涉及到其它文件的修改。
执行命令mv改文件,把文件名改成bhhello.jar
mv bhhello-1.0.0-SNAPSHOT.jar bhhello.jar

把bhhello.jar改成可执行文件
chmod 500 bhhello.jar

启动项目

也可以用/opt/bhhello.jar启动项目

访问api


结果正确。只是这样还不够,现在如果把xshell窗口关闭,或者中止当前执行。服务就会停止。我们需要给它放到后台运行。我的方案是配置成系统服务。
配置centos系统服务
进入目录/etc/systemd/system,执行vi bhhello.service编辑文件bhhello.service
[Unit]
Description=bh hello server
After=syslog.target
[Service]
User=root
ExecStart=/opt/bhhello.jar
SuccessExitStatus=143
[Install]
WantedBy=multi-user.target
按"esc"键退出编辑模式,输入":wq"保存退出。
执行命令systemctl start bhhello启动项目
执行命令systemctl status bhhello -l 查看服务状态

看到服务正在启动。访问api结果相同。

如果需要开机自动启动服务,只需运行命令systemctl enable bhhello

多环境配置
上面已经完成项目部署。从开发环境搭建到编码到编译发布,基本走通。
假设现在项目是部署在测试环境中,测试通过后,部署到生产环境中。对于这个小项目没什么问题,在生产环境中走一遍上面的部署流程就可以。如果测试环境中的一些参数与生产环境中不一样的话呢,假如测试连接的数据库与生产环境中连接的数据库是不同一个。那么就需要修改配置文件,再编译,再发布到生产环境。这样就不合适了,重新编译后就会有些不确定因素存在。说得严重了点,控制好可能也不会出大问题。总归是不如一次编译,同一个文件在不同环境中运行。
spring boot提供了多环境配置的解决方案。下面来体验下。
解决方案
SpringBoot可以有多个配置文件,根据不同的环境选择不同的配置文件。可以把各环境相同的配置项配置在一个文件中同,区别的项分多个文件配置。在运行项目的时候传参选择环境。这样描述比较难以理解。下面实践下。
修改配置文件
原来的配置文件修改下,增加spring.profiles.active:dev配置项和值。dev表示开发环境,这个值是自己定义的。这里这样定义
dev: 开发环境
test: 测试环境
prod: 生产环境
application.yml文件结果
server:
port: 80
spring:
profiles:
active: dev
custom:
name: bhhello-app
在src/main/resources目录中,即application.yml同目录中创建三个文件application-dev.yml,application-test.yml,application-prod.yml 分别是开发环境、测试环境、生产环境的配置。把通用的配置写在application.yml中。
这里只是做一个演示,用每个环境中的custom.name的值的变化来演示配置的变化。
application-dev.yml的内容
custom:
name: bhhello-app-dev
application-test.yml的内容
custom:
name: bhhello-app-test
application-prod.yml的内容
custom:
name: bhhello-app-prod
目录结构如下

现在我们在开发环境中(IDEA)中启动项目

控制台中会打印出当前执行的配置环境
访问下api,因为这里有4个yml配置文件,打印的结果会是哪个呢?

打印的是bhhello-app-dev。
如果改一下application.yml中spring.profiles.active的值如下
server:
port: 80
spring:
profiles:
active: test
custom:
name: bhhello-app
重启服务后,再访问。访问结果就会变化成application-test.yml中的配置。


编译部署
这几个配置文件都是打包在.jar文件中的,如果不能解决部署的时候改变spring.profiles.active的值,就达不到一次编译,根据环境不同配置的需求。下面先把spring.profiles.active的值改回dev,开发调试的时候都是这个值。这个值的变化需要在部署的时候不重新编译的情况下变化。
执行mvn package编译打包成.jar

先停止linux服务器中,前面运行的bhhello服务。使用命令systemctl stop bhhello停止服务,可以查看一下状态是否停止。

上传刚刚打包的bhhello-1.0.0-SNAPSHOT.jar文件到服务器的/opt目录中,与前面一致。这里有个更便捷的方法,先在本地修改好文件名再覆盖上传,就不用再执行chmod 500 命令了。


先用命令行执行试试,/opt/bhhello.jar。可以看到现在选择的是dev的配置。

访问api验证下。

修改环境配置
按键盘Ctrl+c停止程序。
如果要修改配置文件中的一个值,可以在命令后跟上--[属性]=[值],是命令后面空格,再跟上两个“-”,接上属性=值。这里需要修改spring.profiles.active的值为test,这是部署测试环境的。
执行命令/opt/bhhello.jar --spring.profiles.active=test

访问验证一下

这样,在不重新编译的情况下改变了配置值。
接下来,修改服务文件,因为最终的启动是通过服务启动的。
进入目录/etc/systemd/system,执行命令vi bhhello.service,进入查看文件内容,按键盘i键进入编辑模式,修改如下
[Unit]
Description=bh hello server
After=syslog.target
[Service]
User=root
ExecStart=/opt/bhhello.jar --spring.profiles.active=test
SuccessExitStatus=143
[Install]
WantedBy=multi-user.target
保存文件,执行命令systemctl daemon-reload刷新服务。
执行systemctl start bhhello启动服务,执行systemctl status bhhello -l查看服务状态

访问api验证结果

结果如预期一致。
后记
部署到生产环境的话,同上面测试文件的部署流程。把.service文件中的test改成prod。就选择了生产环境的配置值。还可以更多环境的个性化配置。只要spring.profiles.active的值与配置文件名配置,application-[spring.profiles.active].yml。如增加一个配置文件application-hhh.yml,部署的时候命令中跟上--spring.profiles.active=hhh ,服务就会根据application-hhh.yml中的配置值执行。
网友评论