美文网首页spring bootJava专题
我是这样使用SpringBoot(多环境配置与部署)

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

作者: 碧波之心 | 来源:发表于2019-03-17 14:53 被阅读86次

    目录

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

    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中的配置值执行。

    相关文章

      网友评论

        本文标题:我是这样使用SpringBoot(多环境配置与部署)

        本文链接:https://www.haomeiwen.com/subject/vwmymqtx.html