归档 11 月 2024

Cilium netkit:容器网络性能的最后前沿

边际收益理论认为 ,微小但显著的改进可以带来巨大的成果。这种方法被应用于英国自行车队的训练,使他们在最近的奥运会赛事中取得了巨大的成功。Cilium 相继推出的网络增强功能是“边际收益”的另一个案例研究。就像自行车训练方案能够最大限度地发挥运动员的身体和精神表现一样,Cilium 引入的每一项改进——XDP BPF路由 BIG TCP等……——都旨在从网络中获得尽可能多的性能。

在现代网络中,无论您是否运行耗费大量带宽且对延迟敏感的 AI 工作负载,每一毫秒都很重要。

Cilium netkit 是 Cilium 的最新功能,于 1.16 版本中推出,旨在优化容器网络性能。Cilium 是第一个提供对netkit内置支持的公共项目,netkit 是 Linux 网络设备,于 6.7 内核版本中引入,由 Isovalent 工程师开发。

Netkit 已经显示出显著的改进:

好消息,我们已经完成了概念验证 (PoC),与 veth 相比,netkit 的 CPS (每秒连接数) 提高了 12%(太不可思议了!)。现在我们计划尽可能多地在我们的 DC 中使用 netkit。字节跳动云计算开发人员汤晨

Cilium netkit 的目标是实现原本无法实现的目标:主机网络和容器网络之间的网络性能匹配

有接近吗?让我们来一探究竟。

高性能网络专家

为了让 Kubernetes 集群获得最佳网络性能,请与 eBPF 和 Isovalent 的创建者合作。请求演示

容器网络之前的一系列妥协

多年来,容器化和云原生架构的优势已经变得如此明显,以至于我们往往会忘记在此过程中做出的妥协。很简单——抽象是有代价的。虚拟机的性能永远不可能像裸机那样快,但这是一个可以接受的权衡:我们知道虚拟化提供了显着的可扩展性和灵活性优势。

容器化和 Kubernetes 也是如此:现在,我们都了解它们为基础设施工程师和应用程序开发人员带来的好处。但为了支持这种模式,我们不得不在此过程中做出一些让步,其中最严重的就是网络性能。

这些限制的影响是容器网络性能和主机网络性能之间的性能大幅下降了 35% 。

使用 Cilium 1.16,性能损失现在可以被消除。

让我们回顾一下标准 Kubernetes 网络数据路径架构的一些限制以及 Cilium 如何解决这些限制,最后介绍 Cilium 1.16 引入的最新变化(如果您已经熟悉 Cilium,可以直接跳到新内容)。

障碍#1:Kube-Proxy 和 iptables

在原始 Kubernetes 部署中,Kube-Proxy 将通过 iptables 或 ipvs 系统处理 NAT 和服务负载平衡。我们在之前的博客文章中详细讨论了 Kube-Proxy 的局限性,这里无需重复,尤其是当iptables 创建者本人认为 eBPF 更合适时

简而言之:Kube-Proxy 对 iptables 的依赖(一种不适合 Kubernetes 的变动和规模的技术)增加了显著的开销,如下图所示。

捷径 #1:基于 eBPF 的 Kube-Proxy 替代品

再次强调,Jeremy关于 kube-proxy 替代品的优秀博客文章应该会告诉您所有您需要了解的关于为什么应该使用 Cilium 基于 eBPF 的 kube-proxy 替代品的信息。阅读它以了解更多背景信息,但一图胜千言,请将 Cilium 基于 eBPF 的 Kube-Proxy 替代品与前一个替代品的简单性进行比较:

eBPF 的 kube-proxy 替代品的性能明显优于原来的产品,特别是在规模方面:

eBPF kube-proxy 替代品现在是 Cilium 的基础方面:它也是下面突出显示的调整功能的要求。

障碍 #2:上层堆栈转发

当流量离开 Pod 时,通常需要将Pod 的源 IP伪装为其离开的主机上的 IP。

伪装

强制执行这种形式的网络转换传统上是通过将数据包发送到网络堆栈上,以便netfilter子系统更改 IP 地址来完成的。鉴于伪装需要连接跟踪器查看来自两个方向的流量以避免无效连接导致的丢包,来自主机网卡的返回入口流量也必须发送到网络堆栈上。

