我是這樣使用SpringBoot(多環(huán)境配置與部署)

目錄

前面已經(jīng)完成了一個(gè)簡(jiǎn)單的項(xiàng)目,項(xiàng)目開發(fā)完成后,進(jìn)入測(cè)試,然后發(fā)布到生產(chǎn)環(huán)境。這章的目標(biāo)就是一次編譯,就可以部署到測(cè)試環(huán)境和生產(chǎn)環(huán)境。

SpringBoot項(xiàng)目編譯

調(diào)整項(xiàng)目

首先調(diào)整一下HelloApplication類中的"/hello" api移到com.biboheart.demos.api包中(有點(diǎn)強(qiáng)迫癥,不喜歡在入中類中放API)。
在com.biboheart.demos.api包中創(chuàng)建一個(gè)類"HelloController"
內(nèi)容如下:

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;
    }
}

原來(lái)HelloApplication的內(nèi)容

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);
    }
}

啟動(dòng)項(xiàng)目,看看當(dāng)前效果


訪問(wèn)結(jié)果

控制臺(tái)打印


控制臺(tái)打印

回顧

回顧下這個(gè)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;
    }
}

通過(guò)@Value,從配置文件中獲取custom.name的值,如果沒有配置這個(gè)值,則值為default。
當(dāng)訪問(wèn)api “/hello”是,控制臺(tái)打印這個(gè)值,返回"hello" + [傳入?yún)?shù)的值] + " with " + [配置的值]
配置文件是這樣的

server:
  port: 80
custom:
  name: bhhello

停止運(yùn)行,改下配置文件

server:
  port: 80
custom:
  name: bhhello-app

運(yùn)行項(xiàng)目,查看訪問(wèn)結(jié)果


結(jié)果

控制臺(tái)打印

當(dāng)前目錄


目錄結(jié)構(gòu)

編譯項(xiàng)目

完成項(xiàng)目之后需要編譯(打包)后發(fā)布。點(diǎn)擊IDEA下方的“Terminal”,打開命令行窗口


打開命令行界面

命令行窗口

輸入

cd bhhello

進(jìn)入項(xiàng)目目錄


項(xiàng)目目錄

執(zhí)行maven打包命令

mvn package
執(zhí)行結(jié)果

顯示"BUILD SUCCESS" 表示打包成功,可以在target目錄中看到編譯完成的jar文件。


編譯后的文件

部署項(xiàng)目

項(xiàng)目編譯完成后。開始部署項(xiàng)目。首先部署到測(cè)試服務(wù)器,供測(cè)試人員測(cè)試。SpringBoot的項(xiàng)目適合部署到linux服務(wù)器,windows中也是可以運(yùn)行這個(gè)項(xiàng)目,但是做系統(tǒng)服務(wù)似乎比較麻煩。我們這里不講windows環(huán)境的部署,只講linux環(huán)境中的部署。這個(gè)環(huán)境要自行想辦法了,可以安裝虛擬機(jī)(前面已經(jīng)安裝過(guò)docker,那時(shí)候已經(jīng)安裝了虛擬機(jī))。我就遠(yuǎn)程到自己的阿里云服務(wù)器部署。

在windows中執(zhí)行項(xiàng)目

打開cmd,進(jìn)入target目錄。


進(jìn)入target目錄

執(zhí)行

java -jar bhhello-1.0.0-SNAPSHOT.jar

出錯(cuò)了,顯示bhhello-1.0.0-SNAPSHOT.jar中沒有主清單屬性


出錯(cuò)了

可以進(jìn)入項(xiàng)目的pom.xml文件,加上一個(gè)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>

這里我們不加在本項(xiàng)目的pom.xml文件中,我們加在bhparent(即bhhello項(xiàng)目的父項(xiàng)目)的pom.xml中。


父項(xiàng)目的pom

加這里的好處,后面開發(fā)的子項(xiàng)目中都不需要再加這個(gè)plugin。
下面是/bhparent/pom.xml文件的內(nèi)容

<?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>

        <!-- 我常用的一些工具寫在這個(gè)包里,源碼地址:https://gitee.com/biboheart/brick 已經(jīng)在maven中央倉(cāng)庫(kù)發(fā)布 -->
        <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>

重新編譯項(xiàng)目


編譯項(xiàng)目

編譯完成后,再次執(zhí)行


啟動(dòng)spring boot

啟動(dòng)完成,訪問(wèn)api
得到正確結(jié)果

控制臺(tái)中打印出相應(yīng)字符串


控制臺(tái)打印

發(fā)布到服務(wù)器

