java-jar jar包帶環境變量(參數)啓動

需求

java工程我們可以編譯成jar也可以翻譯成war,一般地,war包我會丟到tomcat容器裏,啓動tomcat來訪問服務,端口、SSL證書、日誌等等,都託給tomcat。

如果打的是jar包,我通常會用nohup啓動,比如生產環境的一些db、redis、第三方secret等不會配置到項目裏,今天要記錄的便是用nohup java -jar 啓動jar包時如何加載環境變量配置的問題。

java語言開發的jar包啓動時可以按照如下方式加啓動參數。

方式一:-DpropName=propValue

這種方式應該很快都能找到

-DpropName=propValue

比如:

java -jar -DdatabaseUrl="mysql://localhost:3306/pdb?user=root&password=root"  -Dapp.key="123" -Dapp.secret="xxx"  demo.jar

多個參數也可以。

方式二:參數直接跟在命令後面,多個參數之間用空格隔開

java -jar demo.jar JOURNAL_TREENODE_DATA-20190404174502.txt processType=1

這種方式參數就是jar包裏主啓動類中main方法的args參數,按順序來

方式三:使用springboot的方式,--propName=propValue方式

java -jar demo.jar  --spring.profiles.active=dev  --server.port=8181

注意:
運行jar包時指定端口:java -jar xxx.jar --server.port=8088
若命令行傳入的server.port沒有作用,服務仍然使用8081端口啓動,原因是spring-cloud-config會覆蓋命令行傳入的參數,這是有意爲之,

辦法是在web-prod.yml中做點小改動,讓“配置”變得“可配置”:加一對花括符

server.port={port:8081}

用clojure開發的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的端口連接上你的服務,你會發現,這個配置導致database-url的值確實已經改了,但是後面兩個沒有。

究其原因,我們java從classpath裏獲取參數使用的是properties形式的,也就是json的格式。這不難理解,spring有它的辦法,clojure當然也有自己的方式。

"app": {
    "key": "123",
    "secret":"xxx"
}

雖然json和我們的edn裏map是很像的,但是畢竟是不同,於是要分析下現在的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 {}))))

從獲取的過程看,應該是會把_做爲單元節點斷開,因此需要改成這樣

java -jar -Ddatabase-url="mysql://localhost:3306/pdb?user=root&password=root"  -Dapp_key="123" -Dapp_secret="xxx"  demo.jar

對應到edn裏應該是

{:app
    {:key "123"
     :secret "xxx"}}

如果仔細看看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個參數需要在啓東時指定,估計看那個命令就瘋了,那能不能在啓東時指定一個配置文件,比如prod-config.edn之類的呢?我沒有找到,如果有就更方便了。

參考

cprop



作者:小馬將過河
鏈接:https://www.jianshu.com/p/fed7a174bfb8
來源:簡書
著作權歸作者所有。商業轉載請聯繫作者獲得授權,非商業轉載請註明出處。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章