伪装还需要咨询内核的路由层以了解下一跳地址/接口并填充目标/源 MAC 地址。

上层堆栈转发导致孤立套接字

总结一下,伪装流量会导致内部网络堆栈处理出站和入站流量。这会带来不必要的延迟和处理,但还不止于此:它会破坏 TCP 流量控制机制。在将流量转发到堆栈上时,数据包的套接字关联在主机堆栈的转发层中变为孤立状态。

换句话说,即使数据包仍在由内部系统处理,系统也会通知应用程序流量已离开节点。这意味着应用程序可能没有意识到系统何时拥塞,从而影响 TCP 背压过程并最终导致缓冲区膨胀并对性能产生重大影响(我在之前关于另一个网络性能功能 – BBR 的博客文章中写到了缓冲区膨胀):

捷径 #2:基于 eBPF 的主机路由

考虑到转向上层网络堆栈会造成多大影响,Cilium 和 eBPF 开发人员考虑实施基于 eBPF 的主机路由,以便为离开和进入 Pod 的数据包提供更直接的路由。他们创建了两个 Linux 内核 BPF 助手 –bpf_redirect_peer()bpf_redirect_neigh()– 并在 Cilium 代码库中进行了适当的更改,并在Cilium 1.9中发布了基于 eBPF 的主机路由。

和 分别转发来自 Pod 和到 Pod 的流量,避免将数据包推送到网络堆栈bpf_redirect_neigh()bpf_redirect_peer()

bpf_redirect_peer()确保物理 NIC 可以一次性将数据包推送到位于不同 Pod 命名空间中的应用程序套接字中。

bpf_redirect_neigh()将解析下一跳的 L2 地址并将数据包重定向到 NIC 驱动程序,同时保持数据包的套接字关联。这可以避免出现孤立套接字并确保 TCP 堆栈有适当的背压。

网络性能的提升是巨大的。

不过,正如您在橙色条(“veth + BPF 主机路由”)和黄色条(“主机(基线/最佳情况)”)之间看到的,仍然存在明显的性能差距。

我们还能做什么来关闭它?

障碍 #3:TCP 数据包太小

100+Gbps 网络接口卡的推出产生了意想不到的后果:CPU 如何处理每秒 800 万个数据包(假设 MTU 为 1,538 字节)?

正如我在 Cilium 博客文章 BIG TCP中深入解释的那样,减少数据包数量的一种方法就是将它们分组在一起。虽然 GRO(通用接收卸载)和 TSO(传输分段卸载)可以将数据包批量处理在一起,但由于 IP 标头中的长度字段,我们受到64K数据包大小的限制。

如果我们可以将数据包分组为更大的数据包会怎么样?

捷径#3:BIG TCP

借助 Cilium 上的 BIG TCP,我们现在可以将 TCP 数据包组合成一个超大的192K数据包;减少对 CPU 的影响并显著提高性能。

再次,吞吐量测试的结果非常惊人:

了解有关BIG TCP 背后的历史以及如何在 Cilium 上使用它的更多信息,或者在BIG TCP 实验室中亲自测试它。

障碍4:传统的虚拟电缆

大多数容器网络接口 (CNI) 插件(包括 Cilium 1.15 版本之前版本)都会通过虚拟以太网设备 ( veth ) 将 Kubernetes Pod 附加到其托管的节点。veth通常将网络命名空间中的 Pod 连接到主机网络命名空间中的节点,这也是容器可以访问其他容器或外部工作负载的方式。

让我们查看集群中的 Pod(运行 Cilium 1.15)并检查其网络接口。

# ip a show eth0
10: eth0@if11: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether 9a:f9:bd:42:0c:ae brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 10.244.2.114/32 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::98f9:bdff:fe42:cae/64 scope link 
       valid_lft forever preferred_lft forever

# ip -d l
[...]
11: lxc3c34280cf99e@if10: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DEFAULT group default qlen 1000
    link/ether 86:fe:01:80:08:ac brd ff:ff:ff:ff:ff:ff link-netns cni-8ba2017a-96bd-f18d-d09a-8e48c9284121 promiscuity 0  allmulti 0 minmtu 68 maxmtu 65535 
    veth addrgenmode eui64 numtxqueues 8 numrxqueues 8 gso_max_size 65536 gso_max_segs 65535 tso_max_size 524280 tso_max_segs 65535 gro_max_size 65536

