轉 zabbix 自動發現和 zabbix自定義用戶key與參數User parameters


########31

https://www.cnblogs.com/yjt1993/p/10883345.html

1、概念

  在配置Iterms的過程中,有時候需要對類似的Iterms進行添加,這些Iterms具有共同的特征,表現為某些特定的參數是變量,而其他設置都是一樣的,例如:一個程序有多個端口,而需要對端口配置Iterms。再如,磁盤分區,網卡的名稱等等,由於具有不確定性,古配置固定的Items會出現無法通用的問題。

  Low level discovery的Key可以對網卡、文件系統等進行自動發現,當然也支持自定義。

  Low level discovery的使用過程分如下兩步:

    (1)自動發現特定變量的名稱。

    (2)添加對變量的Items。

  Zabbix中Low level discovery的Key返回值是一個JSON格式。查看Low level discovery Key返回格式如下:

2、案列

  使用Zabbix監控Hadoop集群的進程。每台機器啟動的進程不一樣,而這個時候想要監控每一台機器的hadoop進程,就需要自動發現規則了,如果配置通用的模板,把每一個監控項(監控每一個hadoop的進程)都配置上,會發現每一台主機對有些監控項是不支持的。

zabbix客戶端配置如下:

EnableRemoteCommands=1  開啟遠程執行命令,默認是0,當監控到hadoop進程掉了以后,自動啟動。

Timeout=30  超時

StartAgents=8  開啟處理線程 

編寫自動發現腳本如下:

復制代碼
[root@manager1 script_py 19:20:09]#cat hadoopDiscovery.py 
#!/usr/bin/env python3
import os
import json

with open("/data1/zabbix_sh/jps.txt", "r") as f:
    text_lst = [i.split("\n")[0] for i in f.readlines()]

hadoopProcess = []

for i in text_lst:
    hadoopProcess += [{'{#hadoopProcessName}':i}]
print(json.dumps({'data':hadoopProcess},sort_keys=True,indent=7,separators=(',',':')))
復制代碼
[root@manager1 script_py 19:20:12]#cat /data1/zabbix_sh/jps.txt    這里面存儲的是當前節點本應該啟動的進程
DataNode
Master

執行效果如下:

  (1)自定義Key,如下:

# cat /etc/zabbix/zabbix_agentd.d/hadoop_process.conf 
UserParameter=hadoop_process[*],sudo /data1/zabbix_sh/hadoopProcess.py $1
UserParameter=hadoop_state,sudo  /data1/zabbix_sh/hadoopState.py
UserParameter=hadoop.process.discovery,sudo /data1/zabbix_sh/hadoopDiscovery.py
hadoopProcess.py腳本如下:
復制代碼
# cat hadoopProcess.py 
#!/usr/bin/env python3
'this is a system monitor scripts'
__author__="yjt"

import os
import sys
def hadoop_program():
    with open("/data1/zabbix_sh/jps.txt", "r") as f:
        list_jps = [i.split("\n")[0] for i in f.readlines()]

    job_value = []
#    hadoop_process = ['JournalNode','ResourceManager','HMaster','DataNode','DFSZKFailoverController','QuorumPeerMain','HQuorumPeerMain','JobHistory','Kfaka','NodeManager','Worker','Master','HRegionServer','NameNode','PrestoServer','RunJar']
    job_lst = os.popen('/data1/jdk/bin/jps').readlines()
    for i in job_lst:
        value = i.split()[1]
        if value != 'Jps':
            job_value.append(value)
    if sys.argv[1] in job_value:
        print(1 )
    elif sys.argv[1] in list_jps:
        print(0)
#    else:
#        print(2)

if __name__ == "__main__":
    if len(sys.argv) > 1:
        hadoop_program()
復制代碼

配置完重啟zabbix客戶端

測試,是否可以從server端獲取到數據:

 

(2)web界面的配置:

   1)創建一個模板:配置---> 模板--->創建模板

 

   2)在改模板上創建自動發現規則:

 

   3)自動發現規則配置

 

 

 

  4)為這個模板創建原型的監控項

 

 

 

 

  5)創建觸發器:

  6)創建圖形:

 

 

 

到這里這個模板就創建好了。這個時候在創建主機的時候,關聯這個模板看看效果,需要等待一段時間。效果如下:

第一台機器:

 

 第二台機器:

 

 OK

 

##########32

http://www.ttlsa.com/zabbix/zabbix-user-parameters/

為什么要自定義KEY

有時候我們想讓被監控端執行一個zabbix沒有預定義的檢測,zabbix的用戶自定義參數功能提供了這個方法。我們可以在客戶端配置文件zabbix_angentd.conf里面配置UserParameter.
語法如下:

用戶自定義參數包含一個key和一個命令,key必須整個系統唯一,配置好之后,重啟客戶端。

然后配置item,在key的位置填上我們自定義的key即可。

用戶自定義參數里指定的腳本由zabbix agent來執行,最大可以返回512KB的數據.

用戶自定義key實例

簡單點的命令示例:
UserParameter=ping,echo 1
如果調用ping這個key,將會收到返回值1.
更復雜的命令示例:
UserParameter=mysql.ping,mysqladmin -uroot ping|grep -c alive
如果返回1表示MySQL運行中,如果返回0表示MySQL掛了

靈活的自定義key:

如下為靈活的用戶自定義參數

 

參數 描述
Key 唯一. [*]表示里面可以傳遞多個參數
Command 需要執行的腳本,key的[]里面的參數一一對應$1到$9,一共9個參數。$0表示腳本命令.

注意事項

1. 如果需要使用命令行里面出現$2這種變量,那么你要使用兩個$$2,例如awk ’{ print $$2 }’,之前就遇到過這個問題,不停的測試自己腳本輸出正常,但是zabbix卻拿不到數據,原來是出在這里。為了防止和參數沖突,所以zabbix做了這個規定。
2. zabbix禁止使用一些不安全的參數,如下:
\ ' ” ` * ? [ ] { } ~ $ ! & ; ( ) < > | # @
3. 從zabbix 2.0開始,zabbix返回文本數據可以是空格。

示例1

UserParameter=ping[*],echo $1
ping[0] - 將一直返回0
ping[aaa] - 將一直返回 'aaa'

示例2

UserParameter=mysql.ping[*],mysqladmin -u$1 -p$2 ping | grep -c alive
如下參數用於監控MYSQL,並且可以傳遞用戶名和密碼。
mysql.ping[zabbix,our_password]

示例3

統計一個文件中有多少行被匹配?
UserParameter=wc[*],grep -c "$2" $1
如下方法將會返回文件中出現指定字符的行數
wc[/etc/passwd,root]
wc[/etc/services,zabbix]

 

 

##########below is sample

 

1.percona Mysql template

1.1 單實例

 

 

一、概述

 

zabbix自帶的MySQL插件來監控mysql數據庫,但是太過簡陋了,對於我們dba來說,基本沒有啥作用,所以需要做更詳細的監控,而percona就有這個詳細監控的模版以及腳本,正好拿過來用。

percona官網: www.percona.com

Percona組成介紹

1、PHP腳本    用來數據采集  (ss_get_mysql_stats.php)

2、shell腳本  用來調用采集信息 (get_mysql_stats_wrapper.sh)

3、zabbix配置文件

4、zabbix模板文件

5. 300秒的輪詢間隔,現有PHP腳本用於收集和緩存MySQL度量,除了一些觸發器特定的項之外。由於結果的緩存,PHP腳本每個周期只運行一次。

$cache_dir  = '/tmp';  # If set, this uses caching to avoid multiple calls.

(以下都是在zabbix用戶下調試)

 

6.整個流程