服務(wù)器需要安裝java。
用xshell連接服務(wù)器,打開服務(wù)器操作界面。服務(wù)器是centos7的環(huán)境。域名www.blueheart.cn已經(jīng)解析到這臺(tái)服務(wù)器。后面的訪問(wèn)會(huì)通過(guò)域名訪問(wèn)。

服務(wù)器界面

進(jìn)入/opt目錄,把項(xiàng)目部署到這個(gè)目錄中。
目錄

上傳文件到/opt,我用xftp上傳
上傳界面

ls命令查看目錄中的文件
查看文件

改下文件名稱,這個(gè)名稱有點(diǎn)不方便使用,而且在升級(jí)版本之后,版本號(hào)變化會(huì)導(dǎo)致文件名變化,會(huì)涉及到其它文件的修改。
執(zhí)行命令mv改文件,把文件名改成bhhello.jar

mv bhhello-1.0.0-SNAPSHOT.jar bhhello.jar
改名

把bhhello.jar改成可執(zhí)行文件

chmod 500 bhhello.jar
修改文件屬性

啟動(dòng)項(xiàng)目


啟動(dòng)項(xiàng)目

也可以用/opt/bhhello.jar啟動(dòng)項(xiàng)目


啟動(dòng)程序

訪問(wèn)api
訪問(wèn)結(jié)果

服務(wù)控制臺(tái)

結(jié)果正確。只是這樣還不夠,現(xiàn)在如果把xshell窗口關(guān)閉,或者中止當(dāng)前執(zhí)行。服務(wù)就會(huì)停止。我們需要給它放到后臺(tái)運(yùn)行。我的方案是配置成系統(tǒng)服務(wù)。

配置centos系統(tǒng)服務(wù)

進(jìn)入目錄/etc/systemd/system,執(zhí)行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"保存退出。
執(zhí)行命令systemctl start bhhello啟動(dòng)項(xiàng)目
執(zhí)行命令systemctl status bhhello -l 查看服務(wù)狀態(tài)


服務(wù)狀態(tài)

看到服務(wù)正在啟動(dòng)。訪問(wèn)api結(jié)果相同。


訪問(wèn)結(jié)果

如果需要開機(jī)自動(dòng)啟動(dòng)服務(wù),只需運(yùn)行命令systemctl enable bhhello
開機(jī)自啟動(dòng)

多環(huán)境配置

上面已經(jīng)完成項(xiàng)目部署。從開發(fā)環(huán)境搭建到編碼到編譯發(fā)布,基本走通。
假設(shè)現(xiàn)在項(xiàng)目是部署在測(cè)試環(huán)境中,測(cè)試通過(guò)后,部署到生產(chǎn)環(huán)境中。對(duì)于這個(gè)小項(xiàng)目沒什么問(wèn)題,在生產(chǎn)環(huán)境中走一遍上面的部署流程就可以。如果測(cè)試環(huán)境中的一些參數(shù)與生產(chǎn)環(huán)境中不一樣的話呢,假如測(cè)試連接的數(shù)據(jù)庫(kù)與生產(chǎn)環(huán)境中連接的數(shù)據(jù)庫(kù)是不同一個(gè)。那么就需要修改配置文件,再編譯,再發(fā)布到生產(chǎn)環(huán)境。這樣就不合適了,重新編譯后就會(huì)有些不確定因素存在。說(shuō)得嚴(yán)重了點(diǎn),控制好可能也不會(huì)出大問(wèn)題??倸w是不如一次編譯,同一個(gè)文件在不同環(huán)境中運(yùn)行。
spring boot提供了多環(huán)境配置的解決方案。下面來(lái)體驗(yàn)下。

解決方案

SpringBoot可以有多個(gè)配置文件,根據(jù)不同的環(huán)境選擇不同的配置文件??梢园迅鳝h(huán)境相同的配置項(xiàng)配置在一個(gè)文件中同,區(qū)別的項(xiàng)分多個(gè)文件配置。在運(yùn)行項(xiàng)目的時(shí)候傳參選擇環(huán)境。這樣描述比較難以理解。下面實(shí)踐下。

修改配置文件

原來(lái)的配置文件修改下,增加spring.profiles.active:dev配置項(xiàng)和值。dev表示開發(fā)環(huán)境,這個(gè)值是自己定義的。這里這樣定義

dev: 開發(fā)環(huán)境
test: 測(cè)試環(huán)境
prod: 生產(chǎn)環(huán)境

application.yml文件結(jié)果

server:
  port: 80
spring:
  profiles:
    active: dev
custom:
  name: bhhello-app