您可以在上面的输出中看到eth0,通过虚拟以太网(veth)接口与if11另一个命名空间中主机上的另一个接口配对。

当我们检查节点时,我们可以看到虚拟以太网配对的另一端:

11: lxcfd04d472bcde@if10: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether 2e:f9:fc:35:d1:95 brd ff:ff:ff:ff:ff:ff link-netns cni-f24a815a-65e8-fc9e-be8e-c62d419c8b6f
    inet6 fe80::2cf9:fcff:fe35:d195/64 scope link 
       valid_lft forever preferred_lft forever

虽然它被广泛采用为 Linux 容器网络技术,但它是 15 年前在Linux 内核 2.6.24中引入的技术,并且存在一些缺点。

第一个是veth依赖第 2 层通信和 ARP 来让容器与 veth 对的另一端进行通信。这是一个人为的、不必要的步骤:Pod 不应该进行 ARP 解析。

更重要的是,veth 会带来性能损失。当流量离开 Pod 前往另一个节点或节点外流量进入 Pod 时,数据必须首先进入容器内的网络堆栈、切换命名空间、在主机命名空间上进行处理,然后才能发送并由网络接口​​处理以进行重新传输。这看起来可能无害,但整个过程(包括通过每个 CPU 的积压队列发送数据包)在压力下可能会变得代价高昂。

捷径#4:引入 netkit

Isovalent 工程师 Daniel Borkmann 和 Nikolay Aleksandrov最近Netkit引入 Linux 内核 (6.7)。Daniel 领导了本篇博文中重点介绍的许多改进,并在最近的 KubeCon 演讲中介绍了这些改进:

https://youtube.com/watch?v=AVEBcZc0YsQ%3Ffeature%3Doembed

Netkit 基于一个原创概念:如果我们可以将 BPF 程序直接加载到 Pod 中并使其更接近源头,会怎么样?

一个主要的好处是能够更早地做出网络决策。例如,对于发往节点外工作负载的 Pod 出口流量,netkit 会重定向到物理设备,而无需经过每个 CPU 的积压队列。

这是性能显著提升的原因之一,正如您将在后面的图表中看到的。

在第一次迭代中,netkit 设备成对发货,包括主设备和对等设备。主设备通常位于主机命名空间中,而其对等设备则位于 Pod 的命名空间内。

只有主设备才能管理自身及其对等设备的 BPF 程序。这是 Cilium netkit 带来的另一个好处:Pod 内的任何人都无法删除 BPF 程序。由于 Cilium 是 Pod 上运行的 BPF 程序的所有者,因此它还可以防止 BPF 程序相互冲突的情况,或者更糟的是,一个基于 eBPF 的应用程序卸载另一个应用程序安装的 BPF 程序。

Cilium 是第一个受益于 netkit 的公共项目,它将为 Pod 设置 netkit 设备,而不是 veth。Cilium netkit 将默认支持 L3,从而消除 ARP 引入的延迟和管理开销(L2 也是一个受支持的选项)。

Netkit 实践:详细了解如何替换 veth

现在让我们测试一下。首先,让我们安装 Cilium 1.16 并netkit启用该选项:

$ cilium install --version 1.16.0-rc.1 --namespace kube-system \
--set routingMode=native \
--set bpf.masquerade=true \
--set kubeProxyReplacement=true \
--set ipam.mode=kubernetes \
--set autoDirectNodeRoutes=true \
--set ipv4NativeRoutingCIDR="10.0.0.0/8" \
--set bpf.datapathMode=netkit

让我们再检查一下 Cilium netkit 是否已启用:

$ kubectl exec -n kube-system -it -c cilium-agent cilium-2qjjb -- cilium status | grep "Device Mode"
Device Mode:            netkit

让我们bpftool在 Cilium 代理上运行,看看哪些 eBPF 程序已加载。我们可以看到,netkit我们的容器虚拟设备已加载程序(tcx最近对用于其他附件的 tc BPF 数据和控件进行了重新设计):

$ kubectl exec -n kube-system -it -c cilium-agent cilium-2qjjb -- bpftool net
xdp:

tc:
cilium_net(2) tcx/ingress cil_to_host prog_id 3002 link_id 42 
cilium_host(3) tcx/ingress cil_to_host prog_id 2985 link_id 40 
cilium_host(3) tcx/egress cil_from_host prog_id 2986 link_id 41 
eth0(9) tcx/ingress cil_from_netdev prog_id 3006 link_id 43 
eth0(9) tcx/egress cil_to_netdev prog_id 3012 link_id 44 
lxc07d02daab9b3(108) netkit/peer cil_from_container prog_id 4416 link_id 207 
lxc_health(110) netkit/peer cil_from_container prog_id 4429 link_id 208 

flow_dissector:

netfilter:

让我们获取有关网络接口的更多详细信息:

$ kubectl exec -it pod-worker -- ip -d l
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 promiscuity 0 allmulti 0 minmtu 0 maxmtu 0 numtxqueues 1 numrxqueues 1 gso_max_size 65536 gso_max_segs 65535 tso_max_size 524280 tso_max_segs 65535 gro_max_size 65536 gso_ipv4_max_size 65536 gro_ipv4_max_size 65536 
107: eth0@if108: <BROADCAST,MULTICAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DEFAULT group default qlen 1000
    link/ether 00:00:00:00:00:00 brd ff:ff:ff:ff:ff:ff link-netnsid 0 promiscuity 0 allmulti 0 minmtu 68 maxmtu 65535 
    netkit mode l3 type peer policy blackhole numtxqueues 1 numrxqueues 1 gso_max_size 65536 gso_max_segs 65535 tso_max_size 524280 tso_max_segs 65535 gro_max_size 65536 gso_ipv4_max_size 65536 gro_ipv4_max_size 65536 

与运行 Cilium 1.15 时的早期输出相比,显著的区别是:

  • netkit用来代替veth
  • mode l3现已使用,取代了 L2,并且不再需要 ARP
  • peer policy blackhole意味着如果没有附加 BPF 程序,则任何时候都不会有任何流量泄漏出 Pod。

现在让我们回顾一下最终的性能测试(您可以在Daniel 的 KubeCon 幻灯片中找到有关如何运行它们的更多信息)。首先,延迟;我们现在将 Pod 到 Pod 的延迟降低到与主机到主机一样低。

吞吐量也是一样 – TCP 上的性能同样高。

现在,我们已经达到了性能平等。让我们最后一次回顾一下我们是如何实现这一目标的:

局限性笔记解决方案
限制 1:基于 iptables 的 Kube-ProxyKube-proxy 依赖于 iptables——一种不适合 Kubernetes 的规模和流失率的技术。使用基于eBPF的高性能kube-proxy替代品
限制 #2:上层堆栈转发来自 Pod 的流量必须通过网络堆栈转发,从而导致额外的延迟并影响 TCP 吞吐量。利用BPF 主机路由避免流量穿越网络堆栈。
限制 #3:TCP 数据包太小100G 网络正在推动对比标准 64K 大小更大的 TCP 数据包的需求。Cilium 上的BIG TCP在进入网络堆栈时将 TCP 数据包的大小增加三倍,从而提高了性能和吞吐量。
限制4:传统的虚拟电缆容器通过传统的 veth 设备连接,这存在性能缺陷,尤其是对于非节点流量。启用netkit以实现离节点流量的快速网络命名空间切换。

最后的话

最近的 Linux Plumbing Conference 演讲中,Martin KaFai Lau(Meta 软件工程师)分享了一些最近的测试结果,将实时 Facebook 生产流量的软件中断 (softirq) 负载与 veth 和 netkit 的最佳基线进行了比较。

如上所示,虽然我们可以观察到 veth 和 baseline 之间的性能影响,但 netkit 的性能与主机没有区别。

转自:https://isovalent.com/blog/post/cilium-netkit-a-new-container-networking-paradigm-for-the-ai-era/

云平台和IDC全方位对比

1成本

2.可靠性

3.安全性

4.服务器资源利用率/业务吻合度

5.性能

6.技术难度/易用性

7.运维团队规模

8..服务响应速度

9.资源可扩展性
10.系统部署效率

11.标准化复杂度

1,成本

云平台是一个规模庞大的系统,当你购买一个云资源时,实际上你是为整个云平台组成的各种资源付费,例如IDC/服务器/存储/网络/云平台运维工资等费用 ,而不是单纯的一个云资源费用,以上这些费用通过算法分摊到每个云资源上

从逻辑上来说,买一个服务器租出去,收到的服务器租金总和要大于购买这个服务器的费用才能赚钱,这个业务才能长期存活下去,更不用说云平台所用的IDC/服务器/存储/网络/云平台运维工资等费用

所以自建IDC成本无论是从逻辑推理上还是实际上都比云平台低,如有疑问可以咨询本站

本站提供优质IDC方案,三年总拥有成本可以做到云平台标准目录价格的35%以内,欢迎大家咨询

2.可靠性对比

2.1云平台和IDC部署方案整体结构如下:

图1-1

2.2 从整体结构看

2.云平台也是基于IDC的

3.一般公司没有自己的运维管理平台,而且一般运维管理平台是同时管理IDC和云平台的

整体架构云平台比IDC多两个风险点,也就是运管理平台和云后台系统,这两个系统一但故障,用户业务就会出现故障

所以在优质的IDC方案整体可靠性风险点少于云平台

2.2 在用户业务基础架构层面,国内云和aws处理的方法完全不同

国内云你可能收到类似信息:

AWS的用户基础架构可靠性完全基于用户自己的设置,例如EFS karpenter

2.3 IDC基础设施层面

云平台的IDC对用户是一个暗箱,用户根本不知道他位置、网络、恒温恒湿系统等实际信息

但是用户自己选的IDC可以实际去了解个方面

从这个角度,IDC可以依据自己需求选择对比IDC,并且是透明的

而云平台的IDC对用户来说是不可知的,用户完全无法判断云平台用的IDC好还是不好

同时各大云平台出问题的IDC也不少,当然具体网上自己搜索

对于云厂商服务器硬件方面的可靠性,还是有部分信息判断可靠性,例如您可能会收到以下类似邮件

综速:优质的IDC方案风险点少于云平台,可靠性高于云平台

3.安全性

3.1 DDOS攻击

云平台处理方式:将被攻击IP拖入黑洞,因为攻击一般跟着域名走,所以业务实际上也是瘫痪状态

当然云平台可能会要求你购买ddos高防平台,

IDC处理方式:也是封锁被攻击IP,或者购买DDOS高防平台

DDOS高防平台有以下缺点:

1.价格昂贵

2.抵御攻击带宽有限

3.不能阻挡带有业务逻辑的攻击(等于钱白花了)

需要便宜实用的ddos攻击防御方案请找本站,联系方式见首页

3.2 OWASP 攻击

因为每个公司的业务逻辑都不一样,所以各云平台并不是实际处理OWASP攻击,这个只能靠公司自己的安全团队

3.3 管理平台安全

因为IDC没有管理平台,只有云有管理平台,但是云平台一般安全性很高,所以基本无差别

3.4帐号/费用安全

云平台的帐号密钥泄露后可能造成云平台费用异常,但是IDC没有这个问题,因为IDC带宽等费用都是事先定好的

3.5数据安全

采用云平台,数据是放在云端存储,采用IDC,数据是放在自有存储,所以IDC数据安全性比云平台高

未提及的主机等安全风险,云平台和IDC都是要自己处理的

综述,在ddos/owasp攻击上,IDC和云平台安全风险是一样的,数据安全性IDC高于云平台,同时云平台存在异常费用风险

同时在使用云平台时,很多人会误以为云平台会处理所有安全风险,但是实际上不是,而且云平台各种安全风险提示太多,是否需要处理还是需要专业人员判断,反而增加了工作量

4.服务器资源利用率/业务需求吻合度

4.1 服务器资源利用率对比

云平台:一般为了业务隔离,用户会买很多云主机用于不同业务项目,但是云主机是运行于云平台的物理服务器之上的,所以空闲的资源没法利用

