* CCSMX最大压缩类空间尺寸

好了,上面正是自身找到的有的对jstat获取的数额意思的总结,各位看官能够做个参谋。
好了,这一章的剧情到此基本竣事,前边的东西都以一些理论类的事物,未有实际的操作。俗话说,光说不练假把式。接下来,大家将开启下一章的旅程,脚本+jstat的施用。
其三章:脚本+jstat获取数据
率先,大家来看一下该章节介绍的多少个脚本吧:
1.jvm_list.sh
获取该机器上具有运维的JVM的进程对应的次第根目录以及程序名称
2.get_jvmlist.sh
将获取的该机器上的装有进度对应的主次名称连串化成json格式并发送给zabbix服务器
3.get_jvmstatus.sh
通过获取的顺序根目录获取到对应的顺序进度,再通过jstat抓取多少写入到文件中缓存
4.set_jvmstatus.sh
zabbix通过调用该脚本获取缓存文件中的关于某些JVM进程的情景音信
好了,简要介绍了上面多少个剧本的出力,上边我们列出那多少个本子的实在内容:
    #cat jvm_list.sh 
    #!/bin/bash
     
    packagePath=/usr/local/etc/scripts/package_path.txt
    echo -n >$packagePath
     
    for i in `ps -fC java|tail -n +2|grep -v ‘flume’|awk ‘{print
$2}’`;
    do
            pgrootpath=`ls -l /proc/$i/cwd|awk ‘{print $NF}’`
            if [[ -r $pgrootpath/appconfig ]] && [  `grep
^packagename= $pgrootpath/appconfig|wc -l`==1 ];then
                            packagename=$(grep ^packagename=
$pgrootpath/appconfig 2>/dev/null|awk -F'”‘ ‘{print $2}’)
            elif [[ -r $pgrootpath/webconfig ]] && [  `grep
^packagename= $pgrootpath/webconfig|wc -l`==1 ];then
                            packagename=$(grep ^packagename=
$pgrootpath/webconfig 2>/dev/null|awk -F'”‘ ‘{print $2}’)
            else
                    packagename=$(basename
$pgrootpath)-1.0.0-bin.tar.gz
            fi
     
            echo “$packagename $pgrootpath” >> $packagePath
    done

该脚本的目标是先经过行使ps -fC
java命令获取该机器上面除了flume进度外的持有别的java进度(笔者那边使用的是flume来访谈职业日志的。)
接下来,通过获取到的PID使用ll
/proc/pid/cwd命令获取该进度的顺序根目录,后边那么些决断是赢得该进程对应的包名(这一步各位能够依据自个儿公司的意况自行修改,作者那边取包名的措施并不可以同盟各位公司的装置,在下力不能够支了。)
末尾是将收获到的主次根目录和包名贮存在变量package帕特h对应的文件中。
    #cat get_jvmlist.sh 
    #!/bin/bash
     
    TABLESPACE=`awk ‘{print $1}’
/usr/local/etc/scripts/package_path.txt`
    COUNT=`echo “$TABLESPACE” |wc -l`
    INDEX=0
    echo ‘{“data”:[‘
    echo “$TABLESPACE” | while read LINE; do
        echo -n ‘{“{#TABLENAME}”:”‘$LINE'”}’
        INDEX=`expr $INDEX + 1`
        if [ $INDEX -lt $COUNT ]; then
            echo ‘,’
        fi
    done
    echo ‘]}’

本条剧本的职能便是通过读取文件之中的包名,然后将包名进行json种类化输出,没什么好讲的,套路套三个循环脚本就行。
接下去正是首要的脚本了,调用jstat获取JVM状态,并缓存到文件中。
#cat get_jvmstatus.sh 
    #!/bin/bash
     
    MAINCLASS=”*Main.class”
    scriptPath=/usr/local/etc/scripts
     
    cat $scriptPath/package_path.txt|while read line
    do
    packageName=$(echo $line|awk ‘{print $1}’)
    pgRootPath=$(echo $line|awk ‘{print $2}’)
    if [[ -d $pgRootPath/tomcat ]];then
    pid=$(cat $pgRootPath/tomcat/tomcat.pid)
    else
    mainPath=$(find $pgRootPath -name $MAINCLASS)
    appName=$(echo ${mainPath##*classes/}|sed ‘s#/#.#g’|sed
‘s#.class##g’)
    pid=$(ps -fC java|grep “$appName”|awk ‘{print $2}’)
    fi
    javaHome=/usr/local/java/jdk1.8.0
    #javaHome=/usr/local/java/latest
    #if [[ -r $pgRootPath/appconfig ]] && [  `grep ^JAVA_HOME=
$pgRootPath/appconfig|wc -l` == 1 ] && [ `grep ^JAVA_HOME=
$pgRootPath/appconfig|grep 8|wc -l` == 1 ];then
                            #javaHome=$(grep ^JAVA_HOME=
$pgRootPath/appconfig 2>/dev/null|awk -F’=’ ‘{print $2}’)
    #javaHome=/usr/local/java/jdk1.8.0
            #else
            #        if [[ -r $pgRootPath/webconfig ]] && [ `grep
^’export JAVA_HOME=’ $pgRootPath/webconfig|wc -l` == 1 ] && [ `grep
^’export JAVA_HOME=’ $pgRootPath/webconfig|grep 8|wc -l` == 1
];then
            #                #javaHome=$(grep ^’export JAVA_HOME=’
$pgRootPath/webconfig 2>/dev/null|awk -F'”‘ ‘{print $2}’)
            #        javaHome=/usr/local/java/jdk1.8.0
    #fi
    #fi
    #echo ——————————–$pgRootPath
    #echo $javaHome
    echo ——————————-$pid
    sleep 5
    #echo -n >$scriptPath/package/$packageName
    #$javaHome/bin/jstat -gccapacity $pid > ./package/$packageName
2>/dev/null
    #$javaHome/bin/jmap -heap $pid>>./package/$packageName
2>/dev/null
    echo gcnew >> $scriptPath/package/$packageName
2>/dev/null
    $javaHome/bin/jstat -gcnew $pid >>
$scriptPath/package/$packageName 2>/dev/null
    echo gcutil >> $scriptPath/package/$packageName
2>/dev/null
    $javaHome/bin/jstat -gcutil $pid >>
$scriptPath/package/$packageName 2>/dev/null
    echo gcnewcapacity >> $scriptPath/package/$packageName
2>/dev/null
    $javaHome/bin/jstat -gcnewcapacity $pid >>
$scriptPath/package/$packageName 2>/dev/null
            echo gccapacity >> $scriptPath/package/$packageName
2>/dev/null
    $javaHome/bin/jstat -gccapacity $pid >>
$scriptPath/package/$packageName 2>/dev/null
            #echo gcold >> $scriptPath/package/$packageName
2>/dev/null
    #$javaHome/bin/jstat -gcold $pid >>
$scriptPath/package/$packageName 2>/dev/null
            echo gc >> $scriptPath/package/$packageName
2>/dev/null
    $javaHome/bin/jstat -gc $pid >>
$scriptPath/package/$packageName 2>/dev/null
            echo class >> $scriptPath/package/$packageName
2>/dev/null
    $javaHome/bin/jstat -class $pid >>
$scriptPath/package/$packageName 2>/dev/null
    echo cpu >> $scriptPath/package/$packageName 2>/dev/null
    echo -e “CPU\n$( ps aux|grep $pid|grep -v grep|awk ‘{print $3}’)”
>> $scriptPath/package/$packageName 2>/dev/null
    echo mem >> $scriptPath/package/$packageName 2>/dev/null
    echo -e “MEM\n$( ps aux|grep $pid|grep -v grep|awk ‘{print $6}’)”
>> $scriptPath/package/$packageName 2>/dev/null
     
    done

那当中首先是经过获得到程序的根目录,然后本身那的java程序除了tomcat跑的之外,别的的java程序都以由此Main.class运转的,所以能够赢获得AppName,那样经过ps命令就会找到其对应的PID了,而只假使tomcat运行的历程来讲,在程序根目录上面包车型地铁tomcat目录下有三个tomcat.pid文件之中有该程序的PID。后边被讲明的那一边代码其实以前是丰盛去的,那段代码的功能是判断该进程使用的是JDK7照旧JDK8运维的,当初的安插是想着即使是JDK7运营的历程就用JDK7的jstat去获取数据,假设是JDK8运转的进程就用JDK8的jstat去获取数据,后来开掘不一样版本的JDK获取的多少格式分歧,于是。。。。。。后悔莫及的把这段代码注释掉了。前面综合商社真实情形思量,JDK8的主次用得比相当多,JDK7的主次相对来讲比非常少,而且稳步都会向JDK8进行改造,所以,权衡利弊之下,之后将jstat的JDK全部换到了JDK8,那样的震慑便是得到不到JDK7的万北周数据。当然,各位有意思味的话,也得以JDK7和JDK8同不日常候选拔,在过滤输出文件的时候加三个声明位实行决断,当然,笔者这里暂风尚未做那上面包车型地铁退换。。。毕竟时间有限。。。
第八个剧本,个人感到写的最烂的三个剧本。。。但是。。。无法,才具水平有限,各位将就着看吗(捂脸哭)
# cat set_jvmstatus.sh 
    #!/bin/bash
    packageName=$1
    key=$2
     
    if [ $2 == “S0C” -o $2 == “S0U” -o $2 == “S1C” -o $2 == “S1U” -o $2
== “DSS” -o $2 == “EC” -o $2 == “EU” ];then
    part=gcnew
    elif [ $2 == “S0” -o $2 == “S1” -o $2 == “E” -o $2 == “O” -o $2 ==
“M” -o $2 == “CCS” -o $2 == “YGCT” -o $2 == “FGCT” -o $2 == “GCT”
];then
    part=gcutil
    elif [ $2 == “S0CMX” -o $2 == “S1CMX” -o $2 == “ECMX” ];then
    part=gcnewcapacity
    elif [ $2 == “NGCMN” -o $2 == “NGCMX” -o $2 == “NGC” -o $2 ==
“OGCMX” -o $2 == “OGCMN” -o $2 == “OGC” -o $2 == “MCMN” -o $2 == “MCMX”
-o $2 == “MC” -o $2 == “CCSMN” -o $2 == “CCSMX” -o $2 == “CCSC” -o $2 ==
“YGC” -o $2 == “FGC” ];then
    part=gccapacity
    elif [ $2 == “MU” -o $2 == “CCSU” -o $2 == “OC” -o $2 == “OU”
];then
    part=gc
    elif [ $2 == “Loaded” -o $2 == “Unloaded” ];then
    part=class
    elif [ $2 == “CPU” ];then
    part=cpu
    elif [ $2 == “MEM” ];then
            part=mem
    else
    echo “Error input:”
    exit 0
    fi
    case $2 in
    S0C)
    grep -wA 2 ^”$part” /usr/local/etc/scripts/package/$1|tail -1|awk
‘{printf “%d\n”, $1*1024}’
    ;;
    S0U)
    grep -wA 2 ^”$part” /usr/local/etc/scripts/package/$1|tail -1|awk
‘{printf “%d\n”, $3*1024}’
    ;;
    S0)
    grep -wA 2 ^”$part” /usr/local/etc/scripts/package/$1|tail -1|awk
‘{printf “%f\n”, $0}’
    ;;
    S0CMX)
    grep -wA 2 ^”$part” /usr/local/etc/scripts/package/$1|tail -1|awk
‘{printf “%d\n”, $4*1024}’
    ;;
    S1C)
    grep -wA 2 ^”$part” /usr/local/etc/scripts/package/$1|tail -1|awk
‘{printf “%d\n”, $2*1024}’
    ;;
    S1U)
    grep -wA 2 ^”$part” /usr/local/etc/scripts/package/$1|tail -1|awk
‘{printf “%d\n”, $4*1024}’
    ;;
    S1)
    grep -wA 2 ^”$part” /usr/local/etc/scripts/package/$1|tail -1|awk
‘{printf “%f\n”, $2}’
    ;;
    S1CMX)
    grep -wA 2 ^”$part” /usr/local/etc/scripts/package/$1|tail -1|awk
‘{printf “%d\n”, $6*1024}’
    ;;
    DSS)
    grep -wA 2 ^”$part” /usr/local/etc/scripts/package/$1|tail -1|awk
‘{printf “%d\n”, $7*1024}’
    ;;
    EC)
    grep -wA 2 ^”$part” /usr/local/etc/scripts/package/$1|tail -1|awk
‘{printf “%d\n”, $8*1024}’
    ;;
    EU)
    grep -wA 2 ^”$part” /usr/local/etc/scripts/package/$1|tail -1|awk
‘{printf “%d\n”, $9*1024}’
    ;;
    ECMX)
    grep -wA 2 ^”$part” /usr/local/etc/scripts/package/$1|tail -1|awk
‘{printf “%d\n”, $8*1024}’
    ;;
    E)
    grep -wA 2 ^”$part” /usr/local/etc/scripts/package/$1|tail -1|awk
‘{printf “%f\n”, $3}’
    ;;
    NGCMN)
    grep -wA 2 ^”$part” /usr/local/etc/scripts/package/$1|tail -1|awk
‘{printf “%d\n”, $1*1024}’
    ;;
    NGCMX)
    grep -wA 2 ^”$part” /usr/local/etc/scripts/package/$1|tail -1|awk
‘{printf “%d\n”, $2*1024}’
    ;;
    NGC)
    grep -wA 2 ^”$part” /usr/local/etc/scripts/package/$1|tail -1|awk
‘{printf “%d\n”, $3*1024}’
    ;;
    OC)
    grep -wA 2 ^”$part” /usr/local/etc/scripts/package/$1|tail -1|awk
‘{printf “%d\n”, $7*1024}’
    ;;
    OU)
    grep -wA 2 ^”$part” /usr/local/etc/scripts/package/$1|tail -1|awk
‘{printf “%d\n”, $8*1024}’
    ;;
    OGCMX)
    grep -wA 2 ^”$part” /usr/local/etc/scripts/package/$1|tail -1|awk
‘{printf “%d\n”, $8*1024}’
    ;;
    OGCMN)
    grep -wA 2 ^”$part” /usr/local/etc/scripts/package/$1|tail -1|awk
‘{printf “%d\n”, $7*1024}’
    ;;
    O)
    grep -wA 2 ^”$part” /usr/local/etc/scripts/package/$1|tail -1|awk
‘{printf “%f\n”, $4}’
    ;;
    OGC)
    grep -wA 2 ^”$part” /usr/local/etc/scripts/package/$1|tail -1|awk
‘{printf “%d\n”, $9*1024}’
    ;;
    M)
    grep -wA 2 ^”$part” /usr/local/etc/scripts/package/$1|tail -1|awk
‘{printf “%f\n”, $5}’
    ;;
    MC)
    grep -wA 2 ^”$part” /usr/local/etc/scripts/package/$1|tail -1|awk
‘{printf “%d\n”, $13*1024}’
威澳门尼斯人36366com,    ;;
    MU)
    grep -wA 2 ^”$part” /usr/local/etc/scripts/package/$1|tail -1|awk
‘{printf “%d\n”, $10*1024}’
    ;;
    MCMN)
    grep -wA 2 ^”$part” /usr/local/etc/scripts/package/$1|tail -1|awk
‘{printf “%d\n”, $11*1024}’
    ;;
    MCMX)
    grep -wA 2 ^”$part” /usr/local/etc/scripts/package/$1|tail -1|awk
‘{printf “%d\n”, $12*1024}’
    ;;
    CCS)
    grep -wA 2 ^”$part” /usr/local/etc/scripts/package/$1|tail -1|awk
‘{printf “%f\n”, $6}’
    ;;
    CCSC)
    grep -wA 2 ^”$part” /usr/local/etc/scripts/package/$1|tail -1|awk
‘{printf “%d\n”, $13*1024}’
    ;;
    CCSU)
    grep -wA 2 ^”$part” /usr/local/etc/scripts/package/$1|tail -1|awk
‘{printf “%d\n”, $12*1024}’
    ;;
    CCSMN)
    grep -wA 2 ^”$part” /usr/local/etc/scripts/package/$1|tail -1|awk
‘{printf “%d\n”, $14*1024}’
    ;;
    CCSMX)
    grep -wA 2 ^”$part” /usr/local/etc/scripts/package/$1|tail -1|awk
‘{printf “%d\n”, $15*1024}’
    ;;
    YGC)
    grep -wA 2 ^”$part” /usr/local/etc/scripts/package/$1|tail -1|awk
‘{printf “%d\n”, $17}’
    ;;
    YGCT)
    grep -wA 2 ^”$part” /usr/local/etc/scripts/package/$1|tail -1|awk
‘{printf “%f\n”, $8}’
    ;;
    FGC)
    grep -wA 2 ^”$part” /usr/local/etc/scripts/package/$1|tail -1|awk
‘{printf “%d\n”, $18}’
    ;;
    FGCT)
    grep -wA 2 ^”$part” /usr/local/etc/scripts/package/$1|tail -1|awk
‘{printf “%f\n”, $10}’
    ;;
    GCT)
    grep -wA 2 ^”$part” /usr/local/etc/scripts/package/$1|tail -1|awk
‘{printf “%f\n”, $11}’
    ;;
    TT)
    grep -wA 2 ^”$part” /usr/local/etc/scripts/package/$1|tail -1|awk
‘{printf “%d\n”, $5}’
    ;;
    MTT)
    grep -wA 2 ^”$part” /usr/local/etc/scripts/package/$1|tail -1|awk
‘{printf “%d\n”, $6}’
    ;;
    Loaded)
    grep -wA 2 ^”$part” /usr/local/etc/scripts/package/$1|tail -1|awk
‘{printf “%d\n”, $1}’
    ;;
    Unloaded)
    grep -wA 2 ^”$part” /usr/local/etc/scripts/package/$1|tail -1|awk
‘{printf “%d\n”, $3}’
    ;;
    CPU)
    grep -wA 2 ^”$part” /usr/local/etc/scripts/package/$1|tail -1|awk
‘{printf “%f\n”, $1}’
    ;;
    MEM)
    grep -wA 2 ^”$part” /usr/local/etc/scripts/package/$1|tail -1|awk
‘{printf “%d\n”, $1*1024}’
    ;;
    *)
    echo “Error input:”
    ;;
    esac
    exit 0

那套脚本没什么讲的,正是重新的拓展部分剖断,抓数据并出口(注意,在此之前写的得到的jstat参数的值其实是不可信赖的,获取的值是以KB为单位而不是以字节为单位,所以笔者取完数据后对数码实行成字节为单位了。)
接下去,讲一下那多少个脚本该怎么布局。小编那边的zabbix_agentd是透过yum安装的,所以安装在/usr/local目录下,配置文件在/usr/local/etc目录下,须要在zabbix_agentd.conf里面增多上边两行获取数据的key(注意,增加好后一定要记得重启zabbix_agentd进程):
UserParameter=jmx.discovery,/usr/local/etc/scripts/get_jvmlist.sh
UserParameter=jmx.resource[*],/usr/local/etc/scripts/set_jvmstatus.sh
$1 $2

然后脚本都停放在/usr/local/etc/scripts/目录下,该目录下的本子权限如下:
 -rwxr-xr-x 1 zabbix zabbix  326 3月  26 22:29 get_jvmlist.sh
 -rwxr-xr-x 1 root  root  2956 3月  28 20:57 get_jvmstatus.sh
 -rwxr-xr-x 1 root  root    818 3月  26 22:33 jvm_list.sh
 drwxr-xr-x 2 zabbix zabbix 4096 3月  26 23:05 package
 -rw-r–r– 1 zabbix zabbix 1947 3月  29 11:23 package_path.txt
 -rwxr-xr-x 1 zabbix zabbix 5240 3月  28 20:50 set_jvmstatus.sh

然后须求在crontab里面定义jvm_list.sh和get_jvmstatus.sh脚本的定期任务,我这里定义的如下:
12 * */1 * * * /usr/local/etc/scripts/jvm_list.sh
*/5 * * * * /usr/local/etc/scripts/get_jvmstatus.sh

只顾那多少个本子应当要以root权限去试行,因为在那之中涉及到的有个别下令独有root用户才有权力去施行。
从此能够手动推行脚本去获取数据,看是或不是能够抓取到相应的多寡。
好了,那章的台本讲完了,下一章,正是哪些通过zabbix获取相应的数码了。
第四章:zabbix获取数据

透过事先的本子铺排,可以在zabbix_server下面通过zabbix_get命令去反省是不是收获到了相应的多寡:

    # zabbix_get  -s xx.xx.xx.xx -k
jmx.resource[Abcdefg-1.0.0-rc-bin.tar.gz,MEM]
    641036288
自家那边能够拿走到多少了(注意IP被自个儿注释掉了,为了爱惜隐衷哈,包名也被作者特意修改了,隐秘隐衷哈)
接下去就可以配备模板了,至于模板作者已经做好了,能够间接在附属类小部件里面下载。至于模板作者制作了有的大约的key的值收集,以及图像的来得,至于监察和控制报告警方值的装置,由于各类集团的条件分歧,供给各位自身依据自个儿须要自动设置。

Zabbix模板到Linux公社能源站下载:

——————————————分割线——————————————

免费下载地址在

用户名与密码都以www.linuxidc.com

切切实实下载目录在
/二〇一六年龄资历料/3月/二十二二十七日/Zabbix使用自动开掘功用监察和控制服务器各JVM进度景况/

下载格局见
http://www.linuxidc.com/Linux/2013-07/87684.htm

——————————————分割线——————————————

正文永世更新链接地址:http://www.linuxidc.com/Linux/2016-09/135139.htm

威澳门尼斯人36366com 1

采纳Zabbix动态监控磁盘I/O

多年来在看Linux
I/O子系统有关的素材,需求监察和控制每台服务器的磁盘I/O,特别是MongoDB数据库服务器的磁盘I/O,由于每台服务器的磁盘名称恐怕分裂等,所以要求选取Zabbix的LLD功用来开采磁盘并监察和控制I/O

参照他事他说加以考察小说

1.编纂发掘磁盘的步子

shell版本disk_discovery.sh

 #!/bin/bash

 diskarray=(`cat /proc/diskstats |grep -E
“\bsd[a-z]\b|\bxvd[a-z]\b|\bvd[a-z]\b”|awk ‘{print
$3}’|sort|uniq  2>/dev/null`)

 

 length=${#diskarray[@]}

printf “{\n”

printf  ‘\t'”\”data\”:[“

for ((i=0;i<$length;i++))

do

        printf ‘\n\t\t{‘

        printf “\”{#DISK_NAME}\”:\”${diskarray[$i]}\”}”

        if [ $i -lt $[$length-1] ];then

                printf ‘,’

        fi

done

printf  “\n\t]\n”

printf “}\n”

   

$ sh disk_discovery.sh

{

    “data”:[

        {“{#DISK_NAME}”:”xvda”},

        {“{#DISK_NAME}”:”xvdb”}

    ]

}

Python版本disk_discovery.py

#/usr/bin/python

#This script is used to discovery disk on the server

import subprocess

import json

args=”cat /proc/diskstats |grep -E
‘\ssd[a-z]\s|\sxvd[a-z]\s|\svd[a-z]\s’|awk ‘{print
$3}’|sort|uniq 2>/dev/null”

t=subprocess.Popen(args,shell=True,stdout=subprocess.PIPE).communicate()[0]

 

disks=[]

 

for disk in t.split(‘\n’):

    if len(disk) != 0:

      disks.append({‘{#DISK_NAME}’:disk})

print json.dumps({‘data’:disks},indent=4,separators=(‘,’,’:’))

$ python disk_discovery.py

{

    “data”:[

        {

            “{#DISK_NAME}”:”xvda”

        },

        {

            “{#DISK_NAME}”:”xvdb”

        }

    ]

}

2.编辑获取磁盘I/O信息的台本

采纳iostat搜集磁盘I/O新闻

#/bin/sh

device=$1

item=$2

 

/usr/bin/iostat -dxkt 1 5 > /tmp/iostat_output 2>/dev/null

 

case $item in

        rrqm)

            /usr/bin/tail -n20 /tmp/iostat_output |grep
“\b$device\b”|tail -1|awk ‘{print $2}’

            ;;

        wrqm)

            /usr/bin/tail -n20 /tmp/iostat_output |grep
“\b$device\b”|tail -1|awk ‘{print $3}’

            ;;

          rps)

            /usr/bin/tail -n20 /tmp/iostat_output |grep
“\b$device\b”|tail -1|awk ‘{print $4}’

            ;;

          wps)

            /usr/bin/tail -n20 /tmp/iostat_output |grep “\b$device\b”
|tail -1|awk ‘{print $5}’

            ;;

        rKBps)

            /usr/bin/tail -n20 /tmp/iostat_output |grep “\b$device\b”
|tail -1|awk ‘{print $6}’

            ;;

        wKBps)

            /usr/bin/tail -n20 /tmp/iostat_output |grep “\b$device\b”
|tail -1|awk ‘{print $7}’

            ;;

    avgrq-sz)

            /usr/bin/tail -n20 /tmp/iostat_output |grep “\b$device\b”
|tail -1|awk ‘{print $8}’

            ;;

    avgqu-sz)

            /usr/bin/tail -n20 /tmp/iostat_output |grep “\b$device\b”
|tail -1|awk ‘{print $9}’

            ;;

        await)

            /usr/bin/tail -n20 /tmp/iostat_output |grep “\b$device\b”
|tail -1|awk ‘{print $10}’

            ;;

        svctm)

            /usr/bin/tail -n20 /tmp/iostat_output |grep “\b$device\b”
|tail -1|awk ‘{print $11}’

            ;;

        util)

            /usr/bin/tail -n20 /tmp/iostat_output |grep “\b$device\b”
|tail -1|awk ‘{print $12}’

            ;;

esac

3.修改Zabbix agent配置文件

添加disk_status.conf

Timeout=10

### Option: UserParameter

#      User-defined parameter to monitor. There can be several
user-defined parameters.

#      Format: UserParameter=<key>,<shell command>

#      See ‘zabbix_agentd’ directory for examples.

#

# Mandatory: no

# Default:

# UserParameter=

UserParameter=disk.discovery,/usr/bin/python
/usr/local/zabbix/bin/disk_discovery.py

UserParameter=disk.status[*],/usr/local/zabbix/bin/disk_status.sh $1
$2

这边要求留神,Zabbix agent暗中同意的Timeout值为3秒,由于这里运用iostat
-ydxkt 1
3,每隔1秒刷新二遍,刷新3次,所以只要获得磁盘音信Timeout设置时间短了的话会并发ZBX_NOTSUPPORTED那样的荒谬

接下来再一次加载zabbix agent

4.通过在zabbix server或zabbix proxy端使用zabbix_get获取磁盘新闻

$ /usr/local/zabbix/bin/zabbix_get -s 192.168.1.190 -p 10055 -k
“disk.discovery”

{

    “data”:[

        {

            “{#DISK_NAME}”:”xvda”

        },

        {

            “{#DISK_NAME}”:”xvdb”

        },

        {

            “{#DISK_NAME}”:”xvdc”

        }

    ]

}

$ /usr/local/zabbix/bin/zabbix_get -s 192.168.1.190 -p 10055 -k
“disk.status[xvda,wps]”10.00

局部Zabbix相关课程集结:

设置配备布满式监察和控制种类Zabbix 2.06

《安装配备分布式监察和控制种类Zabbix 2.06》

CentOS 6.3下Zabbix安装配置

Zabbix遍及式监察和控制类别施行

CentOS 6.3下Zabbix监控apache server-status

CentOS 6.3下Zabbix监察和控制MySQL数据库参数

ZABBIX 的详实介绍:请点这里
ZABBIX 的下载地址:请点这里

本文长久更新链接地址:

方今在看Linux
I/O子系统有关的素材,要求监察和控制每台服务器的磁盘I/O,特别是MongoDB数据库服务器的磁盘I/O,由于每…

printf  “\n\t]\n”

server端

 

前言

为啥必要做服务器jvm自动开掘的督察呢?那么些业务根本有两点原因:
    1.zabbix私下认可监控jvm状态是采用jmx中间转播举行监察和控制的,监察和控制功效十分低下
   
2.zabbix使用jmx监察和控制jvm的时候是因为八个主机上的键值不能够重新,也就招致了一台主机上不得不监察和控制叁个jvm实例
   
以上两点原因形成zabbix通过jmx监察和控制jvm的达成不是很不错,加上如今极其须要访谈服务器上边跑的保有java应用的新闻,于是自个儿雕刻了下,依然自身出手,安身立命。利用了周日的时日,通过使用shell脚本+java工具jstat+zabbix达成监督主机上多jvm实例的效果。
首先章:概念的接头
 首先,既然要监督jvm状态,那就一定要打听jvm里面包车型地铁音讯,楼主通过查找资料加自动脑补,把英特网的材质取其卓越,去其残余,整理了弹指间。JVM中的内部存款和储蓄器分类分为堆内存和非堆内部存款和储蓄器,堆内部存款和储蓄器是给实际使用使用的,非堆内部存款和储蓄器是给jvm容器使用的。大家注重关怀的是堆内部存款和储蓄器那块。在堆内部存款和储蓄器里面,给内部存款和储蓄器分为如下几块:
 1.Young代(年轻代)
 2.Old代(老年代)
 3.Perm代(永世代)(关于那一点,在JDK7和JDK第88中学情形不均等,就要背后进行分析)
 个中,年轻代中间又分为了三块,如下:
 1.Eden代(伊甸园代)
 2.sur酷派r0代(0号幸存区)
 3.sur小米r1代(1号幸存区)
 至于更详尽的关于JVM堆内存的音信,各位能够自行百度依然google,作者这里就不赘述了,究竟笔者也是个半桶水,本人找了点资料外加脑补到的部分事物,不敢在关云长门前耍长刀了。
 当然,还得广大学一年级个东西,那正是GC,所谓的GC正是JVM在运行的时候会有四个杂质回收机制,那个污源回收机制是什么境况吧?就是在程序运维的时候会生出过多早就不采取的长空,但还是被占用了的情形,那样会促成非常多不须求的荒芜,于是JVM就有一个垃圾堆回收机制,针对程序中曾经不使用的内部存款和储蓄器财富,会进展回收释放,那几个进程就叫做GC。当然,关于GC还恐怕有众多剧情笔者那边也从未前述,理由同上条。各位看官只必要精晓GC是JVM监察和控制里面包车型客车一个很要紧的参数就行了。
 第一章,关于JVM中概念的知晓甘休了,预见后事怎么着,请听下回分解。
第二章:JAVA工具的选用
 java工具有众多,关于jvm监察和控制的工具首要有如下多少个:
 + jstat
 + jmap
 + jstack
 在那之中jmap –heap
pid能够抓出挺多的有关有些jvm的运行参数,可是特别提示自个儿最棒永不接纳jmap进行jvm监察和控制,具体未有证实原因。于是本着打破砂锅问到底的旺盛,作者又去搜了一把,发掘了之类内容:
 jmap最重视的安危操作是上边这两种:

  1. jmap -dump
    本条命令实行,JVM会将全部heap的音信dump写入到贰个文书,heap如若一点都非常大的话,就能够促成这一个历程相比较耗费时间,并且实行的进度中为了保证dump的新闻是可相信的,所以会停顿使用。
  2. jmap -permstat
    那些命令推行,JVM会去计算perm区的景观,那全部经过也会比较的耗费时间,何况同样也会搁浅使用。
  3. jmap -histo:live
    其一命令试行,JVM会先触发gc,然后再计算消息。
    地点的那多个操作都将对使用的进行产生潜濡默化,所以提议一旦不是很有要求的话,不要去推行。
    为此,从地方三点来看,jmap命令对jvm状态影响照旧十分大的,而且实践jmap
    –heap的时间也正如长,成效十分低,予以排除。
    接下去是jstack,那个命令能够深切到JVM里面前遇到JVM运维难题进行排查,传闻还是可以够总结JVM里面的线程数量。然则这几个命令试行效能也正如低,被拔除掉了。
    于是乎剩下的唯有八个jstat命令了。上边来详细的讲明该命令的运用了,咳咳,各位快点打源点精神来,那只是重头戏来了。

    首先,列出jstat命令的有个别使用案例吧:

    1.jstat -gc pid
                能够展现gc的新闻,查看gc的次数,及时间。
                个中最终五项,分别是young gc的次数,young gc的时光,full
    gc的次数,full gc的时光,gc的总时间。
    S0C    S1C    S0U    S1U      EC      EU        OC        OU      PC   
    PU    YGC    YGCT    FGC    FGCT    GCT   
    9792.0 10048.0  0.0  5143.2 242048.0 220095.4  323200.0  211509.3 
    186368.0 114451.6    317    4.850  4      0.971    5.821
     S0C    S1C    S0U    S1U      EC      EU        OC        OU      MC   
    MU    CCSC  CCSU  YGC    YGCT    FGC    FGCT    GCT   
    1024.0 1024.0  0.0  320.0  11776.0  11604.6  260608.0  149759.6  39344.0
    38142.6 4528.0 4303.1  5473  24.010  2      0.128  24.138
    2.jstat -gccapacity pid
               
    可以显得,VM内部存款和储蓄器中三代(young,old,perm)对象的行使和占用大小,
                如
    PGCMN呈现的是纤维perm的内部存款和储蓄器使用量,PGCMX呈现的是perm的内部存款和储蓄器最大使用量,
                PGC是近来新生成的perm内部存储器占用量,PC是但前perm内部存款和储蓄器占用量。
                别的的能够依据这么些类比, OC是old内纯的占用量。
     NGCMN    NGCMX    NGC    S0C  S1C      EC      OGCMN      OGCMX     
    OGC        OC      PGCMN    PGCMX    PGC      PC    YGC    FGC 
     87360.0 262144.0 262144.0 9792.0 10048.0 242048.0  174784.0  786432.0 
    323200.0  323200.0 131072.0 262144.0 186368.0 186368.0    317    4
     NGCMN    NGCMX    NGC    S0C  S1C      EC      OGCMN      OGCMX     
    OGC        OC      MCMN    MCMX      MC    CCSMN    CCSMX    CCSC   
    YGC    FGC 
     1536.0 174592.0  13312.0  512.0  512.0  11776.0  260608.0  349696.0 
    260608.0  260608.0      0.0 1083392.0  39344.0      0.0 1048576.0 
    4528.0  5474    2
    3.jstat -gcutil pid
                总结gc音信总括。
      S0    S1    E      O      P    YGC    YGCT    FGC    FGCT    GCT   
      0.00  51.19  83.29  65.44  61.41    317    4.850    4    0.971   
    5.821
       
      S0    S1    E      O      M    CCS    YGC    YGCT    FGC    FGCT   
    GCT   
     68.75  0.00  46.74  57.47  96.95  95.03  5474  24.014    2    0.128 
    24.143
    4.jstat -gcnew pid
              年轻代指标的音讯。
     S0C    S1C    S0U    S1U  TT MTT  DSS      EC      EU    YGC    YGCT 
    9792.0 10048.0    0.0 5143.2  3  15 9792.0 242048.0 198653.2    317   
    4.850
     S0C    S1C    S0U    S1U  TT MTT  DSS      EC      EU    YGC    YGCT 
     512.0  512.0  352.0    0.0 15  15  512.0  11776.0  8446.4  5474 
    24.014
    5.jstat -gcnewcapacity pid
              年轻代目的的新闻及其占用量。
    NGCMN      NGCMX      NGC      S0CMX    S0C    S1CMX    S1C      ECMX   
        EC      YGC  FGC 
      87360.0  262144.0  262144.0  87360.0  9792.0  87360.0  10048.0 
    262016.0  242048.0  317    4
    NGCMN      NGCMX      NGC      S0CMX    S0C    S1CMX    S1C      ECMX   
        EC      YGC  FGC 
      1536.0  174592.0    13312.0  57856.0    512.0  57856.0    512.0 
    173568.0    11776.0  5475    2
    6.jstat -gcold pid
              old代对象的信息。
      PC      PU        OC          OU      YGC    FGC    FGCT    GCT   
    186368.0 114451.6    323200.0    211509.3    317    4    0.971   
    5.821
      MC      MU      CCSC    CCSU      OC          OU      YGC    FGC   
    FGCT    GCT   
     39344.0  38142.6  4528.0  4303.1    260608.0    149783.6  5475    2   
    0.128  24.148
    7.jstat -gcoldcapacity pid
              old代对象的消息及其占用量。
      OGCMN      OGCMX        OGC        OC      YGC  FGC    FGCT    GCT 
     
      174784.0    786432.0    323200.0    323200.0  317    4    0.971   
    5.821
      OGCMN      OGCMX        OGC        OC      YGC  FGC    FGCT    GCT 
     
      260608.0    349696.0    260608.0    260608.0  5475    2    0.128 
    24.148
       
       
    8.jstat -gcpermcapacity pid
              perm对象的音讯及其占用量。
      PGCMN      PGCMX      PGC        PC      YGC  FGC    FGCT    GCT   
      131072.0  262144.0  186368.0  186368.0  317    4    0.971    5.821
    没有
    9.jstat -class pid
              显示加载class的数目,及所占空间等消息。
    Loaded  Bytes  Unloaded  Bytes    Time   
     25315 45671.7    5976  7754.1      15.19
    Loaded  Bytes  Unloaded  Bytes    Time   
      6472 11893.0        0    0.0      5.97
    10.jstat -compiler pid
              呈现VM实时编译的多少等消息。
    Compiled Failed Invalid  Time  FailedType FailedMethod
        4219      3      0    63.36          1
    org/aspectj/weaver/ResolvedType addAndRecurse
    Compiled Failed Invalid  Time  FailedType FailedMethod
      11364      1      0  107.53          1 sun/nio/cs/UTF_8$Decoder
    decode
    11.stat -printcompilation pid
              当前VM施行的消息。
    Compiled  Size  Type Method
        4219  2232    1 net/spy/memcached/protocol/ascii/BaseGetOpImpl
    initialize
    Compiled  Size  Type Method
      11364    212    1
    com/alibaba/rocketmq/client/impl/consumer/RebalanceService run
      ==================================================

 
能够看到地点作者列出的授命试行结果为啥有两行呢,那是因为是用差别的jdk版本实行的。
 
上边是JDK7推行结果,上面是JDK8实践结果,那七个本子之间输出的结果是有反差的,下边,就来分析为何会爆发这种差异。
JDK7和JDK第88中学JVM堆内部存款和储蓄器划分数之差别
 
假若记性好的童鞋们应该还是能够记得作者下面在介绍JVM堆内部存款和储蓄器分类的时候括号里写的百般东东吧,没有错,便是那么些东西导致的。在JDK7中的Perm代(长久代)在JDK第88中学被打消了,替代它的是Metadata代(元数据代),据书上说那些元数据代相对于永世代实行了优化,假如不设置最大值的话,私下认可会按需抓好,
不会导致像Perm代中内存占满后会爆出内部存款和储蓄器溢出的一无所能,元数据代也能够设置最大值,那样的话,当内部存款和储蓄器区域被消耗完的时候将会和Perm代同样爆出内部存款和储蓄器溢出的失实。(PS:原谅本人的布鼓雷门,只好解释到那贰个范畴了。)
好了,解释清楚了JDK7和JDK8的异样今后,接下去大家来解释jstat抓到的那些参数了。
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960

        {“{#DISK_NAME}”:”xvdb”}

安装如下:

 

 

jstat命令获取参数剖析

* S0C 年轻代中首先个surMotorolar(幸存区)的体积 (字节)jstat -gcnew
$pid|tail -1|awk ‘{print $1*1024}’
* S0U 年轻代中率先个sur一加r(幸存区)这两天已选用空间 (字节)jstat -gcnew
$pid|tail -1|awk ‘{print $3*1024}’
* S0 年轻代中第多少个surNokiar(幸存区)已运用的占当前容积百分比jstat
-gcutil $pid|tail -1|awk ‘{print $1}’
* S0CMX 年轻代中率先个sur索爱r(幸存区)的最大体量 (字节)jstat
-gcnewcapacity $pid|tail -1|awk ‘{print $4*1024}’

* S1C 年轻代中第一个sur三星r(幸存区)的体积 (字节)jstat -gcnew
$pid|tail -1|awk ‘{print $2*1024}’
* S1U 年轻代中第叁个sur小米r(幸存区)近年来已利用空间 (字节)jstat -gcnew
$pid|tail -1|awk ‘{print $4*1024}’
* S1 年青代中第二个sur金立r(幸存区)已使用的占当前体量百分比jstat
-gcutil $pid|tail -1|awk ‘{print $2}’
* S1CMX  年轻代中第二个sur摩托罗拉r(幸存区)的最大容积 (字节)jstat
-gcnewcapacity $pid|tail -1|awk ‘{print $6*1024}’
* DSS 当前亟待suriPhoner(幸存区)的体积 (字节)(Eden区已满)jstat -gcnew
$pid|tail -1|awk ‘{print $7*1024}’

* EC 年轻代中Eden(伊甸园)的体积 (字节)jstat -gcnew $pid|tail -1|awk
‘{print $8*1024}’
* EU 年轻代中Eden(伊甸园)近些日子已利用空间 (字节)jstat -gcnew $pid|tail
-1|awk ‘{print $9*1024}’
* ECMX 年轻代中Eden(伊甸园)的最大体积 (字节)jstat -gcnewcapacity
$pid|tail -1|awk ‘{print $8*1024}’
* E 年轻代中艾登(伊甸园)已运用的占当前体积百分比jstat -gcutil
$pid|tail -1|awk ‘{print $3}’

* NGCMN 年轻代(young)中开始化(最小)的大小 (字节)jstat -gccapacity
$pid|tail -1|awk ‘{print $1*1024}’
* NGCMX 年轻代(young)的最大体量 (字节)jstat -gccapacity $pid|tail
-1|awk ‘{print $2*1024}’
* NGC 年轻代(young)中当前的体积 (字节)jstat -gccapacity $pid|tail
-1|awk ‘{print $3*1024}’

* OC Old代的体量 (字节)jstat -gcold $pid|tail -1|awk ‘{print
$3*1024}’
* OU Old代最近已使用空间 (字节)jstat -gcold $pid|tail -1|awk ‘{print
$4*1024}’
* OGCMX old代的最大体积 (字节)jstat -gccapacity $pid|tail -1|awk
‘{print $8*1024}’
* OGCMN old代中初叶化(最小)的大小 (字节)jstat -gccapacity $pid|tail
-1|awk ‘{print $7*1024}’
* O old代已使用的占当前容积百分比jstat -gcutil $pid|tail -1|awk ‘{print
$4}’
* OGC old代当前新生成的体量 (字节)jstat -gccapacity $pid|tail -1|awk
‘{print $9*1024}’

* PC Perm(持久代)的容量 (字节)jstat -gccapacity $pid|tail -1|awk
‘{print $14*1024}’
* PU Perm(长久代)近日已利用空间 (字节)jstat -gc $pid|tail -1|awk
‘{print $10*1024}’
* PGCMX perm代的最大容积 (字节)jstat -gccapacity $pid|tail -1|awk
‘{print $12*1024}’
* PGCMN perm代中开端化(最小)的大小 (字节)jstat -gccapacity $pid|tail
-1|awk ‘{print $11*1024}’
* P perm代已利用的占当前容量百分比 jstat -gcutil $pid|tail -1|awk
‘{print $5*1024}’
* PGC perm代当前新生成的体量 (字节)jstat -gccapacity $pid|tail -1|awk
‘{print $13*1024}’

* YGC 从应用程序运维到采集样品时年轻代中gc次数jstat -gccapacity $pid|tail
-1|awk ‘{print $15}’
* YGCT 从应用程序运行到采集样品时年轻代中gc所用时间(s)jstat -gcutil
$pid|tail -1|awk ‘{print $7}’
* FGC从应用程序运维到采集样品时old代(全gc)gc次数jstat -gccapacity $pid|tail
-1|awk ‘{print $16}’
* FGCT 从应用程序运营到采集样品时old代(全gc)gc所用时间(s)jstat -gcutil
$pid|tail -1|awk ‘{print $9}’
* GCT 从应用程序运行到采集样品时gc用的总时间(s)jstat -gcutil $pid|tail
-1|awk ‘{print $10}’

* TT  持有次数限制jstat -gcnew $pid|tail -1|awk ‘{print $5}’
* MTT  最大有所次数限制jstat -gcnew $pid|tail -1|awk ‘{print $6}’
*
* Loadedjvm加载class数量
* Unloadedjvm未加载class数量
*
* M元数据区使用比例
* MC当前元数据空间大小
* MU元数据空间利用大小
* MCMN最小元数据体量 
* MCMX最大元数据体量

* CCS压缩使用比例
* CCSC当前压缩类空间大小
* CCSU压缩类空间利用大小
* CCSMN最小压缩类空间大小

        wKBps)

丰裕完重启agent端

 

service zabbix-agent restart

            ;;

zabbix-server web分界面导入模板以及主机连接模板,还索要安装正则等

 

 

 

 

 

 

 

 

 

            /usr/bin/tail -n20 /tmp/iostat_output |grep
“\b$device\b”|tail -1|awk ‘{print $4}’

在ageng端创造脚本

 

mdkir -p /etc/zabbix/scripts

 

vim redis_low_discovery.sh

 

#/bin/bash

#Script_name redis_low_discovery.sh

redis() {

            port=($(netstat -tpln | awk -F “[ :]+” ‘/redis/ &&
/0.0.0.0/ {print $5}’))

            printf ‘{\n’

            printf ‘\t”data”:[\n’

               for key in ${!port[@]}

                   do

                       if [[ “${#port[@]}” -gt 1 && “${key}” -ne
“$((${#port[@]}-1))” ]];then

              socket=`ps aux|grep ${port[${key}]}|grep -v grep|awk -F
‘=’ ‘{print $10}’|cut -d ‘ ‘ -f 1`

                          printf ‘\t {\n’

                          printf
“\t\t\t\”{#REDISPORT}\”:\”${port[${key}]}\”},\n”

                     else [[ “${key}” -eq “((${#port[@]}-1))” ]]

              socket=`ps aux|grep ${port[${key}]}|grep -v grep|awk -F
‘=’ ‘{print $10}’|cut -d ‘ ‘ -f 1`

                          printf ‘\t {\n’

                          printf
“\t\t\t\”{#REDISPORT}\”:\”${port[${key}]}\”}\n”

                       fi

               done

                          printf ‘\t ]\n’

                          printf ‘}\n’

}

$1

 

$ /usr/local/zabbix/bin/zabbix_get -s 192.168.1.190 -p 10055 -k
“disk.status[xvda,wps]”10.00

修改属主

chown -R zabbix.zabbix /etc/zabbix/scripts/

 

}

检验 是或不是取到redis数据的值:

UserParameter=disk.status[*],/usr/local/zabbix/bin/disk_status.sh $1
$2

添加UserParameter

 

vim /etc/zabbix/zabbix_agentd.conf

 

 

UserParameter=zabbix_low_discovery[*],/bin/bash
/etc/zabbix/scripts/redis_low_discovery.sh $1

UserParameter=redis_stats[*],(echo info; sleep 1) | telnet 127.0.0.1
$1 2>&1 |grep $2|cut -d : -f2

 

CentOS 6.3下Zabbix监察和控制MySQL数据库参数
http://www.linuxidc.com/Linux/2013-05/84800.htm

终极把模版增多到主机里面去

 

 

一些或者自行开采并未有开启

 

 

 

 

 

 

# Mandatory: no

设置正则

Redis regex

 

Result TRUE  = ^(6380|17761|17762|18005|23581)$

 

 

 

 

 

 

        {

在“管理”—> “一般”—>“正则表明式”里,选拔“新的正则表明式”

{

使用zabbix_get获取redis键值

 

cd /usr/bin

 

./zabbix_get -s 192.168.0.11 -k “zabbix_low_discovery[redis]”

 

 

}

给权限

chmod 755 scripts/redis_low_discovery.sh

            ;;

只要运营报错

 

 

那就chmod +s /bin/netstat

 

chmod +s 是什么样看头

为了方便普通用户实行一些特权命令,SUID/SGID程序同意普通用户以root身份权且实施该程序,并在实践完成后再过来身份。

 

 

 

 

 

        printf “\”{#DISK_NAME}\”:\”${diskarray[$i]}\”}”

配置—模板—

 

 

 

 

$ python disk_discovery.py

在终极里面

 

cd  /usr/bin

 

./zabbix_get -s 192.168.0.11 -k
“redis_stats[6381,uptime_in_seconds]”

 

 

./zabbix_get -s 192.168.0.11 -k
“redis_stats[6380,uptime_in_seconds]”

 

 

 

            “{#DISK_NAME}”:”xvdb”

亟需张开telnet服务,没有的急需设置叁个telnet

 

yum install telnet -y

#      User-defined parameter to monitor. There can be several
user-defined parameters.

然后 看数据图

 

    if len(disk) != 0:

关闭requiretty

sed -i ‘s/^Defaults.*.requiretty/#Defaults    requiretty/’ /etc/sudoers

 

或者 vim /etc/sudoers  #56行

 

 

device=$1

一经不让用telnet协议,还足以

 

UserParameter=redis_stats[*],/usr/local/bin/redis-cli -h 127.0.0.1
-p $1 info|grep $2|cut -d : -f2

args=”cat /proc/diskstats |grep -E
‘\ssd[a-z]\s|\sxvd[a-z]\s|\svd[a-z]\s’|awk ‘{print
$3}’|sort|uniq 2>/dev/null”

$ sh disk_discovery.sh

            ;;

do

    avgqu-sz)

    ]

for disk in t.split(‘\n’):

        util)

添加disk_status.conf

 length=${#diskarray[@]}

esac

        await)

        rKBps)

   

Author

发表评论

电子邮件地址不会被公开。 必填项已用*标注

相关文章