我是这样使用SpringBoot(多环境配置与部署)

目录

前面已经完成了一个简单的项目,项目开发完成后,进入测试,然后发布到生产环境。这章的目标就是一次编译,就可以部署到测试环境和生产环境。

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目录。


进入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中。


父项目的pom

加这里的好处,后面开发的子项目中都不需要再加这个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>

重新编译项目


编译项目

编译完成后,再次执行


启动spring boot

启动完成,访问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配置文件,打印的结果会是哪个呢?


dev

打印的是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的配置。


dev

访问api验证下。
访问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中的配置值执行。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 157,012评论 4 359
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,589评论 1 290
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 106,819评论 0 237
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,652评论 0 202
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 51,954评论 3 285
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,381评论 1 210
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,687评论 2 310
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,404评论 0 194
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,082评论 1 238
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,355评论 2 241
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,880评论 1 255
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,249评论 2 250
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,864评论 3 232
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,007评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,760评论 0 192
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,394评论 2 269
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,281评论 2 259

推荐阅读更多精彩内容