Zabbix は Java プロセスのメモリ使用量を監視します

 要件: クラスタ内のすべての Java プロセスのメモリ使用量を監視します。

Linux システムで実行されている Java プロセスを確認します: jps コマンド

[root@localhost zabbix]# jps
26490 YarnTaskExecutorRunner
12012 NodeManager
14047 YarnTaskExecutorRunner
25007 Jps

java プロセスのメモリ使用量を表示します: jstat コマンド -gc -gcutil

[root@node035 zabbix]# jstat -gc 12012
 S0C    S1C    S0U    S1U      EC       EU        OC         OU       MC     MU    CCSC   CCSU   YGC     YGCT    FGC    FGCT     GCT   
2560.0 2560.0  0.0   2208.0 335872.0 180374.6  338432.0   57522.0   51624.0 50525.8 5808.0 5542.1 104079  881.980   3      0.384  882.364
[root@node035 zabbix]# jstat -gcutil 12012
  S0     S1     E      O      M     CCS    YGC     YGCT    FGC    FGCT     GCT   
  0.00  86.25  89.43  17.00  97.87  95.42 104079  881.980     3    0.384  882.364

 #################################################### #################### 

データ スクリプトを収集します。

        ここでは、grep コマンドを使用して、監視するすべての Java プロセスを除外することをお勧めします。grep -v 除外メソッドは使用しないでください。

        jps、jstat、jmap、その他のコマンドなど、一部のプロセスは jps コマンドを使用するよりも速く生成から破棄に移行する可能性があるため、jps | grep を使用してプロセス pid 番号を 1 つだけ取得できますが、プロセス名やその他のプロセス ID 番号は取得できません。情報。

        スクリプトが時々フリーズし、データ取得に一連の問題が発生します。

        親プロセスと子プロセスなど、同じプロセス名のプロセスが複数存在する可能性がある場合。

        ここでのスクリプトは、kafka、kafka1、kafka2 など、同じプロセス名をマークする方法を使用しています。

        zabbixは自動発見方式でプロセス名を取得するため、プロセス名+pidの方法で取得しようとしたのですが、pidが変わってしまいます。

        そのため、現在、同じプロセス名を持つ 2 つのメソッドを分離する良い方法はありません。

        ただし、監視の意義は、監視項目の傾向の変化を観察することです. プロセスの異常なメモリ ステータスが表示された場合は、スクリプトのデータ ファイルに移動して、プロセス名に応じて pid を取得します。

[root@node031 monitor]# cat getJavaMemoryStatus.sh
#!/bin/bash
# Final output
output=""

# Variables
flag=1
last_name=""
currnet_name=""	

# JPS Command
result=`/usr/local/jdk/bin/jps | egrep  "QuorumPeerMain|Kafka|CanalAdminApplication|CanalLauncher|JournalNode|DFSZKFailoverController|NameNode|DataNode|ResourceManager|NodeManager|YarnJobClusterEntrypoint|YarnTaskExecutorRunner|HMaster|HRegion" | sort -k2 -k1`

# Main Loop
#echo "$result" | while read -r pid name ; do
while read -r pid name ; do
    #echo "${pid},${name},${last_name}"

	# Add num to same process name, for example: Process1, Process2 ...
	if [ x"$name" = x"$last_name" ]; then
		currnet_name="$name$flag"
		flag=$(( $flag + 1 ))	
	else
	    currnet_name="$name"	
		flag=1
	fi
	last_name="$name"

	# Get GC Status
	res_gc=`/usr/local/jdk/bin/jstat -gc $pid 2>/dev/null | awk 'NR==2{print $1, $2, $3, $4, $5, $6, $7, $8}'`
	res_gcutil=`/usr/local/jdk/bin/jstat -gcutil $pid 2>/dev/null | awk 'NR==2{print $1, $2, $3, $4, $7, $8, $9, $10}'`

	# Combime output
	if [ x"$output" = x"" ]; then 
		output="${currnet_name} $pid ${res_gc} ${res_gcutil}"
	else
		output+=$'\n'"${currnet_name} $pid ${res_gc} ${res_gcutil}"
	fi
	#echo "$output"

done <<< "$result"

# Output
echo "$output" > /tmp/java_memory_status.txt

スクリプトの最適化:

        サーバーの負荷を軽減するために、データ コマンドをできるだけ 1 回だけ実行する

        IO を減らすために、データを取得するときにファイルを読み取らないようにしてください

自動検出スクリプトを処理します。

[root@localhost parameter_script]# cat java_discovery.sh 
#!/bin/bash
javaProcessList=`cat /tmp/java_memory_status.txt|awk '{print $2"#"$1}'`
echo "{\"data\":["
first=1
for javaProcess in $javaProcessList;
do
    IFS='#' read -r -a items <<< "$javaProcess";
    if [ $first == 1 ]; then
        echo "{\"{#JAVAPSNAME}\":\"${items[1]}\",\"{#JAVAPSPID}\":\"${items[0]}\"}";
        first=0
    else
        echo ",{\"{#JAVAPSNAME}\":\"${items[1]}\",\"{#JAVAPSPID}\":\"${items[0]}\"}";
    fi
done;

echo "]}";

#################################################### #################### 

Java プロセス メモリ データ スクリプトを取得します。

[root@node031 parameter_script]# cat getjavastatus.sh 
#!/bin/bash
pid=`cat /tmp/java_memory_status.txt | awk '{print $2}'`
case $2 in
# S0总大小
S0C)
	grep -w $1 /tmp/java_memory_status.txt |awk '{print $3}'|bc
	;;
# S1总大小
S1C)
	grep -w $1 /tmp/java_memory_status.txt |awk '{print $4}'|bc
	;;
# S0使用大小
S0U)
	grep -w $1 /tmp/java_memory_status.txt |awk '{print $5}'|bc
	;;
# S1使用大小
S1U)
	grep -w $1 /tmp/java_memory_status.txt |awk '{print $6}'|bc
	;;
# Eden总大小
EC)
	grep -w $1 /tmp/java_memory_status.txt |awk '{print $7}'|bc
	;;
# Eden使用大小
EU)
	grep -w $1 /tmp/java_memory_status.txt |awk '{print $8}'|bc
	;;
#old大小
OC)
	grep -w $1 /tmp/java_memory_status.txt |awk '{print $9}'|bc
	;;
#old使用大小
OU)
	grep -w $1 /tmp/java_memory_status.txt |awk '{print $10}'|bc
	;;
# S0使用率
S0Util)
	grep -w $1 /tmp/java_memory_status.txt |awk '{print $11}'|bc
	;;
# S1使用率
S1Util)
	grep -w $1 /tmp/java_memory_status.txt |awk '{print $12}'|bc
	;;
# Eden使用率
EUtil)
	grep -w $1 /tmp/java_memory_status.txt |awk '{print $13}'|bc
	;;
#old使用率
OUtil)
	grep -w $1 /tmp/java_memory_status.txt |awk '{print $14}'|bc
	;;
# 年轻代垃圾回收次数
YGC)
	grep -w $1 /tmp/java_memory_status.txt |awk '{print $15}'|bc
	;;
# 年轻代垃圾回收消耗时间
YGCT)
	grep -w $1 /tmp/java_memory_status.txt |awk '{print $16}'|bc
	;;
# 老年代垃圾回收次数
FGC)
	grep -w $1 /tmp/java_memory_status.txt |awk '{print $17}'|bc
	;;
# 老年代垃圾回收消耗时间
FGCT)
	grep -w $1 /tmp/java_memory_status.txt |awk '{print $18}'|bc
	;;
esac	

設定ファイルの追加と監視項目のカスタマイズ

UserParameter=javaps,/etc/zabbix/parameter_script/java_discovery.sh
UserParameter=javastat[*],/etc/zabbix/parameter_script/getjavastatus.sh $1 $2

zabbix-agent2 プロセスを再起動します

service zabbix-agent2 restart

スケジュールされたタスクを構成する

*/1 * * * * sh /data/script/monitor/getJavaMemoryStatus.sh

Java プロセスの自動検出を構成する

テンプレート グループを作成します: JavaProcess

 テンプレート JavaProcess を作成する

JavaProcess テンプレートで自動検出ルールを作成する

 

 監視する監視項目のプロトタイプを追加

 監視対象ホストに JavaProcess テンプレートを追加する

 

Zabbix は、検出されたプロセスを対応するホストに自動的に追加し、監視項目のプロトタイプに従って、対応する監視項目を作成します. データを収集した後、Grafana はグラフを生成します.

おすすめ

転載: blog.csdn.net/qq_48391148/article/details/129716562