溫馨提示×

溫馨提示×

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

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

CPU分析BPF工具有哪些?

發(fā)布時間:2020-05-25 14:17:54 來源:億速云 閱讀:315 作者:鴿子 欄目:系統(tǒng)運維

可用于CPU分析的BPF工具,見下圖標注的這些命令

CPU分析BPF工具有哪些?


下表的這些工具有些是屬于BCC或者bpftrace,或為這本書創(chuàng)建的。一些工具同時出現(xiàn)在BCCbpftrace中。下表出了本節(jié)介紹的工具的來源(BTbpftrace的縮寫。)

 

Tool

工具名稱

Source

來源

Target

功效/目標

Description

描述

execsnoop

BCC/BT

Sched

Lists new   process execution

列出新進程的執(zhí)行

exitsnoop

BCC

Sched

Shows process   lifespan and exit reason

顯示進程壽命和退出原因

runqlat

BCC/BT

Sched

Summarizes CPU   run queue latency

總結(jié)CPU運行隊列延遲情況

runqlen

BCC/BT

Sched

Summarizes CPU   run queue length

總結(jié)CPU運行隊列長度

runqslower

BCC

Sched

Prints run   queue waits slower than a threshold

打印等待時間慢于閾值的運行隊列(單位us)

cpudist

BCC

Sched

Summarizes   on-CPU time

匯總on-CPU的時間

cpufreq

Book

CPUs

Samples CPU   frequency by process

按進程采樣CPU頻率

profile

BCC

CPUs

Samples CPU   stack traces

采樣CPU堆棧跟蹤

offcputime

BCC/book

Sched

Summarizes   off-CPU stack traces and times

匯總off-CPU堆棧跟蹤和時間

syscount

BCC/BT

Syscalls

Counts system   calls by type and process

按類型和過程統(tǒng)計syscall系統(tǒng)調(diào)用

argdist

BCC

Syscalls

Can be used   for syscall analysis

可以用于系統(tǒng)調(diào)用分析

trace

BCC

Syscalls

Can be used   for syscall analysis

可以用于系統(tǒng)調(diào)用分析

funccount

BCC

Software

Counts   function calls

計算函數(shù)調(diào)用

softirqs

BCC

Interrupts

Summarizes   soft interrupt time

匯總軟中斷時間

hardirqs

BCC

Interrupts

Summarizes   hard interrupt time

匯總硬中斷時間

smpcalls

Book

Kernel

Times SMP   remote CPU calls

統(tǒng)計SMP遠程CPU調(diào)用的時間

llcstat

BCC

PMCs

Summarizes LLC   hit ratio by process

按進程匯總LLC命中率




execsnoop

通過exec() syscall 系統(tǒng)調(diào)用來跟蹤新進程。

可以發(fā)現(xiàn)消耗CPU資源的短暫進程的問題,還可以用于調(diào)試軟件的執(zhí)行,包括應(yīng)用程序啟動腳本。

該工具捕獲了用戶使用SSH登錄系統(tǒng)并啟動了包括sshdgroups、mesg在內(nèi)的進程的瞬間。它還顯示了來自系統(tǒng)活動記錄器sar的過程,包括將指標寫入其日志,包括sa1sadc。

 

我們可以使用execsnoop查找消耗資源的高速率的短期進程,通常它們可能運行時間很短很難通過top之類的來發(fā)現(xiàn),但是使用execsnoop很容易發(fā)現(xiàn)它。

execsnoop已用于調(diào)試許多生產(chǎn)問題,例如:來自后臺作業(yè)的干擾,應(yīng)用程序啟動緩慢或失敗,容器啟動緩慢或失敗,等等。

 

execsnoop的工作原理:

跟蹤execve系統(tǒng)調(diào)用(常用的exec(2)變體),并顯示execve(2)參數(shù)和返回值的詳細信息。這將捕獲遵循fork(2)/clone(2)-> exec(2)順序的新進程,以及 re-exec(2)的進程。

 

有個特殊情況:一些應(yīng)用程序在不調(diào)用exec(2)的情況下創(chuàng)建新進程,例如,在使用fork(2)或單獨克隆(2)創(chuàng)建工作進程池時。因為它們不調(diào)用execve(2),所以execsnoop輸出中不包括這些。這種情況應(yīng)該不常見:應(yīng)用程序應(yīng)該創(chuàng)建工作線程池,而不是進程。 【舉例子: 我們登錄到redis-cli后再執(zhí)行的其它的命令,execsnoop就無法抓取到】

 