(ServerActive=10.0.0.106 #<====zabbix-server端的IP地址,主動方式)

Zabbix Agent /etc/zabbix/zabbix_agentd.d/ -〉讀取 userparameter_percona_mysql.conf –〉調用 get_mysql_stats_wrapper.sh  ix  ->

調用   Php ->

 

 

二、安裝及配置

1、下載及安裝

https://www.percona.com/downloads/percona-monitoring-plugins/LATEST/

 

同時也支持Nagios和catcti

wget https://www.percona.com/downloads/percona-monitoring-plugins/percona-monitoring-plugins-1.1.7/binary/redhat/6/x86_64/percona-zabbix-templates-1.1.7-2.noarch.rpm

 

-〉1配置agent 配置

 

rpm -ivh percona-zabbix-templates-1.1.8-1.noarch.rpm

 

Scripts are installed to /var/lib/zabbix/percona/scripts

Templates are installed to /var/lib/zabbix/percona/templates

 

yum install percona-zabbix-templates php php-mysql -y

Installed:

  php.x86_64 0:5.3.3-47.el6                 php-mysql.x86_64 0:5.3.3-47.el6               

Dependency Installed:

  php-cli.x86_64 0:5.3.3-47.el6               php-common.x86_64 0:5.3.3-47.el6             

  php-pdo.x86_64 0:5.3.3-47.el6             

Complete!

 

 

[root@devops-mysql-node1 ~]# rpm -ql percona-zabbix-templates

/var/lib/zabbix/percona

/var/lib/zabbix/percona/scripts

/var/lib/zabbix/percona/scripts/get_mysql_stats_wrapper.sh

/var/lib/zabbix/percona/scripts/ss_get_mysql_stats.php

/var/lib/zabbix/percona/templates

/var/lib/zabbix/percona/templates/userparameter_percona_mysql.conf

/var/lib/zabbix/percona/templates/zabbix_agent_template_percona_mysql_server_ht_2.0.9-sver1.1.8.xml   為MYSQL監控模板

 

-zabbix配置文件

將配置文件拷貝到/etc/zabbix/zabbix_agentd.d/目錄

cp  /var/lib/zabbix/percona/templates/userparameter_percona_mysql.conf

/usr/local/zabbix/etc/zabbix_agentd.conf.d/

 

More /usr/local/zabbix/etc/zabbix_agentd.conf.d/userparameter_percona_mysql.conf

(這里是支持擴展的腳本位置)

Useparameter=Mysql.rows-updated,****/get_mysql_stats_wrapper.sh ix

**

 

(Ensure zabbix_agentd.conf contains the line: Include=/etc/zabbix_agentd.conf.d/ )

 

->2建立本地用戶

(如下2個授權grant 命令都需要執行)

> GRANT PROCESS,SUPER,REPLICATION CLIENT ON *.* TO zabbix@'localhost' IDENTIFIED BY '123456';

> grant all privileges on *.* to zabbix@localhost;

> flush privileges;

> select user,host from mysql.user;

> quit;

 

 

-〉3zabbix 腳本文件 ss_get_mysql_stats.php (重要,測試mysql 聯通性 ,配置項目 使用用戶/密碼/本地socket連接)

 

1).vim /var/lib/zabbix/percona/scripts/ss_get_mysql_stats.php

$mysql_user = 'root';

$mysql_pass = '123456';

$mysql_port = 3306;

$mysql_socket = '/db/mysql/data/mysqltmp/mysql.sock';

$mysql_flags = 0;

測試環境root密碼為空,如果生產環境會創建專門只讀賬號。

 

 

2).同時注意:/var/lib/zabbix/percona/scripts/ss_get_mysql_stats.php

以下參數定義緩存文件的具體位置

(如果port變量定義一個非默認的3306 端口,就會往/tmp 寫入一個文件 t-mysql_cacti_stats.txt:$port)

 

$cache_file = "$cache_dir/$sanitized_host-mysql_cacti_stats.txt" . ($port != 3306 ? ":$port" : '');

 

注意:

測試1:(zabzabbix 用戶下)

 

如果 密碼  配置錯誤,

/usr/bin/php -q /var/lib/zabbix/percona/scripts/ss_get_mysql_stats.php --host localhost --items gg

 

會出現如下報錯 :

root@centos6 ~]# /var/lib/zabbix/percona/scripts/get_mysql_stats_wrapper.sh gg

ERROR: run the command manually to investigate the problem: /usr/bin/php -q /var/lib/zabbix/percona/scripts/ss_get_mysql_stats.php --host localhost --items gg

[root@centos6 ~]# /usr/bin/php -q /var/lib/zabbix/percona/scripts/ss_get_mysql_stats.php --host localhost --items gg

ERROR: Can't connect to local MySQL server through socket '/var/lib/mysql/mysql.sock' (2)[root@centos6 ~]#

 

如果連接失敗,可以使用如下PHP 測試下

#######

 

<?php

$i = 10000;

$host= 'localhost';

$user = 'dbmonopr';

$pass = 'dbmonoprommo11';

$port = 3307;

$socket = '/db/mysql/data/mysqltmp/mysql.sock';

$flags = 0;

