溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

java啟動參數(shù)如何排查

發(fā)布時間:2022-06-08 09:29:59 來源:億速云 閱讀:239 作者:zzz 欄目:開發(fā)技術(shù)

這篇文章主要講解了“java啟動參數(shù)如何排查”,文中的講解內(nèi)容簡單清晰,易于學(xué)習(xí)與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學(xué)習(xí)“java啟動參數(shù)如何排查”吧!

排查過程

我們的應(yīng)用是java應(yīng)用,jdk版本是Open-jdk8,阿里云agent是直接注入到容器中的,因此會將agent啟動參數(shù)自動注入到 JAVA_TOOL_OPTIONS 環(huán)境變量中,當(dāng)應(yīng)用啟動時會自動帶上agent啟動參數(shù)。

agent沒注冊,首先檢查應(yīng)用的啟動日志,發(fā)現(xiàn)應(yīng)用是啟動成功的,tomcat端口都是正常的。仔細(xì)觀察日志,發(fā)現(xiàn)了問題。由于agent 啟動參數(shù)是注入到 JAVA_TOOL_OPTIONS 中的,通常jvm 在啟動的時候會優(yōu)先加載 JAVA_TOOL_OPTIONS,日志中會出現(xiàn) Picked up JAVA_TOOL_OPTIONS 的字樣,如下圖所示,但是問題現(xiàn)場卻沒有這一行和agent相關(guān)的啟動日志,說明 jvm 啟動的時候并沒有加載 JAVA_TOOL_OPTIONS。

java啟動參數(shù)如何排查

我們開始懷疑是 agent啟動參數(shù) 的問題,以為是agent在容器重建時沒有將啟動參數(shù)注入到環(huán)境變量中。但是通過環(huán)境變量一看,發(fā)現(xiàn) JAVA_TOOL_OPTIONS 是在的,而且每個agent的參數(shù)都是齊全的。

java啟動參數(shù)如何排查

這個時候就開始懷疑是不是啟動腳本的問題,是不是有人在啟動腳本中加了unset JAVA_TOOL_OPTIONS,因?yàn)楫?dāng)存在JAVA_TOOL_OPTIONS時,使用jdk相關(guān)的命令都會帶上JAVA_TOOL_OPTIONS中的參數(shù),造成一定的困擾,所以有時候在排查問題的時候會先unset掉這個變量,但是檢查完腳本也沒有問題。

最后開始咨詢阿里云的工程師,懷疑是不是agent或者容器環(huán)境有問題。經(jīng)過反復(fù)比較正常容器和問題容器的JAVA_TOOL_OPTIONS啟動參數(shù),發(fā)現(xiàn)問題容器因?yàn)槎嗉虞d一個agent,JAVA_TOOL_OPTIONS多出來一段參數(shù),去掉這段參數(shù)就能恢復(fù)正常,加上就會有問題。到這里,可能正常的思路都是懷疑是多出來的參數(shù)造成的。但在排查其他正常容器時發(fā)現(xiàn),有的容器即使有這一段參數(shù)也能正常啟動。

這個時候,阿里云的工程師懷疑是不是參數(shù)太長導(dǎo)致的,因?yàn)橛袉栴}的容器的應(yīng)用名字比較長,于是我們開始測試,發(fā)現(xiàn)確實(shí)是這個問題,如下圖所示。隨后確定了問題所在,jdk8 在加載默認(rèn)環(huán)境變量時會檢查長度,當(dāng)大于1024字節(jié)時就會加載失敗。

java啟動參數(shù)如何排查

環(huán)境變量

在jdk相關(guān)的環(huán)境變量中,有兩種默認(rèn)的環(huán)境變量 JAVA_TOOL_OPTIONS_JAVA_OPTIONS。

JAVA_TOOL_OPTIONS:在jdk8及之前版本中,該變量是最標(biāo)準(zhǔn)的,所有虛擬機(jī)都能識別和應(yīng)用的環(huán)境變量,在jdk9之后被JDK_JAVA_OPTIONS所取代。該變量限制1024字節(jié),在不同虛擬機(jī)中表現(xiàn)不一樣,有的是加載失敗,有的是截取一段。

_JAVA_OPTIONS:也是默認(rèn)的環(huán)境變量,但是它是JVM廠家自定義的,可以覆蓋JAVA_TOOL_OPTIONS,但各廠家的命名不同,_JAVA_OPTIONS是Oracle的JVM,而IBM的則是用IBM_JAVA_OPTIONS。

因此為避免出現(xiàn)問題,我們應(yīng)該盡量避免使用默認(rèn)的環(huán)境變量,通常情況下可以在腳本中自定義啟動變量如 JAVA_OPTSSPRINGBOOT_OPTS等等。然后在啟動java時顯式的指定啟動參數(shù)。

java [-options] -jar xxx.jar [args…]
可以寫成
JAVA_OPTS="[-options]"
JAVA_ARGS="[args…]"
java ${JAVA_OPTS} -jar xxx.jar ${JAVA_ARGS}

附:啟停腳本

項(xiàng)目打包后在測試環(huán)境的啟停都是個體力活,剛好又給筆者遇到了,綜合別人的腳本記錄了一下

判斷 Java 進(jìn)程是否存在

APP_NAME=xxx.jar
pid=jps -l | grep $APP_NAME

if [ -z $pid ]; then
 	echo "$APP_NAME started"
 else
 	echo "$APP_NAME stoped"
 fi
 
# 普通進(jìn)程的
# pid=ps -ef | grep $APP_NAME | grep -v grep | awk '{print $2}'

啟停腳本

APP_NAME=xxxx-1.0-SNAPSHOT.jar

pid=0
checkpid() {
    javaps=`jps -l | grep $APP_NAME`
    if [ -n "$javaps" ]; then
    	pid=`echo $javaps | awk '{print $1}'`
    else
    	pid=0
}

start() {
    checkpid
    if [ $psid -ne 0 ]; then
    	echo "$APP_NAME already started"
    else
    	echo "Starting $APP_NAME ..."
    	`nohup java -jar $APP_NAME > $APP_NAME'.out' 2>&1 &`
    	checkpid
    	if [ $pid -ne 0]; then
    		echo "$APP_NAME start success"
    	else
    		echo "$APP_NAME start faild"
    	fi
    fi
}

stop() {
    checkpid
    if [ $pid -ne 0 ]; then
    	echo "Stoping $APP_NAME..."
        kill -9 $pid
        if [$? -eq 0 ]; then
        	echo "$APP_NAME stop success"
        else
        	echo "$APP_NAME stop faild"
       	fi
    else
    	echo "$APP_NAME already stoped"
   	fi
}


case "$1" in
 'start')
 start
 ;;
 'stop')
 stop
 ;;
 'restart')
 stop
 start
 ;;
 *)	# 其他任何情況
 
echo "help: $0 {start|stop|restart}"
echo "例子: ./deploy start
exit 1
esac
exit 0

感謝各位的閱讀,以上就是“java啟動參數(shù)如何排查”的內(nèi)容了,經(jīng)過本文的學(xué)習(xí)后,相信大家對java啟動參數(shù)如何排查這一問題有了更深刻的體會,具體使用情況還需要大家實(shí)踐驗(yàn)證。這里是億速云,小編將為大家推送更多相關(guān)知識點(diǎn)的文章,歡迎關(guān)注!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI