java-jar jar包帶環(huán)境變量(參數(shù))啟動
需求
java工程我們可以編譯成jar也可以翻譯成war,一般地,war包我會丟到tomcat容器里,啟動tomcat來訪問服務(wù),端口、SSL證書、日志等等,都托給tomcat。
如果打的是jar包,我通常會用nohup啟動,比如生產(chǎn)環(huán)境的一些db、redis、第三方secret等不會配置到項(xiàng)目里,今天要記錄的便是用nohup java -jar 啟動jar包時如何加載環(huán)境變量配置的問題。
java語言開發(fā)的jar包啟動時可以按照如下方式加啟動參數(shù)。
方式一:-DpropName=propValue
這種方式應(yīng)該很快都能找到
-DpropName=propValue
比如:
java -jar -DdatabaseUrl="mysql://localhost:3306/pdb?user=root&password=root" ?-Dapp.key="123" -Dapp.secret="xxx" ?demo.jar
多個參數(shù)也可以。
方式二:參數(shù)直接跟在命令后面,多個參數(shù)之間用空格隔開
java -jar demo.jar JOURNAL_TREENODE_DATA-20190404174502.txt processType=1
這種方式參數(shù)就是jar包里主啟動類中main方法的args參數(shù),按順序來
方式三:使用springboot的方式,--propName=propValue方式
java -jar demo.jar ?--spring.profiles.active=dev ?--server.port=8181
注意:
運(yùn)行jar包時指定端口:java -jar xxx.jar --server.port=8088
若命令行傳入的server.port沒有作用,服務(wù)仍然使用8081端口啟動,原因是spring-cloud-config會覆蓋命令行傳入的參數(shù),這是有意為之,
辦法是在web-prod.yml中做點(diǎn)小改動,讓“配置”變得“可配置”:加一對花括符
server.port={port:8081}
用clojure開發(fā)的jar里有驚喜
在clojure上面的配置就變得詭異了,猜猜下面的配置能不能生效呢?
java -jar -Ddatabase-url="mysql://localhost:3306/pdb?user=root&password=root" ?-Dapp.key="123" -Dapp.secret="xxx" ?demo.jar
如果你用cider-conect
通過nrepl的端口連接上你的服務(wù),你會發(fā)現(xiàn),這個配置導(dǎo)致database-url
的值確實(shí)已經(jīng)改了,但是后面兩個沒有。
究其原因,我們java從classpath里獲取參數(shù)使用的是properties形式的,也就是json的格式。這不難理解,spring有它的辦法,clojure當(dāng)然也有自己的方式。
"app": {
? ?"key": "123",
? ?"secret":"xxx"
}
雖然json和我們的edn里map是很像的,但是畢竟是不同,于是要分析下現(xiàn)在的edn里的配置信息他是怎么讀取的呢?
代碼里的env
在config
這個namespace里找到了env
(defstate env
?:start
?(load-config
? :merge
? [(args)
? ?(source/from-system-props)
? ?(source/from-env)]))
cprop加載配置
cprop.source
這個文件就是用來加載edn文件的
(defn- env->path [k]
?(k->path k "_" #"__"))(defn read-system-env
?([]
? (read-system-env {}))
?([opts]
? (->> (System/getenv)
? ? ? ?(map (fn [[k v]] [(env->path k)
? ? ? ? ? ? ? ? ? ? ? ? ?(str->value v opts)]))
? ? ? ?(into {}))))
從獲取的過程看,應(yīng)該是會把_
做為單元節(jié)點(diǎn)斷開,因此需要改成這樣
java -jar -Ddatabase-url="mysql://localhost:3306/pdb?user=root&password=root" ?-Dapp_key="123" -Dapp_secret="xxx" ?demo.jar
對應(yīng)到edn里應(yīng)該是
{:app ? ?{:key "123"
? ? :secret "xxx"}}
如果仔細(xì)看看cprop這個庫就不難理解了。
cprop加載配置文件的順序是 :
By default cprop will merge all configurations it can find in the following order:
classpath resource config
file on a file system (pointed by a conf system property or by (load-config :file <path>))
custom configurations, maps from various sources, etc.
System properties
ENV variables
對于ENV的加載也有明確說明
ENV variables lack structure. The only way to mimic the structure is via use of an underscore character. The _ is converted to - by cprop, so instead, to identify nesting, two underscores can be used.
了解更多詳情,請閱讀cprop介紹
我的期望
像上面的命令如果有20個參數(shù)需要在啟東時指定,估計(jì)看那個命令就瘋了,那能不能在啟東時指定一個配置文件,比如prod-config.edn之類的呢?我沒有找到,如果有就更方便了。
參考
cprop
作者:小馬將過河
鏈接:https://www.jianshu.com/p/fed7a174bfb8
來源:簡書
著作權(quán)歸作者所有。商業(yè)轉(zhuǎn)載請聯(lián)系作者獲得授權(quán),非商業(yè)轉(zhuǎn)載請注明出處。