while($i>=0) {

$conn = mysqli_init();

$link =mysqli_real_connect($conn, $host, $user, $pass, NULL, $port, $socket, $flags) or die(mysqli_connect_error());

$info = mysqli_get_host_info($conn);

$i--;

mysqli_close($conn);

unset($conn);

}

?>

###

 

 

2.-> zabbix 腳本文件 get_mysql_stats_wrapper.sh   (如果mysql 端口 不是3306,而是3503。這個也需要修改)

修改1第15行,如果是默認端口,不需要修改這一項

change

CACHEFILE="/tmp/$HOST-mysql_cacti_stats.txt"

to

CACHEFILE="/tmp/$HOST-mysql_cacti_stats.txt:3503"

 

修改2: 第19行 到25行,變量里加入“mysql 的絕對路徑”和“用戶和密碼” 和 “2〉/dev/null”

change

19 行 到 25行修改如下:

to

 

 

RES=`HOME=~zabbix /db/mysql/app/mysql/bin/mysql  -uuser-pdbmonoprommo11 -e 'SHOW SLAVE STATUS\G' 2>/dev/null | egrep '(Slave_IO_Running|Slave_SQL_Running):' | grep -i yes|wc -l`

if [ "$RES" -ne 2 ]; then

echo 1

else

      RES1=`HOME=~zabbix /db/mysql/app/mysql/bin/mysql  -uuser-pdbmonoprommo11 -e 'SHOW SLAVE STATUS\G' 2>/dev/null | egrep '(Slave_IO_Running|Slave_SQL_Running):' | awk -F: '{print $2}' | tr '\n' ','`

     if [ "$RES1" = " Yes, Yes," ]; then

        echo 1

    else

        echo 0

    fi

fi

exit

 

 

測試2:(root 用戶下)

sudo -u  zabbix -H /usr/local/zabbix/bin/get_mysql_stats_wrapper.sh running-slave

0

(正常情況下,應該返回0或者1,而不是“Access denied” 報錯 )

 

/usr/local/zabbix/bin/get_mysql_stats_wrapper.sh running-slave

0

(正常情況下,應該返回0或者1,而不是“Access denied” 報錯 )

 

需要改配置文件需要重啟

/etc/init.d/zabbix-agent restart

或者

pkill zabbix

/usr/local/zabbix/sbin/*

 

測試3:(zabzabbix 用戶下)

進行測試會返回測試結果

cd /var/lib/zabbix/percona/scripts/

./get_mysql_stats_wrapper.sh gm

0

./get_mysql_stats_wrapper.sh gw

20060

 

或者

/usr/bin/php  -q /var/lib/zabbix/percona/scripts/ss_get_mysql_stats.php --host localhost --items gg

0

-q 解讀:

(#!/usr/bin/php -q /* -*- c -*- */

3.打開 Debug (zabbix 用戶下修改ss_get_mysql_stats.php,確保/tmp/1.log  zabbix 用戶有寫的權限)

ss_get_mysql_stats.php

$debug     = true;

$debug_log = '/tmp/1.log';

 

關閉debug 

 

 $debug     = FALSE; # Define whether you want debugging behavior.

$debug_log = FALSE; # If $debug_log is a filename, it'll be used.

 

ss_get_mysql_stats.php 解讀:

 

-〉首先判斷語法 是否正確

ss_get_mysql_stats.php --host localhost --items gg

 

-〉 其次 語法正確,就會在輸出 runquery    SHOW /*!50000 ENGINE*/ INNODB STATUS,

'SHOW /*!50002 GLOBAL */ STATUS'

(如果鍵值在status沒有定義,有可能新版本廢棄了,那么返回值為-1)

 

->  其次判斷 如果cache_file 超過300秒,就會刪除,重寫一遍,如果不超過300秒,就不重寫一遍。

 

->最后 如果有寫的權限,就會寫入一個臨時文件 類似 localhost-mysql_cacti_stats.txt.port

 

 

附錄:

主要運行的命令如下:run_query

命令如下:

SHOW MASTER LOGS

SHOW VARIABLES

SHOW  STATUS

SHOW SLAVE STATUS

SHOW PROCESSLIST

SHOW INNODB STATUS

 