在src/main/resources目錄中,即application.yml同目錄中創(chuàng)建三個(gè)文件application-dev.yml,application-test.yml,application-prod.yml 分別是開發(fā)環(huán)境、測(cè)試環(huán)境、生產(chǎn)環(huán)境的配置。把通用的配置寫在application.yml中。
這里只是做一個(gè)演示,用每個(gè)環(huán)境中的custom.name的值的變化來(lái)演示配置的變化。
application-dev.yml的內(nèi)容

custom:
  name: bhhello-app-dev

application-test.yml的內(nèi)容

custom:
  name: bhhello-app-test

application-prod.yml的內(nèi)容

custom:
  name: bhhello-app-prod

目錄結(jié)構(gòu)如下


新目錄結(jié)構(gòu)

現(xiàn)在我們?cè)陂_發(fā)環(huán)境中(IDEA)中啟動(dòng)項(xiàng)目


控制臺(tái)

控制臺(tái)中會(huì)打印出當(dāng)前執(zhí)行的配置環(huán)境
訪問(wèn)下api,因?yàn)檫@里有4個(gè)yml配置文件,打印的結(jié)果會(huì)是哪個(gè)呢?


dev

打印的是bhhello-app-dev。
如果改一下application.yml中spring.profiles.active的值如下
server:
  port: 80
spring:
  profiles:
    active: test
custom:
  name: bhhello-app

重啟服務(wù)后,再訪問(wèn)。訪問(wèn)結(jié)果就會(huì)變化成application-test.yml中的配置。


訪問(wèn)結(jié)果變化

控制臺(tái)打印

編譯部署

這幾個(gè)配置文件都是打包在.jar文件中的,如果不能解決部署的時(shí)候改變spring.profiles.active的值,就達(dá)不到一次編譯,根據(jù)環(huán)境不同配置的需求。下面先把spring.profiles.active的值改回dev,開發(fā)調(diào)試的時(shí)候都是這個(gè)值。這個(gè)值的變化需要在部署的時(shí)候不重新編譯的情況下變化。
執(zhí)行mvn package編譯打包成.jar


完成打包

先停止linux服務(wù)器中,前面運(yùn)行的bhhello服務(wù)。使用命令systemctl stop bhhello停止服務(wù),可以查看一下狀態(tài)是否停止。


停止服務(wù)

上傳剛剛打包的bhhello-1.0.0-SNAPSHOT.jar文件到服務(wù)器的/opt目錄中,與前面一致。這里有個(gè)更便捷的方法,先在本地修改好文件名再覆蓋上傳,就不用再執(zhí)行chmod 500 命令了。
修改文件名后上傳

覆蓋

先用命令行執(zhí)行試試,/opt/bhhello.jar??梢钥吹浆F(xiàn)在選擇的是dev的配置。


dev

訪問(wèn)api驗(yàn)證下。
訪問(wèn)api

修改環(huán)境配置

按鍵盤Ctrl+c停止程序。
如果要修改配置文件中的一個(gè)值,可以在命令后跟上--[屬性]=[值],是命令后面空格,再跟上兩個(gè)“-”,接上屬性=值。這里需要修改spring.profiles.active的值為test,這是部署測(cè)試環(huán)境的。
執(zhí)行命令/opt/bhhello.jar --spring.profiles.active=test


執(zhí)行

訪問(wèn)驗(yàn)證一下


驗(yàn)證

這樣,在不重新編譯的情況下改變了配置值。
接下來(lái),修改服務(wù)文件,因?yàn)樽罱K的啟動(dòng)是通過(guò)服務(wù)啟動(dòng)的。
進(jìn)入目錄/etc/systemd/system,執(zhí)行命令vi bhhello.service,進(jìn)入查看文件內(nèi)容,按鍵盤i鍵進(jìn)入編輯模式,修改如下
[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

保存文件,執(zhí)行命令systemctl daemon-reload刷新服務(wù)。
執(zhí)行systemctl start bhhello啟動(dòng)服務(wù),執(zhí)行systemctl status bhhello -l查看服務(wù)狀態(tài)


啟動(dòng)服務(wù)

訪問(wèn)api驗(yàn)證結(jié)果


結(jié)果

結(jié)果如預(yù)期一致。

后記

部署到生產(chǎn)環(huán)境的話,同上面測(cè)試文件的部署流程。把.service文件中的test改成prod。就選擇了生產(chǎn)環(huán)境的配置值。還可以更多環(huán)境的個(gè)性化配置。只要spring.profiles.active的值與配置文件名配置,application-[spring.profiles.active].yml。如增加一個(gè)配置文件application-hhh.yml,部署的時(shí)候命令中跟上--spring.profiles.active=hhh ,服務(wù)就會(huì)根據(jù)application-hhh.yml中的配置值執(zhí)行。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容