SpringBoot --spring.profiles.active相關問題

徐州謝廣坤發表於2020-09-27

springboot配置檔案

  1. springboot支援yml或者properties兩種方式
  2. 無論是哪種方式,都可以指定activeprofiles
    profiles官方文件
  3. spring支援在application.properties中直接配置資料庫連線。
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/test?useSSL=false&useUnicode=true&characterEncoding=UTF-8&useOldAliasMetadataBehavior=true&useJDBCCompliantTimezoneShift=true&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true
spring.datasource.username=test
spring.datasource.password=test12345
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
  1. 當我們開發功能的時候,區分本地測試,測試伺服器,正式上線的伺服器,分別為dev,qa,prod
  2. 很重要的一點是,這三個環境的資料庫的密碼並不一樣,因此如果你每次都重新修改資料庫的配置,然後再重新出版本,會很麻煩,因為程式碼並沒有變化,只不過環境變了

因此springboot,支援active的指向

也支援命令列的方式修改java -jar test.jar --spring.profiles.active=prod

profiles支援多個active

在版本稍微高一點點的springboot中,都是支援多個active的profiles的
spring.profiles.active=dev,qa
多個的規則是,靠後的會覆蓋在前面的配置
比如devqa的properties裡面,都有spring.datasource.password
你的本地dev裡面是dev12345,而qa上是qa12345
如果qa是在,後面,那麼qaspring.datasource.password就會覆蓋dev裡面的密碼,所以會使用qa裡面的密碼。

profiles支援外部檔案

假設專案內,只有兩個properties檔案,一個是本地除錯的,一個是release到正式伺服器上的檔案。
properties
則在自己公司是可以這麼設定的,並且可以順利執行的。
但如果要把該工程,分發給客戶的環境上執行,就會有問題了,因為客戶的環境是千奇百怪的。
除非要求客戶的環境和各種配置,跟我們的正式伺服器一模一樣,否則就會出現各種密碼錯誤,最突出的就是客戶的資料庫密碼想要自己設定。這樣我們的配置檔案不夠用了,直接在外部配置一個properties,裡面把所有客戶想要自己設定的屬性,都寫上,然後放在後面,覆蓋我們本身的prod或者dev
外部properties
java -jar test.jar --spring.profiles.active=prod,ext執行,就會讀取application-ext.properties中的內容了,並且級別比prod中的高,所以即使war內的properties的值是自己本地的值,也不要緊,只需要在外部的配置檔案中修改就行。

centOS7伺服器上執行springboot問題

服務需要開機啟動

自己寫一個service固然可以,但是一般還是用supervisor來管理jar包。
因此自己將服務寫在了supervisor的外部檔案中,即:開啟include

[include] 
files = supervisord.d/*.ini    ;可以指定一個或多個以.ini結束的配置檔案

supervisord.d資料夾下面,我新建了一個javatest.ini檔案。

[program:test]
command=/usr/bin/java -Xms128m -Xmx256m -jar /opt/test/test.war --spring.profiles.active=prod,ext --server.port=8080
autostart=true
startsecs=10
autorestart=false
startretries=3
user=root
priority=999
redirect_stderr=false
stdout_logfile_maxbytes=10MB
stdout_logfile_backups = 20
stdout_logfile=/opt/test/logs/java8080.out
stderr_logfile=/opt/test/logs/java8080err.out
stderr_logfile_maxbytes=10MB
stderr_logfile_backups=20
stderr_capture_maxbytes=1MB
stderr_events_enabled=false
stopasgroup=false
killasgroup=false

使用supervisor來管理我們的服務,是它可以開機啟動。

資料庫連線不上

但執行了之後,還是會提示DB連線錯誤,看了一下錯誤資訊
java.sql.SQLException: Access denied for user 'aaaaaaa'@'localhost' (using password: YES)
明明在application-ext.properties中修改了資料庫的使用者名稱和密碼,為什麼用的還是prod中的使用者名稱呢?

分析

  1. javatest.ini檔案沒有寫對
    自己檢視了supervisor官方文件,裡面有解釋,在command裡面,帶引數的,有時候需要用""包起來才行,結果改成command=/usr/bin/java -Xms128m -Xmx256m -jar /opt/test/test.war --spring.profiles.active="prod,ext" --server.port=8080也還是不行。

  2. 分析入參
    自己在WebApplicationmain方法中,將所有入參都列印出來,發現入參並沒有問題。

  3. 懷疑先後順序問題
    於是使用了spring.profiles.include,修改command:

command=/usr/bin/java -Xms128m -Xmx256m -jar /opt/test/test.war --spring.profiles.active=ext --spring.profiles.include=prod --server.port=8080

發現依然報錯,這個時候,忽然想到,有可能是沒有發現properties檔案
於是在supervisord.conf的同級目錄下面,將application-ext.properties檔案複製到該資料夾。
發現一切正常。

結論

--spring.profiles.active=prod,ext中的prodext,spring會去尋找application-prod.propertiesapplication-ext.properties包括war包內,和執行指令碼的那個目錄下面,而不是war存放的目錄下。

相關文章