先说一个我见过很多次的场景。一台标着万兆口的机器,跑内网数据同步或者对象存储回源,压测的时候吞吐死活卡在 2 点多 G。第一反应基本都是怀疑带宽被限速了——去控制台看端口流量图,确实就这么多;再看整机监控,top 里总 CPU 才用了十几个点,内存三成,iostat 里磁盘几乎没动静。哪儿都不忙,可带宽就是上不去。
这时候只要做一件事:在 top 界面里按一下数字 1,把每个逻辑核展开。你会看到 CPU 使用率根本不是均匀的——有那么一个核,si(软中断)那一列顶到八九十,us 只有几个点;其余三十几个核的 idle 全在 95% 以上。整机 CPU 使用率是个假指标,它把这些核平均掉了。
这就是本文要立的那个判断:标称万兆却只跑出两三 G,绝大多数时候不是带宽不够,而是收包的软中断只落在少数几个核上,吞吐被单核的处理能力钉死了。
要定位瓶颈,得先知道一个包进来,CPU 的活儿是怎么花的。
第一步,网卡通过 DMA 把包直接写进内存里的环形缓冲区(Ring Buffer,也叫描述符环)。这一步不占 CPU,网卡自己写内存。
第二步是硬中断。硬中断处理程序很短,干的活儿基本就是把这个队列后续的中断关掉、把队列挂到本 CPU 的 NAPI poll 列表上、触发一个软中断,然后返回。你在 top 里看到的 %hi 通常很低,原因就在这儿。
第三步是软中断 NET_RX,也就是 NAPI 的 poll 函数。这才是体力活:从 ring 里把包取出来、给每个包分配 skb、做校验和处理、跑驱动逻辑,再交给 IP 层和 TCP 层,最后放进 socket 的接收队列等应用来读。GRO/LRO 会在这一层把同一条流的小包合并成大包,能省下不少每包开销,但这个合并动作本身也在这同一个核上做。要是软中断一次性没处理完(受 netdev_budget 这类参数限制),剩下的活儿会被交给 ksoftirqd 内核线程接着干——这时候你在 top 里会看到一个叫 ksoftirqd/3 的进程 CPU 很高,那个数字 3 就是中断落在的核。
第四步才是应用:recv/read 把数据从内核拷到用户态,业务逻辑处理。
关键点来了:软中断在哪个核上被触发,就在哪个核上消耗 CPU。硬中断落在 CPU3,NET_RX 就在 CPU3 上跑,CPU3 的 si 就跟着涨。这条链路上从取包、分配 skb 到协议栈处理这一段,在没有多队列的情况下是不可拆开的——一个队列的包只能由一个核按序处理。所以单队列网卡的收包吞吐上限,就是单核软中断的处理上限。
到这里,那台卡在 2 点多 G 的机器就说得通了:包其实都收进来了,只是只有一个核在干活,那个核干到 90%,其余核在旁边看着。带宽没跑满,但 CPU 确实已经到顶了——只不过到顶的是"某一个核",不是"整机的 CPU"。
这笔账建议你自己算一遍:sar -n DEV 1 拿到 rxpck/s 和 rxkB/s,两个一除就是平均包长。同一个万兆口,在 1500 字节标准帧下线速大约是 0.81 Mpps(每帧按 1538 字节含前导码与帧间隔算),在 64 字节小包下线速是 14.88 Mpps——同样的端口速率,小包场景对 CPU 的要求高出一个数量级以上。
单核软中断能吃下的包处理量是有上限的,具体数字受 CPU 主频与架构、驱动实现、GRO 是否生效、netfilter/conntrack 有没有介入的影响极大,只能实测确认。但结论是确定的:同一张万兆网卡,跑大文件同步可能能到五六 G,跑小包业务可能 1–2G 就撞墙了。这不是撞上了带宽墙,是撞上了 pps 墙。
所以看到"卡在 2 点多 G"的时候,先别急着算带宽够不够,先看一眼平均包长。平均包长只有一两百字节却拿着万兆口,这类业务最容易被单核钉死,而且开了多队列之后收益也最明显。
现代万兆网卡基本都是多队列的。多队列的意思是:网卡内部维护多条独立的接收队列,每条队列有自己的 ring buffer 和自己的中断(MSI-X 向量)。网卡对收到的包做 RSS(Receive Side Scaling)哈希——对五元组(源 IP、目的 IP、源端口、目的端口、协议)算哈希值,再查间接表(indirection table)映射到某条队列。不同流进不同队列,每条队列的中断绑到不同的核,NET_RX 就自然摊开了。
这里有个常被忽略的边界:RSS 是按流哈希的,不是按包轮询的。一条 TCP 流从建立到结束,所有包都落在同一条队列上——这是刻意设计的,为了保证同一条流的包不乱序。所以一条流的上限就是"一条队列 + 一个核"的上限,RSS 帮不了它。
另外,收包方向的对偶问题是发送方向的 XPS(/sys/class/net/eth0/queues/tx-*/xps_cpus),它决定发包用哪条队列。本文主角是收包,XPS 只在多队列发送不均衡时才需要关心,不展开。
第一条是 ethtool -l eth0,看 Pre-set maximums 和 Current hardware settings 两栏里的 Combined。当前值远小于最大值,就是队列数没开起来——这大概是我在线上见得最多的一种成因。虚拟机里、默认镜像里、某些驱动的保守默认参数下都很常见。也有些驱动会按 CPU 核数自动收敛队列数,核少了队列也跟着少。
第二条是看队列的实际流量分布:ethtool -S eth0 | grep -i "rx_queue\|rx.*packets",或者直接 ls /sys/class/net/eth0/queues/ 数一下 rx-N 目录有几个。如果队列数是 8,但只有 rx-0 的计数在飞涨、rx-1 到 rx-7 几乎不动,那问题就不是"队列数不够",而是"哈希不均匀"或者"流太少"。
哈希不均匀的典型成因是大象流:业务里就那么几条大流,哈希结果全落到同一条队列。处理办法有两个方向,一是增加并发流数让哈希自然分散,二是调整参与哈希的字段(ethtool -N eth0 rx-flow-hash tcp4 sdfn 这种写法,sdfn 表示源/目的 IP 加端口,具体支持哪些字段看网卡和驱动)。前者更容易见效,后者受硬件限制较多。
说一千道一万,得拿证据说话。下面这几个命令都是真实可用的,输出形态是通用的,具体数值在你自己的机器上完全可能不一样——定位的时候永远以你自己机器上跑出来的数为准,别拿别人的数字当阈值。
在 top 界面按数字 1 展开每个逻辑核,看 si 那一列。判读标准很直接:如果只有一个或少数几个核的 si 长期在 60%–90%,其余核 si 接近 0,而整机平均 CPU 很低——这就是中断集中的典型形态。同时留意 top 进程列表里有没有 ksoftirqd/N 占 CPU,N 就是那个被压着的核。
cat /proc/softirqs 会按行列出 TIMER、NET_TX、NET_RX、BLOCK、SCHED、RCU 等软中断在每个核上的累计计数。单次看没意义,要隔一秒取两次看增量:
watch -n1 'grep NET_RX /proc/softirqs'
判读:NET_RX 那一行的增量如果几乎只出现在某一个核上(比如 CPU3 每秒涨十几万,别的核只涨几百),那就是实锤。TIMER 和 SCHED 通常是所有核都在涨,那是正常的,别被它们干扰。
cat /proc/interrupts | grep eth0(网卡名按实际换成 ens33、enp1s0、eno1 之类)。多队列网卡会列出 eth0-rx-0、eth0-rx-1 …… eth0-rx-N,还有对应的 tx 队列和其他事件。只有 rx-0 那一列在快速增长,说明流量全走了一条队列。顺手记下第一列的中断号,后面绑核要用。
mpstat 把每个核的 %usr、%sys、%irq、%soft、%idle 分列。%soft 高而 %irq 低,符合前面说的路径特征(硬中断短、软中断重);如果 %irq 本身就很高,问题可能在硬中断层面——中断合并没开或者中断风暴,处理方向是 ethtool -c eth0 / ethtool -C eth0 rx-usecs 调中断合并,不是本文的软中断话题。
| 看什么 | 用什么命令 | 什么现象说明是中断问题 | 什么现象说明不是 |
|---|---|---|---|
| 每核软中断占比 | top 后按 1,看 %si 列 | 某一个核 si 长期 60%–90%,其余核接近 0,整机均值却很低 | 各核 si 都不高且均匀,us 或 sy 高——瓶颈在应用逻辑或系统调用 |
| NET_RX 的核间分布 | watch -n1 'grep NET_RX /proc/softirqs'(看增量) | NET_RX 增量几乎只在一个核上增长,其余核几乎不动 | 多核同步增长;或增长主要发生在 TIMER / SCHED / RCU 行上 |
| 各队列中断计数 | cat /proc/interrupts | grep 网卡名 | 只有 rx-0 快速增长,rx-1 到 rx-N 几乎不动 | 各队列同步增长而吞吐仍上不去——去看窗口、连接数、应用消费能力 |
| 队列数与上限 | ethtool -l eth0 | Current 的 Combined 远小于 Pre-set maximums(如 1 对 63) | 当前值已等于最大值且各队列计数均匀——队列这条路已经走到头 |
| 网卡侧丢包 | ethtool -S eth0(no_buffer / fifo / missed / over) | 计数几乎不涨——包全收进来了,只是处理不过来 | 计数持续上涨——是"收不进来",先查 ring 大小与驱动,不是中断分布 |
| 硬中断 vs 软中断 | mpstat -P ALL 1 | %soft 高、%irq 低——时间花在 NET_RX 处理上 | %irq 本身就高——先处理中断合并或中断风暴;%usr 高——看应用 |
一、队列数压根没开起来。ethtool -l 里 Current 的 Combined 是 1,Pre-set maximums 是 63。原因可能是驱动默认参数保守、BIOS 里相关特性被关、或者某个启动脚本里写死过。虚拟机里更常见——virtio-net 的队列数默认通常跟 vCPU 数或某个较小的值绑定,一台 4 vCPU 的云主机很可能只有 1–2 条队列。
二、亲和性被人工写死到同一个核。cat /proc/irq/中断号/smp_affinity_list,所有队列的中断全指向同一个核。这种一般是有人手动 echo 过,或者某次"优化"留下的痕迹。把中断号跟队列一一对应着看一遍就能发现。
三、irqbalance 没起作用,或者起了反作用。irqbalance 的目标函数是系统整体的中断负载均衡,它不感知网络流量特征——它不知道哪个队列上跑着 8G 流量、哪个队列只有几十兆,只按中断次数和自己的负载模型来分配。在 NUMA 拓扑下,它也可能把中断放到离网卡较远的那个节点的核上,带来额外的跨 socket 内存访问。更麻烦的是:你手工设了 affinity 之后,有些版本和配置下它又会重新分配,把你设的值覆盖掉。
四、并发流数太少。这个坑在压测里特别常见。iperf3 默认只跑一条流,一条流永远只落一个队列一个核,你拿它去测一台开了 16 条队列的机器,测出来的还是单核那点吞吐。压测要用 iperf3 -P 8 或者更多并发流,有条件就用业务的真实流量模型。反过来,如果业务本身就是少数几条长连接大流(数据库同步、单条大文件传输),那 RSS 分散不了它,这是业务形态决定的,得认清。
五、中断和应用进程抢同一个核。中断绑在 CPU2,业务进程也跑在 CPU2,两边互相挤。这种时候 us 和 si 都不低,但吞吐照样上不去,而且延迟抖动会明显变大。判读方式就是看 top 按 1 里同一个核上 us 和 si 是不是都很高。
六、虚拟化环境里队列数被限制。云主机的 virtio-net 队列数由宿主机一侧决定,常见规则是取 vCPU 数与某个上限的较小值;镜像里的默认值也可能偏低。能不能自己改,取决于平台有没有把 ethtool -L 的权限放给你——有些镜像里执行 ethtool -L 会直接报不支持。
这也是我一直建议的做法:要做网络性能调优的业务,优先选能自己控制中断分布的物理机。一万网络深耕 IDC 19 年(成立于 2007 年),裸金属和云主机两种形态都提供;裸金属是无虚拟化开销的形态,队列数、中断亲和、NUMA 这些都能自己动手改,云主机形态下这些参数受平台约束,能不能改要看平台放不放权限。真到了要逐核调中断的地步,前者省心得多。
看到 si 高之后别急着改队列,先做一个区分:包是根本没进内存(收不进来),还是收进来了但 CPU 消化不动(处理不过来)。这两者的处置路径不一样,走错了会白忙一场。
看 ethtool -S eth0 里这几类计数,隔几秒取两次看增量:
如果这些计数几乎不涨,说明包全都顺顺当当进了内存,只是 CPU 消化得慢——这就是典型的软中断瓶颈,走开队列、绑核这条路。
如果这些计数持续在涨,说明包在网卡层面就被丢了。这时候先看 ring buffer 大小:ethtool -g eth0 看当前值和上限,ethtool -G eth0 rx 4096 之类把它调大(具体能设多大看驱动)。ring 调大能吸收突发流量,但如果软中断长期处理不过来,加大 ring 只是把丢包的时点往后推,不会凭空变出处理能力——这是个常见的自欺欺人操作。
还有两个容易混淆的丢包位置顺手看一下:ip -s link 里的 RX dropped 是链路层统计;nstat -a 或 netstat -s 里的 TcpExtListenOverflows / TcpExtListenDrops 说明 accept 队列满了,那是应用 accept 得太慢,跟中断分布没关系。
顺序我一般这么走,每一步都有它的代价,别跳步。
ethtool -l eth0 先确认最大值,然后 ethtool -L eth0 combined N。
N 怎么取?不是越大越好。经验做法是取"网卡所在 NUMA 节点的物理核数"和"队列最大值"之间,8、16 这种量级比较常见;盲目拉到 63 会让哈希更碎、流在核间跳来跳去、缓存局部性变差,中断本身的开销也会上升,实测下来未必更好。具体取多少,需要你在自己的机器上压一遍确认。
代价必须说清楚:改队列数会让多数驱动重新初始化队列,通常伴随网卡短暂 down/up,等于一次秒级到十几秒级的断网。一定要在允许的时间窗做,别在生产高峰期远程改,改之前留好本地串口 / IPMI / KVM 的后路。像一万网络这类提供 IPMI 与控制台的裸金属,动之前先确认控制台能连上,比什么都重要。改完立刻用 ethtool -l 复查当前值,再用 ethtool -S 看各队列计数有没有摊开。
先拿到队列的中断号(cat /proc/interrupts | grep eth0),假设 eth0-rx-0 对应 125:
echo 3 > /proc/irq/125/smp_affinity_list (把这条队列的中断绑到 CPU3)
或者用位掩码写法:echo 8 > /proc/irq/125/smp_affinity。批量处理的话用 shell 循环遍历 grep 出来的中断号,注意把 cut 出来的字段 trim 干净,别把空格写进去。
NUMA 对齐这步别省。先确认网卡插在哪:cat /sys/class/net/eth0/device/numa_node,返回 0 就是在 node0;再看哪些核属于 node0:lscpu 或 numactl -H。双路机器上如果把 node1 上的网卡中断绑到 node0 的核,每收一个包都可能要跨 socket 走 UPI 访问内存,延迟和有效带宽都要打折。numastat 里的 numa_miss 和 numa_foreign 涨得快,就是这个信号。
但要讲清楚:NUMA 只是加成项,它不会让中断从"集中在 1 个核"变成"分散到 8 个核"。本文的主题始终是队列与中断分布,NUMA 是在分布做对之后才谈的优化,别把力气用反了。
中断绑一批核,业务进程用另一批核:taskset -c 8-15 nginx,或者 numactl -C 8-15 ./app。
这里有个反直觉的地方:把软中断和应用完全分开,未必是最优解。包被软中断处理完要交给应用读,如果两个核离得太远(尤其是跨 socket),数据在缓存里的局部性就没了,还得再跨一次。更常见的做法是让中断和应用落在同一个 NUMA 节点内的不同核——既避免互相抢 CPU,又保住缓存亲和。具体怎么划,要看你的业务是收包重还是计算重,没有放之四海皆准的答案,得实测。
我的看法是别一刀切。irqbalance 在队列数正确、核数多的机器上通常工作得不错,省事;但它不感知流量特征,也不懂你的业务布局。要做精确绑核(比如按 NUMA 对齐再加与应用错开的排布),就得让它别插手:在 /etc/sysconfig/irqbalance 里用 IRQBALANCE_BANNED_CPUS 把你手工绑定的核排除掉,或者用 --banirq 排除特定中断,再或者干脆停掉它自己做全套。
最常见的翻车是:你手工设了 affinity,irqbalance 又把它改回去了,你以为改了其实没改。改完一定要复查 /proc/irq/N/smp_affinity_list,过几分钟再看一次,确认没被覆盖。
加核、加机器能解决的是"队列已经摊开、但每个核还是不够"的情况。如果队列数是 1,加到 64 核也没用——这就是为什么有人把机器从 8 核升到 32 核,吞吐一动不动。反过来,在队列已经摊开的前提下,单核主频和 CPU 架构对 NET_RX 吞吐的影响是很实在的,这时候换更高主频的 CPU 才有效果。
RPS(Receive Packet Steering)是内核提供的软件层方案:在软中断里对包再算一次哈希,然后通过 IPI(处理器间中断)把包投递到另一个核的 backlog 队列,让那个核来处理后续的协议栈流程。它不需要网卡硬件支持多队列,所以是单队列网卡、改不了硬件队列的虚拟机的唯一退路。
配置就这几行:
echo ff > /sys/class/net/eth0/queues/rx-0/rps_cpus (位掩码,哪些核参与 RPS)
echo 32768 > /sys/class/net/eth0/queues/rx-0/rps_flow_cnt
echo 32768 > /proc/sys/net/core/rps_sock_flow_entries (RFS 用的全局流表大小)
RFS 是在 RPS 基础上再进一步:它看这个包属于哪个 socket、跑那个 socket 的应用在哪个核上,就把软中断派到那个核去,让数据处理和应用在同一核的缓存里完成。对收包后紧跟着大量处理(比如代理转发)的业务,RFS 的收益通常比纯 RPS 更明显。
要说清代价,就得说清它和 RSS 的区别:
一句话结论:RPS 是"没有硬件多队列时的软件补偿",不是 RSS 的替代品,更不是性能优化的首选动作。
第一,压测必须用多流。iperf3 -c 目标 -P 8(或更多并发流),单流测不出多队列的效果,这一点前面强调过。有条件直接用业务真实流量模型,比 synthetic 可信得多。
第二,压测的同时开两个窗口:一个 top 按 1 看 %si 有没有摊开、最高的那个核降到多少;一个 watch -n1 'grep NET_RX /proc/softirqs' 看增量是不是分布在多个核上。如果带宽涨了但 si 还是集中在一个核上,那多半是别的原因带来的改善,别急着下结论。
第三,ethtool -S eth0 的 drop 类计数是否还在涨。
还有一条纪律:一次只改一个变量。同时改队列数和绑核,你就不知道是谁的功劳。改动前后各跑一轮同样的压测,把三个数记下来对比。
把这些排除项过一遍再回到中断。整篇的结论就一句:"带宽跑不满"先别怀疑运营商和网卡,先看中断分布;判断依据是 %si 在各核上的分布,不是总 CPU 使用率。而调中断分布做的是"把已有能力用出来"这件事,它不会让 1G 端口变成 10G,也不会突破上游给的限速——认不清这条边界,就容易在错误的方向上一直加机器。
不是,但要换思路。云主机里 virtio-net 的队列数由宿主机一侧决定,平台没放开 ethtool -L 权限的话,硬件队列这条路是堵死的。退路有两条:一是上 RPS/RFS,在软件层把软中断二次分散,代价是多一次 IPI 和跨核投递,效率不如 RSS,但通常能把吞吐从"单核的量"往上抬一截;二是换个形态——换成能自己改队列数和中断亲和的裸金属。一万网络的裸金属从 E5-2620 / 32G / 1T 的 ¥999 元/月起,到双路 E5-2698v4×2 / 32G / 1T 的 ¥3999 元/月(以官网实时价为准),云主机形态的一万云是 ¥25 元/月起。要做逐核调优的业务,我一般建议直接上裸金属,省掉跟平台权限扯皮的时间。
会有短暂中断。多数驱动在 ethtool -L 改变队列数时会重新初始化队列,等同于网卡 down/up 一次,通常是秒级,个别驱动和老卡可能更长。生产环境可以做,但必须在低峰期、走变更流程,并且确认你有带外通道(IPMI / KVM / 串口)能连上机器——万一改完网络起不来,还能自己登进去回滚。另外改之前先把当前配置记下来:ethtool -l、ethtool -g、各队列的 smp_affinity_list 都存一份,方便出问题时原样恢复。
不能替代,只能兜底。RSS 是网卡硬件按五元组哈希把包直接分到多条队列,包从进内存那一刻就在不同核上;RPS 是内核软件在软中断里再算一次哈希,把已经收到的包通过 IPI 转投到别的核。前者没有二次投递,缓存局部性也更好,效率明显更高。所以有硬件多队列时一律优先 RSS,只有在单队列网卡、或者云主机里改不了队列数时才用 RPS。两者也不冲突——开了 RSS 之后再叠加 RPS,通常只是增加开销,不建议这么干。
看你要不要精确控制。队列数正确、核数多、业务不挑核的机器,留着挺好,省事且能自动适应负载变化。但它的目标函数是系统整体的中断负载均衡,不感知哪条队列上跑着多少流量,NUMA 拓扑下也可能做出次优选择。你要做按 NUMA 对齐、跟应用错开的精确排布,就得让它别插手:用 IRQBALANCE_BANNED_CPUS 排除手工绑定的核,或者 --banirq 排除特定中断,或者停掉它自己做全套。最要紧的是改完复查 /proc/irq/N/smp_affinity_list,隔几分钟再看一次,确认没被它覆盖回去。
先按 NUMA 分块:网卡在 node0(cat /sys/class/net/eth0/device/numa_node 确认),就把中断绑在 node0 的核上。剩下的问题是在 node0 内部怎么分。我常用的排法是中断占 node0 的前几个核,业务进程用 taskset 或 numactl 绑到 node0 剩下的核——既不让两边抢同一个核,又保住同一个 socket 内的缓存亲和。别为了"彻底分开"把业务赶到 node1 去,跨 socket 的内存访问和缓存失效会把这点收益吃掉。具体的核数配比要看业务是收包重还是计算重,得实测。
九成是队列数没跟着变。收包用的是"队列数"个核,不是"核数"个核——队列数是 1 的时候,加到 64 核也只有一个核在收包,剩下的核全部闲着。验证很简单:ethtool -l eth0 看 Combined 的当前值是不是 1,再看 /proc/interrupts 里是不是只有 rx-0 在涨。两个数都对上了,加核就是白花钱。正确的顺序是先把队列数开起来、把中断摊到多个核,之后如果每个核仍然吃力,加核才有意义。
先看三件事:一是 vCPU 数,virtio-net 的队列数在很多平台上是跟 vCPU 数挂钩的,2 vCPU 的机器很难给你 8 条队列;二是镜像里的默认配置,有些发行版镜像的默认队列数偏低;三是平台策略,宿主机一侧的 tun/tap 与 vhost 配置决定上限。确认清楚之后再决定:平台允许就用 ethtool -L 调,不允许就上 RPS/RFS 兜底,再不行就换物理机形态。另外别忘了压测时用多流——iperf3 单流在任何队列数下都只会用到一个核。
带宽是结果,不是证据。要确认改动真的生效,得看三个中间量:一是 top 按 1 之后 %si 有没有从"一个核 90%、其余核 0%"变成"多个核各有 20%–40%";二是 /proc/softirqs 里 NET_RX 的增量是不是分布在多个核上,而不是仍然只在一个核涨;三是 ethtool -S 的 drop 类计数是不是不再增长。这三个都变了,带宽的上涨才站得住。反过来,如果带宽涨了但 si 还集中在一个核上,那多半是别的因素(比如换了对端、换了压测参数)带来的改善,别把它记到中断调优头上。
文中出现的全部命令(top、/proc/softirqs、/proc/interrupts、mpstat、ethtool 的 -l / -L / -S / -g / -G / -x / -N / -c、RPS 相关的 sysfs 与 sysctl 路径、taskset / numactl / numastat / sar)均为 Linux 通用工具与内核接口,具体输出形态与可用参数随内核版本、驱动与网卡型号而异,请以你自己机器上的实际情况为准;文中所有性能描述均为"通常会出现 / 需要实测确认"的口径,不构成任何实测数据或性能承诺。
涉及的服务器与云主机形态、裸金属档位(E5-2620 / 32G / 1T ¥999 元/月起、双路 E5-2698v4×2 / 32G / 1T ¥3999 元/月)、一万云 ¥25 元/月起,以及一万网络"深耕 IDC 19 年(成立于 2007 年)"的品牌与服务信息,均引自一万网络官网 https://www.idc10000.net/ 的相应产品页面。具体以签约时最新报价与合同为准,起价档通常对应最低配置与特定付款方式,实际成交价请以下单时核算结果为准。
Copyright © 2013-2020 idc10000.net. All Rights Reserved. 一万网络 科技有限公司 版权所有 深圳市科技有限公司 粤ICP备07026347号
本网站的域名注册业务代理北京新网数码信息技术有限公司的产品