IDC:IDC可以用kvm自定义虚拟化,如果kvm宿主机的利用率不高,可以增加kvm虚拟机提搞服务器资源利用率

结论:IDC服务器资源利用率高于云平台

4.2 服务器和业务吻合度

云平台:云平台的云主机都是事先规划好的机型,固定了GPU/CPU/内存,虽然机型多,但是是通用型标准,未必符合自己的实际业务需要,例如有的业务需要多GPU低CPU内存,这样的机型在云平台就很难找到

IDC:IDC可以依据业务需求实现规划服务器方案,实现实际采购服务器和业务需求的一致性,避免不必要的服务器费用和不合适的资源浪费

结论:IDC服务器和业务需求一致性高于云平台

5.性能

5.1 网络性能

云平台一般采用AS自治域广播自己的IP地址,国内最佳网络是移动、联通、电信网络,而且只有移动、联通、电信网络有骨干网络,选择中国核心网络节点IDC会得到更好的网络性能和稳定性

结论:选择优质IDC会得到更好的网络性能

5.2 服务器性能

云平台:云平台云主机一般运行在虚拟化宿主机之上,具体的云平台宿主机对用户来说属于暗箱,用户根本不知道云平台云主机的具体配置性能,机器是新是旧,其实际运行的云主机数量有多少

IDC:虚拟化方案可以依据实际业务环境进行确定,并且可以不用虚拟化方案,直接用物理服务器,同时可以采购最新高性能服务器

结论:IDC服务器性能高于云主机

6.技术难度/易用性

云平台:使用云平台需要了解VPC/S3/OSS/ACR/ECR/ACK/ASK等云专用平台,而且每个云平台的模式还都有差别,同时产品多,web界面菜单界面多,使用非常繁琐,如果调用SDK,需要一一了解云平台各模块接口,并不那么简单轻松,如果使用AWS平台所有都需要自己配置,和IDC无异

IDC:都是使用开源系统,例如Linux/kubernetes/KVM/mysql/redis/等,使用均为命令行

其实云平台是把开源的kubernetes/KVM/mysql/redis封装为产品,免除了用户安装系统的过程,但是如果一个运维不了解具体的架构系统,也很难很好的维护云平台

但是在实际情况中,因为云平台做了系统安装部分的工作,同时有web界面,给人的感觉是云平台技术要求低,拿来就能用,如果一个mysql DBA不会安装mysql,那他怎么维护好mysql呢

在具体的操作易用性上,命令行的操作便利性和效率是高于云平台的web化鼠标点击界面的

在具体的技术深度上,云平台做了系统安装部分的工作,同时有web界面,给人的感觉是云平台技术要求低,拿来就能用,如果一个mysql DBA不会安装mysql,那他怎么维护好mysql呢?如果需要保障一个业务系统的稳定运行,其实云平台和IDC需要的技术深度是一致的

7.团队规模

云平台实际上只解决了linux/mysql等系统的安装问题和服务器数据统计问题,实际上系统的维护,例如mysql的日常维护,linux的参数针对性优化,安全事务等还是需要用户自己设置和管理,并不是用了云平台就万事大吉,就可以少招专业的运维人员,而且系统安装对于一个运维来说,属于低阶技术,不存在使用云平台就可以降低对运维能力的要求

所以无论是IDC还是云平台,都需要专业的运维团队,但是需要按照业务需求合理规划运维团队

如果觉得目前运维团队臃肿低效,可以联系本站分析处理

8.服务响应速度

云平台如果出了问题,只能工单联系等回复,并且还要判断是云平台的问题还是用户系统的问题,因为云平台模块多,响应不一定及时,并且有时候只能等待

IDC可以有专门的微信QQ群等方式,并且架构简单,可以快速定位问题并答复

9.服务器自动扩容

云平台自动扩容比较方便,不需要临时采购服务器,但是也有容量上限,一般服务器需求量大,需要事先和云平台沟通,

IDC则服务器则不能随时增加服务器,采购流程较久,但是可以冗余部分服务器

在临时性业务需求的服务器伸缩上,云平台优于IDC,所以可以将大部分业务放在IDC,秒杀型业务放在云平台

error: Content is protected !!