網絡情況


網絡帶寬的單位bps,b表示的bit,一個Byte=8bit。一般常說的10M帶寬,10Mbps=10/8=1.25MBps(Byte)

Mps是每秒傳輸的兆比特位數,是速度單位。MBps,指每秒傳輸多少兆字節,Mbps=Mbit/s即兆比特每秒。

千兆網卡以太網理論上的限制是 128MB。這個數字從何而來?看看這些計算:

1Gb = 1024Mb;1024Mb/8 = 128MB;"b" = "bits,"、"B" = "bytes"

 

千兆帶寬,都是全雙工的,即上行(上傳)與下行(下載)都是千兆,理論都為128MB/s,但是網絡都有損耗,按20%損耗實際帶寬會是100MB/s。

 

一、環境檢查

linux下網卡相關檢查

1、先用ifconfig看看有多少塊網卡和bonding。bonding是個很棒的東西,可以把多塊網卡綁起來,突破單塊網卡的帶寬限制。

2、檢查每塊網卡的速度,比如"ethtool eth0"。再檢查bonding,比如"cat /proc/net/bonding/bond0", 留意其Bonding Mode是負載均衡的,再留意其捆綁的網卡的速度。

3、查看網卡是否支持多隊列,是否打開了多隊列,最后確認每個隊列是否綁定到不同的CPU。

4、最后檢查測試客戶機與服務機之間的帶寬,先簡單ping或traceroute 一下得到RTT時間,iperf之類的可稍后。

 

網卡模式

當主機有1個以上的網卡時,Linux會將多個網卡綁定為一個虛擬的bonded網絡接口,對TCP/IP而言只存在一個bonded網卡。多網卡綁定一方面能夠提高網絡吞吐量,另一方面也可以增強網絡高可用。

可以通過cat/proc/net/bonding/bond0查看本機的Bonding模式

一般很少需要開發去設置網卡Bonding模式。Linux支持7種Bonding模式(詳細的看內核):

  • Mode 0(balance-rr) Round-robin策略,這個模式具備負載均衡和容錯能力

  • Mode 1(active-backup) 主備策略,在綁定中只有一個網卡被激活,其他處於備份狀態

  • Mode 2(balance-xor) XOR策略,通過源MAC地址與目的MAC地址做異或操作選擇slave網卡

  • Mode 3 (broadcast) 廣播,在所有的網卡上傳送所有的報文

  • Mode 4 (802.3ad) IEEE 802.3ad動態鏈路聚合。創建共享相同的速率和雙工模式的聚合組

  • Mode 5 (balance-tlb) Adaptive transmit loadbalancing

  • Mode 6 (balance-alb) Adaptive loadbalancing

 

查看機器網卡速度

windows

打開"網絡和共享中心"->選擇網絡,查看網絡連接狀態。如下圖所示:

11Mbps

 

linux

使用查詢及設置網卡參數的命令ethtool(http://man.linuxde.net/ethtool)查看,如使用ethtool eth1

# ethtool eth1
   Settings for eth1:
        Supported ports: [ TP ]
        Supported link modes:   10baseT/Half 10baseT/Full 
                                100baseT/Half 100baseT/Full 
                                1000baseT/Full 
        Supports auto-negotiation: Yes
        Advertised link modes: 10baseT/Half 10baseT/Full 
                                100baseT/Half 100baseT/Full 
                                1000baseT/Full 
        Advertised auto-negotiation: Yes
        Speed: 1000Mb/s
        Duplex: Full
        Port: Twisted Pair
        PHYAD: 0
        Transceiver: internal
        Auto-negotiation: on
        Supports Wake-on: umbg
        Wake-on: d
        Link detected: yes

操作完畢后,輸出信息中Speed:這一項就指示了網卡的速度。

 

網卡多隊列及中斷綁定

隨着網絡的帶寬的不斷提升,單核CPU已經不能滿足網卡的需求,這時通過多隊列網卡驅動的支持,可以將每個隊列通過中斷綁定到不同的CPU核上,充分利用多核提升數據包的處理能力。

1)查看網卡是否支持多隊列

使用lspci  -vvv命令,找到Ethernetcontroller項:

 

如果有MSI-X, Enable+ 並且Count > 1,則該網卡是多隊列網卡。網卡的中斷機制是MSI-X,即網卡的每個隊列都可以分配中斷(MSI-X支持2048個中斷)。

備注:linux 2.6.32 上有lspci命令,但無-vvv參數。

2)查看是否打開了網卡多隊列。

使用命令cat/proc/interrupts,如果看到eth0-TxRx-0表明多隊列支持已經打開:

 

  • /proc/interrupts:該文件存放了每個I/O設備的對應中斷號、每個CPU的中斷數、中斷類型。
  • /proc/irq/:該目錄下存放的是以IRQ號命名的目錄,如/proc/irq/40/,表示中斷號為40的相關信息
  • /proc/irq/[irq_num]/smp_affinity:該文件存放的是CPU位掩碼(十六進制)。修改該文件中的值可以改變CPU和某中斷的親和性
  • /proc/irq/[irq_num]/smp_affinity_list:該文件存放的是CPU列表(十進制)。注意,CPU核心個數用表示編號從0開始,如cpu0,cpu1等
  • smp_affinity_list和smp_affinity任意更改一個文件都會生效,兩個文件相互影響,只不過是表示方法不一致,但一般都是修改smp_affinity 文件

 

3)最后確認每個隊列是否綁定到不同的CPU。

cat/proc/interrupts查詢到每個隊列的中斷號,對應的文件/proc/irq/${IRQ_NUM}/smp_affinity為中斷號IRQ_NUM綁定的CPU核的情況。以十六進制表示,每一位代表一個CPU核:(00000001)代表CPU0(00000010)代表CPU1(00000011)代表CPU0和CPU1。

中斷的親緣性設置可以在 cat /proc/irq/${中斷號}/smp_affinity 或 cat /proc/irq/${中斷號}/smp_affinity_list 中確認,前者是16進制掩碼形式,后者是以CPU Core序號形式。例如下圖中,將16進制的400轉換成2進制后,為 10000000000,“1”在第10位上,表示親緣性是第10個CPU Core。

那為什么中斷號只設置一個CPU Core呢?而不是為每一個中斷號設置多個CPU Core平行處理。經過測試,發現當給中斷設置了多個CPU Core后,它也僅能由設置的第一個CPU Core來處理,其他的CPU Core並不會參與中斷處理,原因猜想是當CPU可以平行收包時,不同的核收取了同一個queue的數據包,但處理速度不一致,導致提交到IP層后的順序也不一致,這就會產生亂序的問題,由同一個核來處理可以避免了亂序問題。

 

如果綁定的不均衡,可以手工設置,例如:

echo "1" > /proc/irq/99/smp_affinity echo "2" > /proc/irq/100/smp_affinity echo "4" > /proc/irq/101/smp_affinity echo "8" > /proc/irq/102/smp_affinity echo "10" > /proc/irq/103/smp_affinity echo "20" > /proc/irq/104/smp_affinity echo "40" > /proc/irq/105/smp_affinity echo "80" > /proc/irq/106/smp_affinity

 

上述命令使用時需要注意一個是權限,一個是不同系統之間命令的差異。

理論參考:多隊列網卡CPU中斷均衡

 

 

檢查實際帶寬

可以先做ping、traceroute看下 參考資料:網絡丟包分析

 

監控帶寬命令

  • 監控總體帶寬使用――nload、bmon、slurm、bwm-ng、cbm、speedometer和netload
  • 監控總體帶寬使用(批量式輸出)――vnstat、ifstat、dstat和collectl
  • 每個套接字連接的帶寬使用――iftop、iptraf、tcptrack、pktstat、netwatch和trafshow
  • 每個進程的帶寬使用――nethogs

 

Linux服務器網絡帶寬測試——iperf 

工具下載地址

可以在系統不繁忙或者臨時下線前檢測客戶端和server或者proxy 的帶寬:

1)使用 iperf -s 命令將 Iperf 啟動為 server 模式:

iperf –s
————————————————————
Server listening on TCP port 5001
TCP window size: 8.00 KByte (default)
————————————————————

2)啟動客戶端,向IP為10.230.48.65的主機發出TCP測試,並每2秒返回一次測試結果,以Mbytes/sec為單位顯示測試結果:

iperf -c 10.230.48.65 -f M -i 2

 

在服務端上,運行:

# iperf -s -f M

這台機器將用作服務器並以'M' = MBytes/sec為單位輸出執行速度。

在客戶端節點上,運行:

# iperf -c ginger -P 4 -f M -w 256k -t 60

兩個屏幕上的結果都指示了速度是多少。在使用千兆網卡的普通服務器上,可能會看到速度約為 112MB。這是 TCP 堆棧和物理電纜中的常用帶寬。通過以端到端的方式連接兩台服務器,每台服務器使用兩個聯結的以太網卡,獲得了約 220MB的帶寬。

 

ping命令

上邊Ping www.a.shifen.com [220.181.111.188],這里的地址是指域名對應的服務器地址。

如hosts文件里,配置 220.181.111.188 www.a.shifen.com 

 

tracert

 

查看環形緩沖區個數

它位於NIC和IP層之間,是一個典型的FIFO(先進先出)環形隊列。RingBuffer沒有包含數據本身,而是包含了指向sk_buff(socketkernel buffers)的描述符。
可以使用ethtool-g eth0查看當前RingBuffer的設置:

上面的例子接收隊列為4096,傳輸隊列為256。

 

ifconfig

ifconfig的輸出中有兩項,分別是:

RX==receive,接收,從開啟到現在接收封包的情況,是下行流量。

TX==Transmit,發送,從開啟到現在發送封包的情況,是上行流量。

 

ifconfig觀察接收和傳輸隊列的運行狀況:

[root@test etc]# ifconfig eth1
eth1      Link encap:Ethernet  HWaddr 00:26:B9:58:19:88 inet addr:192.168.0.46 Bcast:192.168.0.255 Mask:255.255.255.0 UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:6049782538 errors:0 dropped:2373 overruns:0 frame:0 TX packets:7415059121 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:2611876455455 (2.3 TiB) TX bytes:6028598337794 (5.4 TiB) Interrupt:114 Memory:d8000000-d8012800 

 

RX errors: 表示總的收包的錯誤數量,這包括 too-long-frames 錯誤,Ring Buffer 溢出錯誤,crc 校驗錯誤,幀同步錯誤,fifo overruns 以及 missed pkg 等等。

RX dropped: 表示數據包已經進入了 Ring Buffer,但是由於內存不夠等系統原因,導致在拷貝到內存的過程中被丟棄。

RX overruns: 表示了 fifo 的 overruns,這是由於 Ring Buffer(aka Driver Queue) 傳輸的 IO 大於 kernel 能夠處理的 IO 導致的,而 Ring Buffer 則是指在發起 IRQ 請求之前的那塊 buffer。很明顯,overruns 的增大意味着數據包沒到 Ring Buffer 就被網卡物理層給丟棄了,而 CPU 無法及時的處理中斷是造成 Ring Buffer 滿的原因之一,例如中斷分配的不均勻(都壓在 core0),沒有做 affinity 而造成的丟包。

RX frame: 表示 misaligned 的 frames。

當dropped數量持續增加,建議增大RingBuffer,使用ethtool-G進行設置。

對於 TX 的來說,counter 增大的原因主要包括 aborted transmission, errors due to carrirer, fifo error, heartbeat erros 以及 windown error,而 collisions 則表示由於 CSMA/CD 造成的傳輸中斷。

 

txqueuelen 1000
QDisc(queueing discipline )位於IP層和網卡的ringbuffer之間。QDisc實現了流量管理的高級功能,包括流量分類,優先級和流量整形(rate-shaping)。可以使用tc命令配置QDisc。QDisc的隊列長度由txqueuelen設置,和接收數據包的隊列長度由內核參數net.core.netdev_max_backlog控制所不同,txqueuelen是和網卡關聯。

 

RX和TX輸出的值使有的單位參數是bytes,而利用該命令,我們也可以配置腳本進行流量檢測。

大名鼎鼎的nagios就有一個插件check_traffic,通過ifconfig的輸出的RX、TX值通過之間的差,再除去中間間隔的時間算出流量大小的。該插件的下載頁為:https://github.com/cloved/check_traffic/downloads 。

現摘錄其中部分關於度量值轉換的部分如下:

#to K
uIn=`echo "$ctbpsIn / 1024" | bc` uOut=`echo "$ctbpsOut / 1024" | bc` #to M if [ "$isM" = "True" ]; then uIn=`echo "scale=$Scale; $uIn / 1024" | bc` uOut=`echo "scale=$Scale; $uOut / 1024" | bc` fi #to B if [ "$isB" = "True" ]; then uIn=`echo "scale=$Scale; $uIn / 8" | bc` uOut=`echo "scale=$Scale; $uOut / 8" | bc`

 

二、監控

關於CPU中斷的監控 

  • 動態監控CPU中斷情況,觀察中斷變化

    watch -d -n 1 ‘cat /proc/interrupts’

  • 查看網卡中斷相關信息

    cat /proc/interrupts | grep -E “eth|CPU”

  • 網卡親和性設置 

修改proc/irq/irq_number/smp_affinity之前,先停掉irq自動調節服務,不然修改的值就會被覆蓋。

 

/etc/init.d/irqbalance stop

 

通過查看網卡中斷相關信息,得到網卡中斷為19 

[root@master ~]# cd /proc/irq/19
[root@master 19]# cat smp_affinity
00000000,00000000,00000000,00000001
[root@master 19]# cat smp_affinity_list 
0

 

  • 查看某個進程的CPU親和性 
# taskset -p 30011
pid 30011's current affinity mask: ff

 

  • 設置某個進程的CPU親和性
# taskset -p 1 30011
pid 30011's current affinity mask: ff
pid 30011's new affinity mask: 1
  • 使用-c選項可以將一個進程對應到多個CPU上去
# taskset -p -c 1,3 30011
pid 30011's current affinity list: 0
pid 30011's new affinity list: 1,3


# taskset -p -c 1-7 30011
pid 30011's current affinity list: 1,3
pid 30011's new affinity list: 1-7

可執行test.sh查看smp_affinity_list中的值的變化

#!/bin/bash

irq=`grep 'eth' /proc/interrupts  | awk '{print $1}' | cut -d : -f 1`
for i in $irq
do
    num=`cat /proc/irq/$i/smp_affinity_list`
    echo /proc/irq/$i/smp_affinity_list"    "$num
done

 網卡綁定的時候最好和一個物理CPU的核挨個綁定,這樣避免L1,L2,L3踐踏。

 

使用systemtap診斷測試環境軟中斷分布的方法

global hard, soft, wq

probe irq_handler.entry {
hard[irq, dev_name]++;
}

probe timer.s(1) {
println("==irq number:dev_name")
foreach( [irq, dev_name] in hard- limit 5) {
printf("%d,%s->%d\n", irq, kernel_string(dev_name), hard[irq, dev_name]);      
}

println("==softirq cpu:h:vec:action")
foreach( [c,h,vec,action] in soft- limit 5) {
printf("%d:%x:%x:%s->%d\n", c, h, vec, symdata(action), soft[c,h,vec,action]);      
}


println("==workqueue wq_thread:work_func")
foreach( [wq_thread,work_func] in wq- limit 5) {
printf("%x:%x->%d\n", wq_thread, work_func, wq[wq_thread, work_func]); 
}

println("\n")
delete hard
delete soft
delete wq
}

probe softirq.entry {
soft[cpu(), h,vec,action]++;
}

probe workqueue.execute {
wq[wq_thread, work_func]++
}


probe begin {
println("~")
}
View Code

執行結果:

==irq number:dev_name
87,eth0-0->1693
90,eth0-3->1263
95,eth1-3->746
92,eth1-0->703
89,eth0-2->654
==softirq cpu:h:vec:action
0:ffffffff81a83098:ffffffff81a83080:0xffffffff81461a00->8928
0:ffffffff81a83088:ffffffff81a83080:0xffffffff81084940->626
0:ffffffff81a830c8:ffffffff81a83080:0xffffffff810ecd70->614
16:ffffffff81a83088:ffffffff81a83080:0xffffffff81084940->225
16:ffffffff81a830c8:ffffffff81a83080:0xffffffff810ecd70->224
==workqueue wq_thread:work_func
ffff88083062aae0:ffffffffa01c53d0->10
ffff88083062aae0:ffffffffa01ca8f0->10
ffff88083420a080:ffffffff81142160->2
ffff8808343fe040:ffffffff8127c9d0->2
ffff880834282ae0:ffffffff8133bd20->1
View Code

 

下面是action對應的符號信息:

addr2line -e /usr/lib/debug/lib/modules/2.6.32-431.20.3.el6.mt20161028.x86_64/vmlinux ffffffff81461a00 /usr/src/debug/kernel-2.6.32-431.20.3.el6/linux-2.6.32-431.20.3.el6.mt20161028.x86_64/net/core/dev.c:4013 
打開這個文件,發現它是在執行 static void net_rx_action(struct softirq_action *h)這個函數,而這個函數正是NET_RX_SOFTIRQ 對應的軟中斷處理程序。因此可以確認網卡的軟中斷在機器上分布非常不均,而且主要集中在CPU 0上。通過/proc/interrupts能確認硬中斷集中在CPU 0上,因此軟中斷也都由CPU 0處理,如何優化網卡的中斷成為了我們關注的重點。
 

參考:MYSQL數據庫網卡軟中斷不平衡問題及解決方案 

set_irq_affinity.sh
# cat set_irq_affinity.sh
 
# setting up irq affinity according to /proc/interrupts
# 2008-11-25 Robert Olsson
# 2009-02-19 updated by Jesse Brandeburg
#
# > Dave Miller:
# (To get consistent naming in /proc/interrups)
# I would suggest that people use something like:
#       char buf[IFNAMSIZ+6];
#
#       sprintf(buf, "%s-%s-%d",
#               netdev->name,
#               (RX_INTERRUPT ? "rx" : "tx"),
#               queue->index);
#
#  Assuming a device with two RX and TX queues.
#  This script will assign:
#
#       eth0-rx-0  CPU0
#       eth0-rx-1  CPU1
#       eth0-tx-0  CPU0
#       eth0-tx-1  CPU1
#
 
set_affinity()
{
        if [ $VEC -ge 32 ]
        then
                MASK_FILL=""
                MASK_ZERO="00000000"
                let "IDX = $VEC / 32"
                for ((i=1; i<=$IDX;i++))
                do
                        MASK_FILL="${MASK_FILL},${MASK_ZERO}"
                done
 
                let "VEC -= 32 * $IDX"
                MASK_TMP=$((1<<$VEC))
                MASK=`printf "%X%s" $MASK_TMP $MASK_FILL`
        else
                MASK_TMP=$((1<<(`expr $VEC + $CORE`)))
                MASK=`printf "%X" $MASK_TMP`
        fi
 
    printf "%s mask=%s for /proc/irq/%d/smp_affinity\n" $DEV $MASK $IRQ
    printf "%s" $MASK > /proc/irq/$IRQ/smp_affinity
}
 
if [ $# -ne 2 ] ; then
        echo "Description:"
        echo "    This script attempts to bind each queue of a multi-queue NIC"
        echo "    to the same numbered core, ie tx0|rx0 --> cpu0, tx1|rx1 --> cpu1"
        echo "usage:"
        echo "    $0 core eth0 [eth1 eth2 eth3]"
        exit
fi
 
CORE=$1
 
# check for irqbalance running
IRQBALANCE_ON=`ps ax | grep -v grep | grep -q irqbalance; echo $?`
if [ "$IRQBALANCE_ON" == "0" ] ; then
        echo " WARNING: irqbalance is running and will"
        echo "          likely override this script's affinitization."
        echo "          Please stop the irqbalance service and/or execute"
        echo "          'killall irqbalance'"
fi
 
#
# Set up the desired devices.
#
shift 1
 
for DEV in $*
do
  for DIR in rx tx TxRx
  do
     MAX=`grep $DEV-$DIR /proc/interrupts | wc -l`
     if [ "$MAX" == "0" ] ; then
       MAX=`egrep -i "$DEV:.*$DIR" /proc/interrupts | wc -l`
     fi
     if [ "$MAX" == "0" ] ; then
       echo no $DIR vectors found on $DEV
       continue
     fi
     for VEC in `seq 0 1 $MAX`
     do
        IRQ=`cat /proc/interrupts | grep -i $DEV-$DIR-$VEC"$"  | cut  -d:  -f1 | sed "s/ //g"`
        if [ -n  "$IRQ" ]; then
          set_affinity
        else
           IRQ=`cat /proc/interrupts | egrep -i $DEV:v$VEC-$DIR"$"  | cut  -d:  -f1 | sed "s/ //g"`
           if [ -n  "$IRQ" ]; then
             set_affinity
           fi
        fi
     done
  done
done
View Code

腳本參數是:set_irq_affinity.sh core eth0 [eth1 eth2 eth3] 可以一次設置多個網卡,core的意思是從這個號開始遞增。

#./set_irq_affinity.sh 0 em1
no rx vectors found on em1
no tx vectors found on em1
em1 mask=1 for /proc/irq/109/smp_affinity
em1 mask=2 for /proc/irq/110/smp_affinity
em1 mask=4 for /proc/irq/111/smp_affinity
em1 mask=8 for /proc/irq/112/smp_affinity
em1 mask=10 for /proc/irq/113/smp_affinity
em1 mask=20 for /proc/irq/114/smp_affinity
em1 mask=40 for /proc/irq/115/smp_affinity
em1 mask=80 for /proc/irq/116/smp_affinity
 
#./set_irq_affinity.sh 8 em2
no rx vectors found on em2
no tx vectors found on em2
em2 mask=100 for /proc/irq/118/smp_affinity
em2 mask=200 for /proc/irq/119/smp_affinity
em2 mask=400 for /proc/irq/120/smp_affinity
em2 mask=800 for /proc/irq/121/smp_affinity
em2 mask=1000 for /proc/irq/122/smp_affinity
em2 mask=2000 for /proc/irq/123/smp_affinity
em2 mask=4000 for /proc/irq/124/smp_affinity
em2 mask=8000 for /proc/irq/125/smp_affinity
View Code

 

 
        
 

 

 

 

關於網絡流量的監控 

 watch -n 1 "/sbin/ifconfig eth0|grep bytes"

查看eth0 網卡,按bytes 單位顯示,每隔1s 刷新一下
tx 發送,rx 接收
一般rx 外網指的是下載,tx 指的是上傳,內網恰恰相反

 

出現丟包問題分析思路

當驅動處理速度跟不上網卡收包速度時,驅動來不及分配緩沖區,NIC接收到的數據包無法及時寫到sk_buffer,就會產生堆積,當NIC內部緩沖區寫滿后,就會丟棄部分數據,引起丟包。這部分丟包為rx_fifo_errors,在 /proc/net/dev中體現為fifo字段增長,在ifconfig中體現為overruns指標增長。

如果網絡出現丟包,發現丟包是因為隊列中的數據包超過了 netdev_max_backlog 造成了丟棄,因此首先想到是臨時調大netdev_max_backlog能否解決燃眉之急,事實證明,對於輕微丟包調大參數可以緩解丟包,但對於大量丟包則幾乎不怎么管用,內核處理速度跟不上收包速度的問題還是客觀存在,本質還是因為單核處理中斷有瓶頸,即使不丟包,服務響應速度也會變慢。因此如果能同時使用多個CPU Core來處理中斷,就能顯著提高中斷處理的效率,並且每個CPU都會實例化一個softnet_data對象,隊列數也增加了。 

 

NAPI的處理邏輯是不會走到enqueue_to_backlog 中的,enqueue_to_backlog主要是非NAPI的處理流程中使用的。

這部分丟包可以在cat /proc/net/softnet_stat的輸出結果中進行確認: 

其中每行代表一個CPU,第一列是中斷處理程序接收的幀數,第二列是由於超過 netdev_max_backlog 而丟棄的幀數。 第三列則是在 net_rx_action 函數中處理數據包超過 netdev_budget 指定數量或運行時間超過2個時間片的次數。
 
硬中斷的中斷號及統計數據可以在/proc/interrupts中看到,對於多隊列網卡,當系統啟動並加載NIC設備驅動程序模塊時,每個RXTX隊列會被初始化分配一個唯一的中斷向量號,它通知中斷處理程序該中斷來自哪個NIC隊列。在默認情況下,所有隊列的硬中斷都由CPU 0處理,因此對應的軟中斷邏輯也會在CPU 0上處理。

 

 

 

 

 

 

 

 

參考資料:

Linux TCP隊列相關參數的總結

http://man.linuxde.net/ethtool


免責聲明!

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



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