主要的檢查項目如下:

   $keys = array(

'Key_read_requests'           =>  'gg',

'Key_reads'                   =>  'gh',

 

具體 各個屬性的 縮寫 請參考如下:

 

 

Php 連接調試

<?php

$host= 'localhost';

$conn = mysqli_init();

mysqli_real_connect($conn, NULL, 'dbmonopr', 'dbmonoprommo11', NULL, NULL, '/db/mysql/data/mysqltmp/mysql.sock');

?>

 

 

 

1.2 多實例

 

1台server 多個實例(即這些實例都綁定到同一個機器ip和不同端口)的問題,主要體現在采集端 需要適配多個server 進程

多個實例的監控用戶和密碼必須保持一致

 

1.1.-> zabbix 腳本文件 get_mysql_stats_wrapper.sh 

 

12 行加入

PORT=$2

 

13 host 修改localhost為IP

HOST=”10.241.1.1”

 

15 行更改為 加入 --port $PORT

 

CMD="/usr/bin/php -q $DIR/ss_get_mysql_stats.php --host $HOST --items gg --port $PORT"

 

16修改為:

 

將 CACHEFILE="/tmp/$HOST-mysql_cacti_stats.txt”

修改為

if [ $PORT == 3306 ];then

         CACHEFILE="/tmp/$HOST-mysql_cacti_stats.txt"

else

       CACHEFILE="/tmp/$HOST-mysql_cacti_stats.txt":$PORT

fi

 

如下2修改為 加入-P$PORT

 

RES=`HOME=~zabbix /db/mysql/app/mysql/bin/mysql  -uuser-pdbmonoprommo11 -P$PORT -e 'SHOW SLAVE STATUS\G' 2>/dev/null | egrep '(Slave_IO_Running|Slave_SQL_Running):' | grep -i yes|wc -l`

 

 

 RES1=`HOME=~zabbix /db/mysql/app/mysql/bin/mysql  -uuser-pdbmonoprommo11 -P$PORT -e 'SHOW SLAVE STATUS\G' 2>/dev/null | egrep '(Slave_IO_Running|Slave_SQL_Running):' | awk -F: '{print $2}' | tr '\n' ','`

 

1.2 用戶授權

 

(如下4個授權grant 命令都需要執行,一台服務器多個實例 監控 需要允許 監控賬號遠程登陸)

> GRANT PROCESS,SUPER,REPLICATION CLIENT ON *.* TO zabbix@'localhost' IDENTIFIED BY '123456';

> grant all privileges on *.* to zabbix@localhost;

> flush privileges;

> grant all privileges  on *.* to zabbix@'%' identified by "123456";

 

> grant PROCESS,SUPER,REPLICATION CLIENT  on *.* to zabbix@'%' identified by "123456";

 

> flush privileges;

 

--查詢權限:

> select user,host from mysql.user;

>SELECT Repl_slave_priv,Repl_client_priv,super_priv,host FROM mysql.USER WHERE USER='zabbix ';

> quit;

 

 

 

測試5.1

 

(使用如下帶IP,端口,用戶名,密碼的登陸方式必須成功 )

 mysql -uroot –p123456 -h10.241.1.1 –P3307

mysql -uroot -p123456 -h10.241.1.1 -P3306

 

測試5.2

(3306 和3307 分別對應着一台主機多個mysql 對外提供服務的 端口號,具體以實際為主,如下命令應該有數字返就是正常),

 

sh get_mysql_stats_wrapper.sh  gg  3306

 

sh get_mysql_stats_wrapper.sh  gg  3307

 

如果返回值為空的話,使用-x 進行調試:

sh –x get_mysql_stats_wrapper.sh  gg  3306

 

 

2. zabbix  自動發現腳本文件mysql_low_discovery.sh  

 

2.1  cp mysql_low_discovery.sh   /var/lib/zabbix/percona/scripts/

chmod 755  /var/lib/zabbix/percona/scripts/*

 

 

2.2

(Use root) 注意:由於此處使用了 sudo ,所以要把zabbix用戶加上sudo權限,且只能執行 ss命令

echo 'zabbix ALL=(ALL) NOPASSWD:/usr/sbin/ss'>>/etc/sudoers

echo 'zabbix ALL=(ALL) NOPASSWD:/bin/netstat'>>/etc/sudoers

 

 

3.修改ss_get_mysql_stats.php腳本

 

<=====端口和socket要改為NULL

 

$mysql_port = NULL;

$mysql_socket = NULL;

 

 

測試5.3

 

以下2條命令應該返回 數值

 

php -q /var/lib/zabbix/percona/scripts/ss_get_mysql_stats.php  --host 10.241.1.1 --items gg --port 3306

 

php -q /var/lib/zabbix/percona/scripts/ss_get_mysql_stats.php  --host 10.241.1.1 --items gg --port 3307

 

 

4.修改userparameter_percona_mysql.conf 配置文件

 

4.1 把每行中的逗號',' 替換為[*],

sed -in 's#,#[*],#g' userparameter_percona_mysql.conf

 

4.2 在每行后面添加 $1

sed -in 's#$# $1#g' userparameter_percona_mysql.conf

 

4.3 最后在 首行添加端口自動發現腳本 (以下為一行)

sed -in '1i UserParameter=MySQL.discovery,/bin/bash /var/lib/zabbix/percona/scripts/mysql_low_discovery.sh' userparameter_percona_mysql.conf

 

驗證結果如下:

cat userparameter_percona_mysql.conf

 

 

 

 

測試6zabbix 用戶下執行mysql_low_discovery.sh 

 

返回結果應該如下端口號,那就是正常:

 

 

 

測試7

(該測試是在zabbix  server上做,等待5分鍾,進行測試,返回結果應該出現 端口號 就是正確)

cd /usr/local/zabbix/bin/

->Server:

./zabbix_get -s 10.241.1.1 -k MySQL.discovery

 

 

 

Issue

有的時候,在 主機監控 ,自動發現里 的 percona 多實例會報錯 監控出現 unsupported key 報錯

 

 

解決方法:

1.確認4.3 已經做,並且測試7 通過

 

2.然后重啟zabbix  agent

pkill zabbix

/usr/local/zabbix/sbin/*

 

3.一般10分鍾,zabbix 才會重新檢測 unsupported key 的定義

(實際情況,過了將近20分鍾,unsupported key的報錯才會取消)

 

->  Administration/General/通過右上角下拉框選擇不同的項目完成相關配置和管理。

->  如下圖2-36所示。

 

 

 

 

 

5.導入模板

 

5.1 Zabbix 管理網頁 模板 導入功能  (Mysql_Multiport.xml)

 

 

確認是否導入成功

 

1.顯示已成功導入

 

 

2. 自動發現規則如下

   注意: 所有的監控項目 都在自動發現規則 下

 

 

 

5.2 將主機 鏈接到這個新模板

 

Mysql_Multiport

 

注意:如果原有的主機已經添加了mysql 單機監控模板,

 

需要在網頁端 刪除掉原來的主機。 在重新添加 新加的監控模板(template/percona multiport template) 即可

 

 

 

 

 

 

ISSUE

2、導入模板

標簽無效 "/zabbix_export/date": "YYYY-MM-DDThh:mm:ssZ" 預計。

 

解決辦法

將zabbix_agent_template_percona_mysql_server_ht_2.0.9-sver1.1.7.xml導入zabbix2.4中再導出。之后將新的導出xml導入到3.2中問題解決。

或者使用

zbx_percona_mysql_template_v1導入

 

權限問題

Received value [rm: 無法刪除"/tmp/localhost-mysql_cacti_stats.txt": 不允許的操作0] is not suitable for value type [Numeric (float)]

 

 

解決辦法

cd /tmp

chown -R zabbix.zabbix localhost-mysql_cacti_stats.txt 

 

/etc/init.d/zabbix-agent restart

或者

pkill zabbix

/usr/local/zabbix/sbin/*

 

 

3.添加監控項目

 

->Agent:

cd /usr/local/zabbix/bin/

(More /usr/local/zabbix/etc/zabbix_agentd.conf.d/userparameter_percona_mysql.conf

(這里是支持擴展的腳本位置)

Useparameter=Mysql.rows-updated,****/get_mysql_stats_wrapper.sh ix  )

->Server:

./zabbix_get -s 10.241.1.1 -k MySQL.rows-updated

 

 

( below it from agent /usr/local/zabbix/bin/chk_mysql.sh)

->server

 

./zabbix_get -s 10.241.1.1 -k mysql.status[com_rollback]

 

 

 

 

 

 

---------------------

作者:思考v

來源:CSDN

原文:https://blog.csdn.net/xiegh2014/article/details/72859982

版權聲明:本文為博主原創文章,轉載請附上博文鏈接!

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM