分享

【交易技术前沿】降低网络时延的探讨 / 朱宁,叶婧

 黑马_御风 2016-08-31
?

本文选自《交易技术前沿》第十八期 (2015年3月)。

朱宁,叶婧
上海证券交易所 系统运行部 上海200120
Email:nzhu@sse.com.cn ,jye@sse.com.cn

摘 要:在类似高频交易(HFT)的性能敏感型环境中,低时延是处理巨大交易容量的关键。NASDAQ一笔订单的最快成交速度是100微秒左右。本文通过概述产生网络时延的各个方面,分析了在不远的将来用低时延网络技术全面替代目前的千兆网络,以及部署低时延网络硬件的必要性。
关键词: Low latency;存储转发vs直通;芯片

0. 缘起

       最近一年里,先后接到过多次来自证券公司和期货公司朋友的电话咨询, 都是关于如何能在网络上加快数据传输,并以此为宣传亮点吸引顾客来营业部办理业务。在和他们共同探讨问题的同时,由衷感觉低时延的交易时代确实一步步走近了。无论是金融交易,网购车票或是电商秒杀,都强调拼速度。故借编写此文的机会整理和扩充自己的知识点。

1. 低时延是个系统工程

       根据Wikipedia上描述:Minimizing latency is currently of interest in the capital markets, particularly where algorithmic trading is used to process market updates and turn around orders within milliseconds。 Low latency trading refers to the network connections used by financial institutions to connect to stock exchanges and Electronic communication networks (ECNs) to execute financial transactions。 意思就是降低传输时延可带来高频程序化交易背景下的竞争优势,1笔订单甚至数十笔订单从券商交易系统客户端传入交易所主机排队撮合系统,几微秒或几十纳秒的抢先都会增大成交概率,所以时延也日益成为衡量一个交易闭环系统的关键性能指标。
       低时延是个系统工程,涉及到主机软硬件配置、应用程序、算法设计、存储设备、网络结构和广域线路,每一个环节都对整体时延有重要影响,其中网络结构又包括拓扑设计、设备选型、参数配置和包处理等几个方面。

2. 丢包时延、排队时延、传输时延、串行化时延

       如果把网络时延趋于0做为我们的终级追求,那么如何对这条交易数据传输路径进行调优,使其能尽量做到传输无感知呢?下面我们就来简单分析一下数据包离开主机或PC后的外部时延。
       根据业务边界,我们把交易数据的传输分为两块模型,一块模型是从券商交易客户端下发指令,通过券商内部网络到达券商集中交易机房的中间件,然后由中间件写入数据库,数据库订单记录再通过机房内部网络到达报盘机,最后由报盘机通过广域线路传到交易所前置机。另一块模型是交易所内部网络,简化为从前置机到主机的双向传输。在这两块模型中,券商集中交易机房内部网络和交易所内部网络优化时延的手段是相似的,都是局域网内部的调整。
       交易数据从局域网内部一台主机传输到另一台主机,沿途会经历几种不同类型的时延:丢包产生的时延(Packet Drop Delay)、排队时延(Queuing Delay)、路由交换转发时延(Switch Processing Delay)、传输时延(Propagation Delay)和串行化时延(Serialization Delay)。
       一般而言,丢包和排队所导致的时延对局域网内部总体传输时延影响非常大。如果交换机芯片处理能力低,端口支持的带宽速率不高;或者传输介质受到干扰,在突发流量的情况下,就会产生丢包现象。丢包导致数据包重传,TCP重传前还有一个等待过程(RTO:Retransmission Timeout),这些因素可能会形成数千甚至数万微秒的传输时间损失。另外如果遇到数据传输量大引发交换机出口拥塞,就会导致后续数据包进入出口队列缓冲区,它必须等到队列前方的数据处理完成后才能开始传输,这就是所谓的排队时延。在目前千兆接入的环境下,一般排队时延在微秒级。例如假设交换机端口的Queue Size是64KB,那么千兆接口处理完这个队列数据大概需要510微秒,就是说排在端口对列末尾的数据位需要等待500微秒左右才能离开设备。
       再看下传输时延。我们知道光和电磁波在真空中的传播速度为30万公里/秒。在不同于真空的介质内,电磁波传播的速度会小于光速。但考虑到光纤玻璃1.5的折射率,所以光在光纤中的实际传输速率也只有在真空中的2/3。用距离除以速率可换算出信号在介质中的传输时延:1米的单向传输时延大概在5纳秒(ns),1公里的单向传输时延大概在5微秒。一般远距离数据中心之间通过光纤互联,那么可能会涉及到信号放大、色散补偿、信号再生等一系列光学调整,这些功能由不同光电设备或光模块组件实现,当传输信号经过这些线路设备时会产生额外数百纳秒的时延。

图1 信号在网络介质中传输不同距离的单向时延和双向时延

       所谓串行化时延(Serialization Delay)就是指交换机根据先到先服务原则将当前正在处理的一个数据包帧中所有比特位推向外部链路所需要的时间,串行时延的计算公式是:数据包帧长度 / 链路传输速度,对于64字节长度的帧和1GE的链路出口速率,串行化时延为 64byte*8 / 1000000000 = 0.512微秒,对于256字节长度的数据包帧,串行化时延为 2.048微秒。如果出口速率升级为万兆10GE,那么64字节和256字节长度数据包的串行化时延分别降低为原来的1/10, 即0.05微秒和0.2微秒。根据公式可以看出,数据包越小,出口链路速率越高(相应时钟频率clock rate越高),那么得出的串行化时延越小。
       综上所述,从分析丢包时延、排队时延、传输时延和串行化时延这四个方面我们可以得出采用高速网络传输链路和降低物理连线长度可以明显降低网络整体时延的结论。如果把带宽升级到10G或40G,并把拓扑结构合理调整,这样即使遇到突发流量,网络资源也可以保有余量避免拥塞。

3. 路由交换设备转发时延

       路由交换转发时延的定义就是一个数据位从进入网络设备到被处理转发出同一台网络设备的耗时。
       根据前面提到的券商集中交易机房内部网络和交易所核心交易内部网络,我们集中讨论局域网设备。先来看些数据统计,市场上交换机的数据包处理时延为600纳秒到30微秒不等,路由器处理时间为20微秒到200微秒不等,防火墙处理时间为几微秒到几十微秒不等。
       考虑到设备的适用性和资料的齐全性,我们以思科设备为例,根据其测试公布或经过第三方测试发布的性能指标数据,我们例举几个型号的Catalyst交换机设备(注意这些数值仅供参考用,具体准确性会受到测试仪器、测试方案、设备子卡型号等因素的影响):固定配置交换机Catalyst 3750-G传输64字节数据包时延为7微秒,Catalyst 3750-X传输64字节数据包时延为6.2微秒,Catalyst 4948传输64字节数据包时延为6微秒。
       模块化交换机由于机框,引擎,板卡有多种组合,且不同组合对速率有明显影响,所以比较难测量出一个基准值,下面只提供一些可参考的概念数值:
       表1 模块化交换机数据包转发时延示例

交换机型号所有接入端口加以10%负载时64字节数据包的3层转发时延(微秒)所有接入端口加以90%负载时64字节数据包的3层转发时延(微秒)
Catalyst 45067.4N/A
Catalyst 65097.210-12

       当数据包大小增大为256字节时,Catalyst 4506和3750-X的传输时延分别大约为16.3微秒和8.6微秒。而Catalyst家族中时延很低的固定配置交换机4948E,在传输64个字节数据包和256个字节数据包的情况下时延分别为4.68微秒和6.6微秒。
       从这些测算出的数值可以看到,一般固定配置的交换机传输时延略优于模块化交换机。单台交换机通信负载越少,延迟越低,并且当测试的数据包增大后,转发时延会明显加大。
       现在我们就来讨论一下这些现象,首先固定配置交换机和模块化交换机的产品定位不同,一般而言,在传统的网络架构模式中,固定配置交换机用于接入层,模块化交换机用于核心层和汇聚层,对模块化交换机的要求就是功能多,可扩充性强,可靠性高,背板带宽大,并没有明显的速度要求,数据包进入模块化交换机后,往往会经历两次交换,一次是从进入的端口到背板交换矩阵,另一次是从背板交换矩阵到出口模块,如果数据传输量大,可能还会在各级Buffer中经历排队延迟。但是对于大部分用户来说,模块化交换机的设计要点满足了他们的业务或办公需求,在证券行业相当数量的机房中,模块化交换机依然是各种网络的核心。
       接下来我们研究下为什么随着测试的数据包增大后,转发时延也会明显加大。我们知道交换机在传送源和目的数据包时通常有直通转发(Cut-through switching)、存储转发(Store-and-Forward switching)和无碎片转发(Segment-free switching)三种交换方式。其中无碎片转发是直通转发的变形,交换机在转发前先检查数据包的长度是否够64个字节,如果小于64字节,则判断为假包(或称残帧)且实施丢弃;如果大于64字节,则发送该包。
       目前存储转发仍是传统交换机的主流交换方式。交换机把输入端口的数据帧先存储在缓存中,然后进行CRC检查。若检测到该帧出现差错,则丢弃该帧,否则取出该帧的目的地址,通过查找MAC地址表获得输出端口,再转发出数据帧;并且存储转发支持不同速度端口间的转换,保持高速端口和低速端口间协同工作,这在以前经常存在网络广播、包碰撞的年代,存储转发模式确实能有效地改善网络性能。正因为数据包在被处理前,交换机先要接收下完整的数据包并校验,所以这部分形成了固定时延。这导致在Input端口速率固定的情况下,接收越大的数据包产生的时延也越大,上述交换机的测试结果正是反映出这个现象。思科的Catalyst系列交换机都是属于存储转发模式的交换机。
       直通转发是指交换机在接收数据帧时,一旦检测到6个字节的目标MAC地址后就立即进行转发操作。但这时它并不是一个完整的帧,一是因为数据包内容并没有被交换机保存下来,所以无法检查所传送的数据包是否有误,不能提供错误检测能力;二是由于没有缓存,不能将具有不同速率的输入/输出端口直接接通,而且容易丢包。直通转发优点在于端口交换时延小,交换速度快,过去一般用于小交换机的设计。 随着局域网内部普遍升级到千兆万兆传输速率,各种低速端口纷纷被淘汰,不同速率端口间的转换需求越来越少。另外伴随硬件芯片的发展和算法的进步,目前许多新一代的低时延交换机都采用了改良的直通转发模式。

图2 数据帧结构

       改良的直通转发是利用底层电路控制器(MAC controllers)、ASIC和TCAM(Ternary Content Addressable Memory, 一种三态内容寻址存储器,主要用于快速查找ACL、路由等表项,TCAM中每个bit位有三种状态,除了0和1外,还有一种“don’t care”状态,所以称为三态,它是通过掩码来实现的)的技术发展, 使得交换机能根据收到的部分数据帧包头(前14个字节包括了源地址SMAC,目标地址DMAC,帧类型EtherType), 立刻预判是否要检查更多的包头(后续大小为40个字节的和IPv4相关的三层四层包头),如果使用10G的接口带宽,那么大约需额外再耗费100纳秒的包头处理时间。这些改良能使直通转发交换机在处理某些需要进行数据包深度检测的网络功能如PortChannel端口负载均衡、ACL、QOS的同时,又对整体时延影响极小。如果检测到坏包,直通式交换机打上标记后继续转发,由接收方设备根据数据包侦校验FCS字段实施丢弃。所以现在的直通转发式交换机在软硬件上的设计比存储转发式要复杂。       下图是采用SoC(System on Chip)架构设计的直通式交换机Arista 7050X数据包处理芯片简化结构图:

图3 数据包处理在Arista 7050X单一芯片内的流程实现

       从获取资料便捷性考虑, 我们还是以思科的产品为参照了解一些转发指标。
       思科的Nexus系列交换机,特别是固定配置的Nexus交换机,都是采用直通转发模式,这些产品被定位于低时延交换机。例如,进出都是万兆端口的前提下,Nexus 3064传输64字节数据包的时延为0.92微秒,Nexus 5548传输64字节数据包的时延为2微秒,特别是采用SoC芯片架构的Nexus 3548传输64字节数据包的时延为250纳秒,如果开启WARP模式(思科文档上称之为算法加速引擎,利用特殊分配的内存区域实现多道流程一次性处理, 缩短数据包在内部的转发路径),那么3548传输64字节数据包的时延仅仅只有190纳秒。
       直通转发比存储转发少了入口接收完整数据包的时延,可以理解为无论数据包的大小,同一台直通交换机按照FIFO原则计算出的传输不同大小数据包的时延应该是差不多的。我们通过继续查找资料获得了进一步的数据,Nexus 3064在传输256字节,512字节,1518字节,甚至9216字节大小的数据包时,交换机时延稳定在0.9-1.3微秒左右,Nexus 3548在传输256字节,512字节,1518字节,9216字节大小的数据包时,交换机时延稳定在250纳秒左右, 开启WARP模式,稳定在190纳秒左右。

图4 Nexus 3548在普通模式和WARP模式下转发不同大小数据包的时延

       另一款直通式交换机Arista公司的7150S,时延稳定在350-380纳秒之间,转发性能也相当高。

图5 Arista 7150S系列10G交换机数据包转发时延

       通过上文的论述,我们大致理清了数据包在主机外部传播时遇到的丢包时延、排队时延、路由交换转发时延、传输时延和串行化时延。下面让我们看看还有哪些影响总体网络时延的因素。

4. 低时延网卡

       现在把目光移向网络管理和系统管理的灰色边缘地带——工程师少有触及且容易忽略的主机网卡。做为网络整体时延的组成部分,网卡负责把主机内存中的待发送数据移到主机外的网络链路上,并做为通讯发起方和上游交换机协商网络传输参数。资料表明一般服务器网卡的数据包处理时延为2.5到32微秒,大部分网卡是存储转发模式(网卡把待发送的数据包帧全部接收下来后,再进行校验),需要操作系统协同完成网络协议的处理工作。
       目前市场上有一些新的专定位于低时延数据处理的网卡,其优势就在于把需要操作系统来完成的工作(TCP/IP Stack, Network Driver等)移交到网卡上的专用芯片来处理:传统上处理TCP/IP网络流量会占用大量主机资源,特别是在收发大量数据包时,会引发大量的网络I/O中断,为了减轻主机的压力,出现了一种称为TCP Offload Engine(TOE)的技术,该技术把TCP/IP协议栈的功能延伸到网卡上的集成硬件FPGA中进行,主机只承担TCP/IP控制信息的处理任务,TOE网卡能让应用程序完成一次完整的数据处理进程后才触发一次中断,能显著减轻主机对中断的响应负担。此外部分网卡还支持PCI Express 3.0, 使得机箱内部连接带宽2倍于传统的I/O带宽。这样通过减少主机CPU负担,提升内部总线,来降低主机网络层处理时延。一些产品宣传资料上标明的时延为1微秒到3微秒。

5. 网络拓扑设计

       对于一些时间不敏感的业务和办公类网络,原则就是按需建网,无论是三层模式还是大二层模式,只要管理方便、扩充方便、故障能自愈、符合安全等级即可。一套网可以承载多个业务流量,这里我们不做展开。
       而对于有时延要求的网络,如交易网、主机心跳网、行情网等,那么设计时就要以时间为重要参考指标。这些专用网是未来高频算法交易的承载体,每个网根据负载只限跑一、二种业务,网络设计说简单也简单,我们从上文可以知道每个型号的交换机的时延数据各不相同,线缆长度和网络带宽对总体时延也有明显影响。那么在成本投入允许的范围内,选择最高型号、最低时延的交换机就可以了。一般型号高意味着背板带宽、包转发速率、引擎CPU性能也高,另外就是尽量打造全万兆网络,万兆接入不仅使串行化时延大幅缩小,还能处理突发大流量的冲击,特别是能避免不同速率端口间的转换。关于这点我们再扩展一下,如果数据包在直通式交换机不同速率的端口间交换,那么在某些速率流向的情况下,硬件设计会导致交换机运行模式自动切到存储转发模式。以Nexus 3548和5548为例,当处于万兆Input万兆Output时,交换机运行在直通模式下;当处于万兆Input千兆Output时,交换机仍运行在直通模式下;当处于千兆Input万兆Output时, 交换机就自动转换为存储转发模式。一旦转为存储转发模式, 就必须加上数据包入口时延而且交换机负责处理数据包的底层电路也会不同(千兆万兆由不同的MAC电路处理)。
       专用网的拓扑设计应尽可能简单化、扁平化,一定要减少内部网络跳数。因为除了每台设备有转发时延外,设备上的接口卡和多余的连接线缆等也会产生时延。我们设想一个模型,交易中心只有一台高速交换机,所有主机都接在这台交换机上,考虑到程序化交易的公平性,所有主机到交换机的链路长度相等,接口模块一致。特别在部署高频低时延交易环境时,需要注意所有订单前置机到交换机的布线长度、链路速率、传输介质应该相同,这是公平交易的一环。
       假设主机A和前置机B到交换机的光纤距离都是20米,且配置相同的高速网卡(如Solarflare),中心交换机为Nexus5548,交换机端口接入的万兆光模块为SFP+SR,那么在理想无阻塞状态下,主机A向前置机B传输64字节数据包网络单向时延为:传输时延(20*0.005+20*0.005=0.2微秒)+交换机转发时延(2微秒)+ 进出交换机端口SFP模块时延(0.1+0.1=0.2微秒 = 2.4微秒。如果算上主机内部网卡和TCP/IP STACK协议栈处理,那么理想状态下从主机A到前置机B的数据包完整网络层通讯时延为:外部网络时延2.4微秒+两端网卡处理时延(2.5+2.5=5微秒)=7.4微秒。
       以上我们探讨了如何在网络结构、硬件搭配和线路带宽上降低网络时延,下面将把目光转向网络设备的自身资源分配和参数配置,了解一下还有哪些优化措施可以帮助降低时延。

6. 设备资源分配

       我们知道,当交换机上大部分端口都处于高流量状态时,板卡和引擎上的CPU或ASIC工作负荷会增大。那么通过调整流量模型把端口实际流量进行分流可显著降低芯片的负载及Buffer的使用。分流的方式可以把高流量端口的工作分担到一组端口上,也可以调整路由把几个高流量通讯分担到不同交换机处理, 或者更为细致地调整端口编号把高流量分配到同一台交换机的不同芯片上处理。 一般而言,一块芯片负责处理4个端口或8个端口的通讯,根据交换机或模块型号,每隔4端口或8端口分配高流量负载,也能降低硬件的负荷,减少出现排队和丢包现象。

7. 设备的Running-config

       关于网络设备的参数配置Running-config是否也会影响到网络的总体时延,我们参考思科的公开资料:根据交换架构的设计,最复杂的Running-config所导致的时延竟是最简单配置的3到5倍。其实也可以理解,把交换机的所有功能所有feature都配上,必然出现大量进程,每个运行中的进程都会占用CPU或ASIC资源。数据包一进入交换机端口就要按照这些Running-config的规则被不同功能的芯片处理,处理步骤越多,时延也越长。这就象我们平时用的PC一样, 同时打开很多应用,PC处理程序的响应肯定会变慢。例如Nexus 3064PQ,运行在不同复杂度的Running-config下,最高可相差大约100纳秒的时延。
       有些常用的特性如ACL和NAT,开启后也会增加CPU负担。现在通过厂商硬件芯片优化后, 这些特性对设备整体性能和时延的影响已很小。 例如Catalyst 4948E传输64字节数据包在通常情况下的时延是4.68微秒,配置了ACL后时延也是4.68微秒。 ASR1K路由器传输64字节数据包在通常情况下的时延是20微秒,配置了NAT后时延是30微秒,配置了防火墙功能后时延为25微秒,这比采用独立路由器加独立防火墙的总时延肯定要小。又如上文中提到的Nexus 3548低时延交换机,无论是否开启ACL或NAT,一般情况下时延都保持在250纳秒。

图6 ACL对Catalyst 4948E的包处理时延影响

8. 着手改善时延

       通过前面的分析,我们可以初步归纳出几种减少网络时延的方法:

  1. 网络拓扑尽量结构简单,减少层次,减少设备,功能专一化。
  2. 网络内部尽量保持同一种速率,升级到10GE。
  3. 在符合网络设计需求的前提下,选用相对时延小性能强的网络设备。
  4. 简化网络配置,只开启必须的功能,路由进行汇总。
  5. 根据流量模型合理分配接入端口和调整传输路径。
  6. 按需规划综合布线,控制长度,远离干扰源。
9. 市场上有哪些低时延交换机

       下面的汇总表例举了目前部分厂商的低时延以太网交换机 64字节数据包转发时延(数据来自厂商标称的指标,且都支持10G/40G):
表2 不同厂商低时延交换机转发时延

厂商名称 交换机型号 转发时延(ns:纳秒)
Arista 7250X 550ns
Arista 7150S 380ns
Juniper QFX-3500 900ns
Juniper QFX-5100 550ns
Cisco Nexus 3548 普通模式250ns WARP模式190ns
Cisco Nexus 6004 1000ns
华为 CloudEngine 6800 700ns
Brocade VDX 6740 850ns
H3C S6300 < 1000ns="">
Mellanox SX1710 270ns
Extreme X670-G2 600ns
Dell Force10 S5000 800ns

       注意这些指标仅仅做为参考用来辅助设备选型,更重要的是需要考察是否符合网络规模的需求,是否能融合进当前网络。如指标最好的Nexus 3548和Mellanox SX1710既能做接入层,也能做汇聚层或核心层,但汇聚层核心层除了讲求速度外是否还有其他特性要求?这两款交换机能否满足?所以除了转发速率以外,还要考虑很多其他指标,要进行相关指标的确认和容量测试。即便同样是Nexus 3548,WARP模式比普通模式更快,也是因为在资源占用上进行了裁减,我们从下面的对比就可以看出来:

图7 Nexus 3548在普通模式和WARP模式下的部分容量值


       我们汇总四款适用于接入层或单层次网络的交换机的容量指标,表中的数值来源于厂商公开资料:
表3 四款适用于接入层或单层次网络的交换机的容量数值

华为 CE6850 Cisco Nexus3548 Juniper QFX-3500 Arista 7150S
MAC地址表 128K 64K 120K 64K
IP单播路由 16K 24K 16K 70K
IP主机路由 16K 64K 8K 64K
IP组播路由 4K 8K 3.5K 20K
ACL 4K 4K 1.5K N/A

       另再汇总四款适用于网络汇聚层或核心层的交换机的容量指标,表中的数值来源于厂商公开资料:
       表4 四款适用于网络汇聚层或核心层的交换机的容量数值

Cisco Nexus6004 Juniper QFX-5100 Arista 7250X Extreme X670-G2
MAC地址表 256K 288K 288K 288K
IP单播路由 32K 128K 16K 16K
IP主机路由 128K 128K 208K 136K
IP组播路由 32K 104K 16K 16K
ACL 4K 4K 4K 4K
IGMP组播组 32K N/A 288K N/A

       随着技术发展,表格中的数值和型号会不断攀升,决定交换机性能的关键在于各级芯片。主流交换机厂商一般采用两个模式:一是完全采用自主芯片或自主芯片和商业芯片相结合(成本高,自主控制力强),一是完全采用商业芯片(成本低,但会受到芯片厂家牵制)。如Mellanox交换机 、Cisco Catalyst系列和Nexus 3548/5K/6K等交换机都是采用自主研发的芯片,特别是Mellanox系列和Nexus 3548用的都是厂商自主产权的高性能超低时延芯片。而Nexus 9K就是自主芯片和商业芯片相结合,Juniper的部分交换机也是自主和商业相结合。
       Mellanox和Broadcom是两大商业芯片提供商,Broadcom的Trident+芯片被Juniper QFX-3500,Cisco Nexus3064,Arista 7050S等厂商采用,2012年Broadcom推出了TridentII,并于2013年量产,其性能更强,支持更多个40G端口, Packet Buffer也从Trident+的9M升到TridentII的12M。Juniper QFX-5100,Cisco Nexus9K,Arista 7050X等都是TridentII的用户。其他诸如H3C,Extreme等厂商也是Broadcom硅芯片的客户。另一大芯片商Mellanox在InfiniBand芯片领域颇有建树,其SwitchX是多协议的,可让厂商混合搭配以太网和InfiniBand。2012年推出的SwitchX-2芯片,就提供给Facebook的“开放计算项目”(OCP)。Mellanox SX1710采用了自家的SwitchX-2以达到超低时延。所以我们从这两家芯片商的动向和产品线路图就能大致预测出众多交换机厂商下一代设备的上市时间和指标范围。
       和网络低时延相关的一些其他技术内容如PTP(Precision Time Protocol 精确时钟同步协议)、RDMA over Converged Ethernet(RoCE)技术标准、交换机时延测量方法、操作系统网络参数设置、虚拟交换机对传输性能影响、新一代低时延微波传输等,限于篇幅,这里不做展开。

参考资料和配图来源:

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多