由于進程執(zhí)行速率預(yù)計相對較低(<1000/),因此該工具的開銷可以忽略不計。

 

這里再介紹一個來自Netflix的一個真實問題,我使用execnoop進行了調(diào)試。這發(fā)生在一個用于微基準測試的服務(wù)器上,但是基準測試結(jié)果顯示出太多的差異是不可信任的。當(dāng)系統(tǒng)被認為是空閑的時候,我運行了execnoop,發(fā)現(xiàn)它不是!這些程序每啟動一秒鐘,就會擾亂我們的基準。結(jié)果發(fā)現(xiàn),這是一個配置錯誤的服務(wù),它試圖每秒鐘啟動一次,失敗,然后重新啟動。一旦服務(wù)被停用,這些進程就停止了(正如使用execnoop所確認的那樣),然后基準數(shù)就變得一致了。

 

 

 

?  execsnoop --help

usage: execsnoop [-h] [-T] [-t] [-x] [-q] [-n NAME] [-l LINE]

                 [--max-args MAX_ARGS]

 

Trace exec() syscalls

 

optional arguments:

  -h, --help            show this help message and exit

  -T, --time            include time column on output (HH:MM:SS)

  -t, --timestamp       include timestamp on output

  -x, --fails           include failed exec()s

  -q, --quote           Add quotemarks (") around arguments.

  -n NAME, --name NAME  only print commands matching this name (regex), any arg

  -l LINE, --line LINE  only print commands where arg contains this line (regex)

  --max-args MAX_ARGS   maximum number of arguments parsed and displayed,defaults to 20

 

examples:

    ./execsnoop           # trace all exec() syscalls

    ./execsnoop -x        # include failed exec()s

    ./execsnoop -T        # include time (HH:MM:SS)

    ./execsnoop -t        # include timestamps

    ./execsnoop -q        # add "quotemarks" around arguments

    ./execsnoop -n main   # only print command lines containing "main"

    ./execsnoop -l tpkg   # only print command where arguments contains "tpkg"

 

 

exitsnoop

exitsnoop是一個BCC工具,可跟蹤進程退出的時間,顯示進程的使用期限和退出原因。期限是從進程創(chuàng)建到終止的時間,并且包括CPU的開啟和關(guān)閉時間。

execsnoop一樣,exitsnoop可以幫助調(diào)試短期進程的問題,并提供不同的信息來幫助理解此類工作負載。例如:

 

CPU分析BPF工具有哪些?

 

此輸出顯示退出了許多短期進程,例如cmakeshmake,這表明一個軟件版本正在運行。1.00秒后,sleep進程成功退出(退出代碼0),而由于KILL信號,另一個sleep進程在7.31秒后退出。這也捕獲了221.25秒后退出的“ DOM Worker”線程。

 

該工具通過檢測 sched:sched_process_exit 跟蹤點及其參數(shù)來工作,并且還使用bpf_get_current_task(),以便可以從任務(wù)結(jié)構(gòu)中讀取開始時間(不穩(wěn)定的接口詳細信息)。由于此跟蹤點很少觸發(fā),因此該工具的開銷可以忽略不計。

 

本人的實戰(zhàn)截圖:

CPU分析BPF工具有哪些?



runqlat

runqlat是一個BCCbpftrace工具,用于測量CPU調(diào)度程序延遲,通常稱為運行隊列延遲(即使不再使用運行隊列實現(xiàn))。這對于識別和量化CPU飽和問題很有用,在CPU飽和問題中,對CPU資源的需求超出了服務(wù)能力。runqlat度量的指標是每個線程(任務(wù))等待其打開CPU所花費的時間。

 

下圖顯示了在48CPU生產(chǎn)API實例上運行的BCC runqlat在系統(tǒng)范圍內(nèi)的CPU利用率約為42(可以用top命令查看到CPU的利用率)。runqlat的參數(shù)為10 1,表示以設(shè)置10秒間隔,僅輸出一次:

CPU分析BPF工具有哪些?

此輸出表明,在大多數(shù)情況下,線程等待的時間少于15微秒,直方圖中的模式介于215微秒之間。這是相對較快的(健康系統(tǒng)的一個示例),并且對于運行在42CPU利用率上的系統(tǒng)來說是預(yù)期的。在此示例中,有時運行隊列延遲高達816毫秒存儲桶,但這些異常值是異常的。

 

runqlat的原理:

通過檢測調(diào)度程序喚醒和上下文切換事件來確定從喚醒到運行的時間。注意: 這些事件在繁忙的生產(chǎn)系統(tǒng)上可能非常頻繁,每秒超過一百萬個事件。即使對BPF進行了優(yōu)化,以這些速率,即使每個事件增加一微秒也會導(dǎo)致明顯的開銷。需要小心使用runqlat這個工具。

示例:如果您在一個10核的系統(tǒng)上的上下文切換速率為1M/sec,則每個上下文切換增加1微秒將消耗10%的CPU資源(計算方法: 100×(1×1000000/10×1000000) )。有關(guān)BPF開銷的一些實際測量值,請參見第18章,每個事件通常小于一微秒。

一個使用runqlat診斷案例

在一個36CPU的構(gòu)建服務(wù)器進行軟件構(gòu)建操作,其中并行作業(yè)的數(shù)量被錯誤地設(shè)置為72,從而導(dǎo)致CPU超載。觀測到的截圖如下:

CPU分析BPF工具有哪些?

現(xiàn)在的分布是三模態(tài),最慢的模式以816毫秒的桶為中心.這顯示了線程的大量等待(小于15微秒內(nèi)算健康指標)。

CPU分析BPF工具有哪些?

可以直接從其他工具和指標中識別出此特定問題。例如,sar可以顯示CPU利用率(-u)和運行隊列指標(-q)

CPU分析BPF工具有哪些?

可以看到,當(dāng)前系統(tǒng) CPU idle空閑為0, 全負荷工作。 另外, runq-sz平均運行隊列大小為72(包括正在運行和可運行),也大幅超過了可用的36CPU。



runqlen

runqlen是一個BCCbpftrace工具,用于對CPU運行隊列的長度進行采樣,計算有多少任務(wù)在等待輪到他們,并將其顯示為線性直方圖。這可以用來進一步描述運行隊列延遲的問題或作為更便宜的近似值。

 

下圖顯示了在48CPU生產(chǎn)API實例上運行的BCCrunqlet,該實例在系統(tǒng)范圍內(nèi)的CPU利用率約為42(與先前在runqlat中顯示的實例相同)runqlen的參數(shù)為 10 1,以設(shè)置10秒間隔,僅輸出一次:

CPU分析BPF工具有哪些?

這表明在大多數(shù)情況下,運行隊列長度為零,這意味著線程無需等待輪到他們。

 

我將運行隊列長度描述為輔助性能指標,將運行隊列延遲描述為主要性能。與長度不同,延遲會直接和成比例地影響性能。想象一下在雜貨店加入結(jié)帳行。對您來說更重要的是:線路的長度或您實際花費的等待時間?runqlat更重要。那么,為什么要使用runqlen?

 

首先,可以使用runqlen進一步描述在runqlat中發(fā)現(xiàn)的問題,并解釋延遲如何變高。其次,runqlen采用99赫茲的定時采樣,而runqlat跟蹤調(diào)度程序事件。與runqlat的調(diào)度程序跟蹤相比,此定時采樣的開銷可忽略不計。對于24x7全天候監(jiān)控,最好先使用runqlen來識別問題(因為運行起來更便宜),然后再使用runqlat臨時量化延遲。


四線程,一個CPU的一個示例:

在此示例中,將四個繁忙線程的CPU工作負載綁定到CPU0。執(zhí)行runqlen -C以顯示每個CPU的直方圖:

CPU分析BPF工具有哪些?

CPU 0上的運行隊列長度為三個:一個線程在CPU上等待三個線程。此每個CPU的輸出對于檢查調(diào)度程序平衡非常有用。

 

 

小實驗:

我們執(zhí)行5次這個單行命令taskset -c 0 sh -c 'while :; do :; done' & ,這個循環(huán)操作綁定在cpu0上運行,然后執(zhí)行 runqlen可以看到如下結(jié)果,明顯可以看到cpu0上有很多運行隊列的堆積,而cpu1上堆積基本都是0。

CPU分析BPF工具有哪些?



runqslower

runqslower是一個BCC工具,它列出了運行隊列等待時間超過可配置閾值的實例,并顯示了遭受等待時間及其持續(xù)時間的過程

 

以下示例來自當(dāng)前在系統(tǒng)范圍內(nèi)以45CPU利用率運行的48 CPU生產(chǎn)API實例:

CPU分析BPF工具有哪些?


此輸出表明,在13秒的時間內(nèi),   10個運行隊列等待時間超過默認閾值10000微秒(10毫秒)的情況。對于具有55%空閑CPU余量的服務(wù)器來說,這似乎令人驚訝,但這是一個繁忙的多線程應(yīng)用程序,在調(diào)度程序可以將線程遷移到空閑CPU之前,運行隊列可能不平衡。該工具可以確認受影響的應(yīng)用程序。

 

該工具當(dāng)前通過將kprobes用于內(nèi)核函數(shù)ttwu_do_wakeup(),wake_up_new_task()finish_task_switch() 來工作。將來的版本應(yīng)使用類似于runqlatbpftrace版本的代碼切換到調(diào)度程序跟蹤點。開銷與runqlat相似;由于kprobes的成本,即使在runqslower不輸出任何輸出的情況下,它也會在繁忙的系統(tǒng)上引起明顯的開銷。



cpudist

cpudist是一個BCC工具,用于顯示每個線程喚醒的CPU時間分布。這可用于幫助表征CPU工作負載,為以后的調(diào)整和設(shè)計決策提供詳細信息。

例如,從一個48 CPU生產(chǎn)實例中:

CPU分析BPF工具有哪些?

此輸出表明生產(chǎn)應(yīng)用程序通常僅在CPU上花費很短的時間:從0127微秒。

 

下面的圖,這是一個CPU繁重的工作負載,具有比可用CPU更多的繁忙線程,并且具有以毫秒(-m)為單位的直方圖:

CPU分析BPF工具有哪些?

現(xiàn)在有一種CPU持續(xù)時間從415毫秒的模式:這很可能是線程耗盡了調(diào)度程序的時間量,然后遇到了非自愿的上下文切換。

 

該工具用于幫助了解Netflix的生產(chǎn)變化,其中機器學(xué)習(xí)應(yīng)用程序開始運行的速度快了三倍。perf命令用于顯示上下文切換速率已降低,而cpudist用于解釋其影響:應(yīng)用程序現(xiàn)在通常在上下文切換之間運行兩到四毫秒,而更早的時候只能在03微秒之間運行,然后再被上下文切換中斷。

 

注意:

cpudist通過跟蹤調(diào)度程序上下文切換事件來工作,該事件在繁忙的生產(chǎn)工作負載上非常頻繁(超過一百萬個事件/)。與runqlat一樣,此工具的開銷可能很大,因此請謹慎使用。


root@dba-test:~|?  cpudist --help

usage: cpudist [-h] [-O] [-T] [-m] [-P] [-L] [-p PID] [interval] [count]

 

Summarize on-CPU time per task as a histogram.

 

positional arguments:

  interval            output interval, in seconds

  count               number of outputs

 

optional arguments:

  -h, --help          show this help message and exit

  -O, --offcpu        measure off-CPU time   # 只顯示CPU以外的時間,而不是CPU上的時間

  -T, --timestamp     include timestamp on output

  -m, --milliseconds  millisecond histogram

  -P, --pids          print a histogram per process ID  # 每個進程打印一個直方圖

  -L, --tids          print a histogram per thread ID

  -p PID, --pid PID   trace this PID only

 

examples:

    cpudist              # summarize on-CPU time as a histogram

    cpudist -O           # summarize off-CPU time as a histogram

    cpudist 1 10         # print 1 second summaries, 10 times

    cpudist -mT 1        # 1s summaries, milliseconds, and timestamps

    cpudist -P           # show each PID separately

    cpudist -p 185       # trace PID 185 only



cpufreq

這是個bpftrace腳本文件,不在BCC工具集內(nèi)。 個人認為只要大致了解下這個命令即可。

 

cpufreqCPU頻率進行采樣,并將其顯示為系統(tǒng)范圍的直方圖,并帶有每個進程的名稱直方圖。這僅適用于更改頻率的CPU縮放調(diào)節(jié)器,例如節(jié)電,并可用于確定應(yīng)用程序運行的時鐘速度。



profile

profile是一個BCC工具,它以一定的時間間隔對堆棧跟蹤進行采樣,并報告堆棧跟蹤的頻率計數(shù)。這是BCC中了解CPU消耗的最有用的工具,因為它總結(jié)了消耗CPU資源的幾乎所有代碼路徑。由于事件率固定為可以調(diào)整的采樣率,因此它也可以以相對可忽略的開銷使用。

根據(jù)profile的結(jié)果,我們可以繪制火焰圖

$ profile -af 30 > out.stacks01

$ git clone https://github.com/brendangregg/FlameGraph

$ cd FlameGraph

$ ./flamegraph.pl --color=java < ../out.stacks01 > out.svg

然后即可輸出一幅火焰圖。


使profile與其他CPU探查器不同的原因在于,為了提高效率,此頻率計數(shù)是在內(nèi)核空間中計算的。其他基于內(nèi)核的探查器,例如perf,會將每個采樣的堆棧跟蹤發(fā)送到用戶空間,在該用戶跟蹤中將其后處理為摘要。這可能會占用大量CPU資源,并且取決于調(diào)用,它還可能涉及文件系統(tǒng)和磁盤I/O來記錄樣本。profile避免了這些費用。

root@dba-test:~|? profile --help

usage: profile [-h] [-p PID | -L TID] [-U | -K] [-F FREQUENCY | -c COUNT] [-d]

               [-a] [-I] [-f] [--stack-storage-size STACK_STORAGE_SIZE]

               [-C CPU]

               [duration]

 

Profile CPU stack traces at a timed interval

 

positional arguments:

  duration              duration of trace, in seconds

 

optional arguments:

  -h, --help            show this help message and exit

  -p PID, --pid PID     profile process with this PID only

  -L TID, --tid TID     profile thread with this TID only

  -U, --user-stacks-only    show stacks from user space only (no kernel space stacks)

  -K, --kernel-stacks-only   show stacks from kernel space only (no user space stacks)

  -F FREQUENCY, --frequency FREQUENCY     sample frequency, Hertz

  -c COUNT, --count COUNT  sample period, number of events

  -d, --delimited       insert delimiter between kernel/user stacks

  -a, --annotations     add _[k] annotations to kernel frames

  -I, --include-idle    include CPU idle stacks

  -f, --folded          output folded format, one line per stack (for flame graphs)

  --stack-storage-size STACK_STORAGE_SIZE

                        the number of unique stack traces that can be stored and displayed (default 16384)

  -C CPU, --cpu CPU     cpu number to run profile on

 

examples:

    ./profile             # profile stack traces at 49 Hertz until Ctrl-C

    ./profile -F 99       # profile stack traces at 99 Hertz

    ./profile -c 1000000  # profile stack traces every 1 in a million events

    ./profile 5           # profile at 49 Hertz for 5 seconds only

    ./profile -f 5        # output in folded format for flame graphs

    ./profile -p 185      # only profile process with PID 185

    ./profile -L 185      # only profile thread with TID 185

    ./profile -U          # only show user space stacks (no kernel)

    ./profile -K          # only show kernel space stacks (no user)




offcputime

offcputime是一個BCCbpftrace工具,用于總結(jié)阻塞線程和關(guān)閉CPU所花費的時間,并顯示堆棧跟蹤信息以說明原因

對于CPU分析,此工具說明了為什么線程未在CPU上運行。

profile對應(yīng);在它們之間,它們顯示了線程在系統(tǒng)上花費的全部時間:使用profileCPU時間和使用offcputimeCPU時間。


offcputime已用于查找各種生產(chǎn)問題,包括查找在鎖獲取中阻塞的意外時間以及負責(zé)的堆棧跟蹤。


注意:

offcputime通過檢測上下文切換并記錄從線程離開CPU到返回CPU的時間以及堆棧跟蹤來工作。為了提高效率,在內(nèi)核上下文中對時間和堆棧跟蹤進行了頻率計數(shù)。但是,上下文切換事件可能會非常頻繁,并且對于繁忙的生產(chǎn)工作負載,此工具的開銷可能會變得非常大(例如,> 10)。該工具最好只在短時間內(nèi)運行,以最大程度地減少生產(chǎn)影響。


offCPU time火焰圖

profile一樣,offcputime的輸出可能非常冗長,以至于您可以發(fā)現(xiàn)最好將它作為火焰圖進行檢查。可以將offcputime可視化為非CPU時間火焰圖。

 

相關(guān)繪圖的命令如下:

# offcputime -fKu 5 > out.offcputime01.txt

$ flamegraph.pl --hash --bgcolors=blue --title="Off-CPU Time Flame Graph" < out.offcputime01.txt > out.offcputime01.svg




funccount

funccount是一種BCC工具,可以對函數(shù)和其他事件進行頻率計數(shù)。

它可用于為軟件CPU使用情況提供更多上下文,顯示調(diào)用哪些函數(shù)以及調(diào)用頻率。profile可能能夠顯示某個功能在CPU上很熱,但無法解釋為什么:該功能是否運行緩慢,或者每秒是否被簡單調(diào)用了數(shù)百萬次。

 

TIPSprofile不能輕易解釋這一點。包括profile在內(nèi)的探查器對CPU指令指針進行采樣,因此與該函數(shù)的反匯編進行比較可能會顯示該函數(shù)是卡在循環(huán)中還是被調(diào)用多次。

 

例如,通過匹配以 tcp_ 開頭的功能,可以對繁忙的生產(chǎn)實例上的內(nèi)核TCP功能進行頻率計數(shù):

CPU分析BPF工具有哪些?

可以使用-i 1 使其每1秒輸出一次。例如,較早的profile輸出顯示函數(shù)get_page_from_freelist()CPU上很熱。是因為它經(jīng)常被調(diào)用還是因為它運行緩慢?可以用如下命令來測量其每秒速率:

CPU分析BPF工具有哪些?

這通過使用函數(shù)的動態(tài)跟蹤來進行:內(nèi)核函數(shù)使用kprobes,用戶級函數(shù)使用uprob。此工具的開銷與功能的速率有關(guān)。某些函數(shù)(例如malloc() get_page_from_freelist() )往往會頻繁發(fā)生,因此對其進行跟蹤可能會大大降低目標應(yīng)用程序的速度,超過10%,請謹慎使用。


softirqs

softirqs是一個BCC工具,它顯示了花費在soft IRQ(軟中斷)所花費的時間。

可以通過不同的工具輕松獲得系統(tǒng)范圍的軟中斷時間。例如,mpstat將其顯示為%soft。也有 /proc/softirqs 顯示軟IRQ事件的計數(shù)。

BCC softirqs工具的不同之處在于,它可以顯示每個軟IRQ的時間,而不是事件計數(shù)。

 

例如,從一個48 CPU生產(chǎn)實例和一個10秒的跟蹤中:

CPU分析BPF工具有哪些?

此輸出顯示,花費在net_rx花費的時間最多,總計1358毫秒。這很重要,因為在該48 CPU系統(tǒng)上,它占CPU時間的3%。

 

softirqs通過使用irq:softirq_enterirq:softirq_exit跟蹤點來工作。該工具的開銷與事件發(fā)生率有關(guān),這對于繁忙的生產(chǎn)系統(tǒng)和較高的網(wǎng)絡(luò)數(shù)據(jù)包發(fā)生率可能會很高。謹慎使用并檢查開銷。


hardirqs

hardirqs是一個BCC工具,它顯示了花費在hard IRQ(硬中斷)所花費的時間。

硬中斷中的系統(tǒng)級時間可以從其他工具輕松獲得。例如,mpstat將其顯示為%irq。也有 /proc/interrupts 顯示hard IRQ事件的計數(shù)。

 

BCC hardirqs工具的不同之處在于,它可以顯示每個硬IRQ的時間,而不是事件計數(shù)。

下面是mpstat -P ALL 1 的部分截圖(這臺ecs的負載很低)

CPU分析BPF工具有哪些?


hardirqs可以提供CPU分析器不可見的CPU使用情況信息。有關(guān)缺少硬件PMU的云實例的性能分析,請參見第6.2.4節(jié)的內(nèi)部部分。

CPU分析BPF工具有哪些?



向AI問一下細節(jié)

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

AI