51CTO首页
AI.x社区
博客
学堂
精品班
软考社区
免费课
企业培训
鸿蒙开发者社区
WOT技术大会
IT证书
公众号矩阵
移动端

APM从入门到放弃:可用性监控体系和优化手段的剖析

原创
移动开发 Android iOS 开发工具
在移动互联网时代,一款应用是否成功,用户体验是一个关键的因素。APM的发展使得用户体验越来越完善,本文通过90年代互联产品性能优化的发展过程到今天移动互联网时代下的APM可用性监控体系,如何去解决日渐复杂的业务导致功能不断迭代所突发的致命bug,以及日益增长的用户和膨胀的数据导致流量过大所出现的一些问题。

【51CTO.com原创稿件】在《黑客帝国》电影中较为经典的一幕是让Neo在红药丸和蓝药丸中做出选择。红药丸作为一个跟踪程序,帮助Neo定位物理身体位置,无论在哪里,出现任何问题都能够第一时间定位并解决。而开发者基本都知道,想解决大部分的功能性问题的难点基本就在定位上,而电影里面出现的一些人工智能、机器学习、虚拟现实的技术,也只能够在科幻电影中才能看到。

季度活跃设备增长趋势

今天,在移动终端爆发以及用户需求的推动下,移动应用的“数量”和“体量”急速扩大,APP性能数据在优化产品上变得越来越重要,国内大批APM厂商仿佛一夜间遍地开花,整个监控体系也从服务端到APP端再到H5端不断的加强和改变策略来适应不同的场景需求,使得监控和优化的本质上已经发生了变化。

APM的雏形发展

在1996年时,Tivo与HP公司就从应用程序层面出发,他们认为网络无疑就是应用的速度。直至1998年,面向以组件为中心基础建设监控的APM产品出现,直到2011年,移动设备的普及和APP应用市场的爆发,让大家对移动端的性能体验要求也越来越苛刻。

在这个时候,国外的APM行业New Relic和AppDynamics已经在APM领域拔得头筹,国内一些APM厂商看准移动的这个趋势,APM仿佛一夜之间遍地开花,直至今日,作为国内比较具有代表性的APM厂商有:听云、OneAPM、云智慧、博睿等,当前BAT领域也跻身这一领域,阿里百川码力APM(简称“码力APM”)也在云栖大会中发布公测。开发者无需从零开始构建性能探针、数据平台和控制台,就可以通过可视化、可运维的方式长期监控应用性能、及时解决应用中存在的问题。  

▲ APM 业务与 IT 发展关系变迁

APM可用性度量体系

如今,国内APM业务竞争越来越激烈,大家纷纷在可用性、用户体验上发力。比如,大家用手机淘宝,明显感觉稳定性和流畅度比国内其他电商APP好很多,这不仅仅是因为他们有一堆优秀的开发工程师,更关键是其背后那一套完善的性能监控度量体系。

通过性能监控体系,app上发生的性能指标都会被实时上报,而码力APM服务端会基于这些指标进行聚类和分析,聚合出问题和性能瓶颈,同时完善的日志信息也将支持开发工程师及时修复和优化。

阿里技术专家陈武认为,在性能优化方面,以往的度量是通过APP的打开率来进行对比,很多都是非常主观。而度量体系里面面临的一个很大的问题是常态化。那么,应该如何建立起这一套可视化的性能度量的体系呢?

阿里百川将影响用户使用的性能指标分为可用性度量和体验度量。

1、 可用性度量

可用性包含app可用性和服务可用性。app可用性问题中最常见的就是crash,而用户遇到crash之后,大部分会选择直接卸载app;服务可用性问题则包含网络连接和服务端错误,这类问题往往可能造成用户购买、订阅等关键操作不可用,从而导致资损,而这类问题若长期未能解决,也会导致用户流失。

这类问题需要第一时间被修复,越早修复,止损的效果就越好。

这需要客户端探针具有强大的采集能力。探针SDK将负责采集用户由于线程异常、内存溢出、手机杀进程等各种原因导致的崩溃,并捕获到尽量全面的环境信息,和用户操作轨迹来帮助开发者还原用户操作,定位问题。同时,对网络请求部分也是同样,探针SDK需要支持自动采集网络性能指标,并捕获错误网络请求的日志,来辅助开发工程师解决问题。

但是探针在用户app端采集的均是单一的事件,若有1000个用户出现可用性问题,那么服务端接收到的可能就是1000份日志。让开发工程师在海量的日志中排查问题,显然可行性不高。这就需要APM服务端实时对这些日志进行语义分析以及高效的聚类,比如,将1000条用户日志聚合为3个问题,通过控制台反馈给开发者。这将大大提升开发工程师排查和解决问题的效率。

2、 APP体验度量

APP体验是影响用户留存和活跃的关键,大家对APP使用过程中“如丝般顺滑”都具有天然的好感。但是目前市场大部分APP的体验依旧非常差,用户常会面对卡顿、图片加载失败、页面长时间等待等各种不良体验。这个时候,非常需要有一个系统体系化的去陈列和度量这些体验类问题。

APM控制台对卡顿的处理方式和崩溃类似,同类型的卡顿将被聚类在一起,发生该卡顿的用户详细日志也聚合在一起可以翻页查阅。而对图片加载失败等,页面元素无法正常显示的问题,则可以关注该图片所在静态资源的服务主机是否异常(单分钟请求量过多、图片过大等)。若该静态资源服务正常,则可以关注请求该图片的URL的错误率,可以反推是否为图片本身的问题。

在性能优化的量化方面,如何帮助企业去做定制?陈武认为,应该串联关键路径所需要的全部URL,从关键路径整体来看服务的健康度指标,而非关注全部的URL。比如通过网络性能监控,开发者无需对所有的URL进行关注,不同的开发者关注的核心业务不同,大家关注的URL也不一样。比如,在电商的场景,一个关键的路径是用户通过登录,打开商品,进入详情,然后下单到支付,通过把对应的关键路径所有的URL整合在一起,保障这条关键链路的性能,才能够强化核心业务的服务以及稳定性。

APM的可用性检测方式

▲ 阿里百川码力APM的监控体系

对于加强应用的可用性,APM一般都采取应用监控结合服务监控的形式,使得开发者实现端到端的全链路性能管理。在码力APM监控体系中,阿里巴巴技术专家熊奇介绍了码力APM在监控体系里面的应用监控、服务监控、数据库以及消息推送等性能监控,主要通过以下方式来完成:

★ 在应用监控上,采集了iOS、Android应用的内存、CPU、崩溃、网络等方面的性能数据;

★ 在服务监控上,支持Tomcat、Jetty、JBoss容器和Spring、Struts等框架的性能检测;

★ 支持MySQL等SQL数据库和Redis、Mem cache等NoSQL数据库的性能检测;

★ 码力APM还提供了支持淘宝消息服务TMC、分布式框架Dubbo、淘宝API调用的性能检测。

对于数据采集之后会统一进入可以承载海量数据的存储系统和日志系统,统计系统会利用落地的数据完成数据的计算处理、生成报表,帮助开发者长期跟踪应用和服务的性能,而告警系统则会根据规则在问题发生时发出短信、邮件等即时告警,从而帮助开发者及时解决问题,降低损失。

可用性的度量检测方式-性能

[[174377]]

在应用开发时,程序错误、主线程卡顿和资源使用超过系统限制导致的崩溃,是最严重、也是需要首先解决的问题。

通常开发者会借助模拟器、Instrument或者自动化测试发现一部分问题,但是测试往往难以覆盖用户使用场景下的设备、网络等环境。如果借助于社交媒体或者邮件反馈渠道,虽然可以有限地拿到真实的用户反馈,但是用户往往不能清楚的描述出复现问题所需的信息,往复沟通成本极高。所以,在客户端上,码力APM通过以下检测方式来收集应用崩溃信息。

 

码力APM在信号捕获方式中,通过sigaction设置信号中断时的回调,这样,就可以在回调中根据程序运行状态生成对应的崩溃日志。此外,对于SIGARBT(abnormal termination),我们还需要通过NSSetUncaughtExceptionHandler来获取未捕获异常的堆栈,来补全崩溃信息。

而后,把崩溃日志上报到码力APM,会依据崩溃日志的堆栈信息,聚合同一类型的崩溃后写入数据存储。同时,告警系统可以依据崩溃次数、崩溃率等规则,即时发出告警。

此外,码力Apm提供了dSYM上报脚本,在Xcode的build phrase中添加脚本,就可以在编译成功后自动上报dSYM文件。通过对dSYM文件的解析,重新聚合后写入数据存储,聚合可以减少高达90%数据库行数;同时,也实现了崩溃日志符号化。不依赖mac环境符号化,更好地利用云计算平台服务更多开发者。

第二种技术是卡顿检测,卡顿检测的基础是RunLoop,通过RunLoop Observer监听主线程RunLoop状态的变更。在这里,把RunLoop当作在操场上跑圈的运动员,把Before Sources当做每圈的起点,同时另外开启一条线程作为计时员,每5秒判断一次RunLoop是否跑过一圈。如果5秒内RunLoop没有完成一次RunLoop,则视为主线程卡顿。在发现主线程卡顿后,会生成卡顿日志,如果是复现的卡顿,可以选择不重复上报。

此外,针对设备不同的运行时期,如启动阶段、后台阶段、空闲阶段,我们会动态调整阈值,降低检测的开销。

对于无法通过信号捕获、卡顿检测的崩溃,码力APM引入了应用中止检测,中止检测虽然不能还原崩溃现场,但是可以揭示问题的存在。在应用进入active状态时,码力APM在持久存储上设立一个标志位,表示程序在正常运行。在应用退出active状态或检测到崩溃时,码力APM就清除持久存储上的标志位,表示程序在已知的情况下退出。这样,在下一次应用启动时,如果持久存储上的标志位为真,则说明应用上一次运行在未知情况下退出,这种情况码力APM就计为应用非正常中止上报。

同时,为了过滤因为电量耗尽导致的关机,码力APM还增加了电量检测,在低电量时,清除标志位,避免中止误报。

可用性的度量检测方式-网络

 

[[174378]]

请求错误、流量开销高、被运营商劫持等网络问题是应用开发时另一类棘手的问题。当然我们也可以借助模拟器、Instrument或者自动化测试发现简单的网络问题,但是测试难以覆盖复杂的用户网络环境,也难以导出网络性能数据进行长期比对监控。如果使用手工埋点的方式记录网络性能,一方面,我们需要应对多种系统网络接口,另一方面,我们需要同步应用网络代码和埋点代码,维护成本将会居高不下。

为了监控应用在真实网络环境中的性能,码力APM中引入了无痕埋点的网络性能监控,在网络检测中引入三种注入技术,帮助开发者长期监控应用的网络性能,优化产品用户体验。

第一种是Method Swizzling。每一个NSObject类都包含一个isa指针,指向objc_class结构体,而每一个objc_class结构体又包含一个methodLists指针,指向objc_method_list结构体数组,在objc_method_list里又包含一个objc_method结构体成员,且每一个objc_method包含一个method_imp指针,指向方法实现。

因此,只要能修改method_imp的值,我们就能替换原有的实现。在<objc/runtime>中,通过class_getClassMethod和class_getInstanceMethod取得objc_method结构体指针,而后通过method_getImplementation取得方法的原始实现地址originIMP,之后在imp_implementationWithBlock生成新实现imp的参数block里,调用原始实现,就可以原有行为前后加入网络性能埋点行为。最后调用method_setImplementation替换方法实现。这样,任何调用都将使用新的实现。

 

第二种技术是Proxy。在Objective-C里,NSProxy是除NSObject外唯一的根类。NSProxy是一个实现了NSObject协议的抽象类,它的正常运作需要子类override -methodSignatureForSelector:方法为sel提供方法签名,以及-forwardInvocation:方法来完成调用的转发。

使用Proxy来注入NSURLConnection、NSURLSession等对delegate的回调。具体来说,在delegate proxy收到消息时,如果不是目标协议方法,则通过消息转发机制,转发给原delegate;如果是目标协议方法,则直接调用proxy实现,在proxy实现中委托调用原delegate;此外,多数协议和协议方法都是可选的,因此,在proxy的实现中需要实现-conformsToProtocol:和-respondsToSelector:方法来声明proxy额外加入的协议和方法。这样,我们就能在不影响原有回调的同时,增加网络性能埋点逻辑。

第三种技术是fishhook。使用fishhook来替换动态链接库中的C函数实现,具体来说是CFNetwork和CoreFoundation中的相关函数。这里,以开车的模型来解释动态链接。设想一名新手司机开车从巴黎到罗马,因为他不知道路线,于是他先去咨询老司机;老司机告诉他正确的线路,这一次他可能还会绕点路,但下一次,他就会按照老司机的建议直接开到罗马。

相应的,在程序运行时,动态链接的C函数dynamic(...)地址记录在__DATA segment下的__la_symbol_ptr中;初始时,程序只知道dynamic函数的符号名而不知道函数的实现地址;首次调用时,程序通过__TEXT segment中的__stub_helper取得绑定信息,通过dyld_stub_binder来更新__la_symbol_ptr中的符号实现地址;这样,再次调用时,就可以通过__la_symbol_ptr直接找到dynamic函数的实现;如果我们需要替换dynamic函数的实现,只需要修改__la_symbol_ptr即可。具体的实现方式,可以参阅Facebook的开源框架fishhook。

加强可用性的优化手段

通过以上两种检测方式,基本能够大部分的性能和网络需求,使得开发者能够满足如今移动互联网下用户的苛刻的需求,那么,建立起来的度量体系后,了解的具体的问题后,我们应该如何去解决这些问题来提升可用性呢?

1、网络安全

运营商、DNS被劫持问题是应用开发时一类棘手的问题, 解决方案也比较多。51信用卡技术总监汪睿认为,51信用卡作为金融属性的产品,基于安全考虑会放在第一位。解决方案主要是基于全栈HTTPS的方案来处理,但会带来一些成本和性能上的损耗。甚至可以像FaceBook、google等一些解决方案,使用HTTP2.0方式,这取决于公司和开发者自身去评估实现的成本。汪睿还介绍了早起的一个过渡方案,那就是HTTP的DNS方式,通过获取一个IP表通过IP来直接连接,可以避免HTTP劫持的问题。

而网络是一个端到端的技术,阿里高级技术专家陈武认为,从电商的场景看,首先要保证服务端的稳定性,服务端可以有反刷,限流,单元化,异地容灾,服务降级等策略保证连接的稳定性。另外,客户端的角度主要看连接链路和数据量。链路里面资源可以做多CDN的备份,通过HTTP DNS或者HTTPS,HTTP2.0来反劫持。在链路稳定的基础上,接着去保证传输的效率,这里面可以通过就近接入,连接复用,提升压缩率,使用二进制协议等技术来减少包大小。当然,这里面最重要的是端到端的网络监控体系,这样在网络服务治理上会更有抓手。

2、系统降级

降级的解决方案,是系统性能保障的最后一道防线,从性能优化的角度上说,没有100%完善的设计,总会有一些意料突发的情况导致性能恶化。所以,在系统设计时,必须做好降级设计。

饿了么移动首席架构师王朝成认为,在饿了么517大促活动上,服务器端承受非常大的压力,这个时候会通过降级部分服务的方式,来确保大促秒杀这种场景得以正常运行。但是,在用户端上,以及APP,还在不断积极的发送用户请求和数据,反而增加服务器集群的压力。这个时候,王朝成表示,他们会考虑把一部分的SDK或者APP上的服务也进行降级,来减少服务端在分析数据上的压力。

降级分为手动降级和智能降级,在策略上分为流量降级、效果降级、功能性降级。流量降级主要表现在通过主动拒绝处理部分流量早餐部分用户服务不可用。而效果降级和功能性降级都表现为服务质量的降级,一个是通过在流量高峰时期用相对低质量、低延时的服务来保障所有用户的服务可用性,另外一个是通过减少功能的方式来提高用户的服务可用性。

3、网络性能

从数据结构上,需要根据不同的业务场景来选择合适的数据结构,在数据流量较少的情况可能客户端上表现不出什么区别,当在数据流量过大,且数据结构复杂的时候很可能就是直接影响到APP的性能。

类似餐饮领域“饿了么”这样的应用,数据发送的频率使得据量会非常大,对用户来说可能没有什么感知,但是商家接收大量的订单,数据量影响很大,感知比较明显。王朝成认为,可以考虑一些新的协议(Protobuf, Flatbuf)来优化数据量,比如HTTP2.0可以压缩http协议的header,使用encoder来减少需要传输的header大小,通过通讯双方各自cache一份header fields表,对于相同的数据不再通过每次请求和响应发送,又减少了需要传输的大小。再一个是采取二进制的协议,只认0和1的组合,通过把原来http1.x的header和body部分用frame重新封装,实现方便且健壮。通过内容压缩与并发传输机制,在低速、不稳定的无线条件下,较少其http body的发送大小,改善用户体验和资源效率。

▲ http1.x和http2.0协议关系

同时,阿里高级技术专家陈武也表示,如果在链路没有问题的情况下,那么必须在整个网络传输层要尽量快,不然很容易出现timeout。所以,第一要从协议层,在协议层里面通过http2.0来减少包头的压缩,同时支持服务端push消息,且通过双通通道,对通道复用更快。第二是从数据层,数据可以通过二进制压缩。在整个网络连通率较低的时候,将打包拆成小包,达到很好的传输效果。

4、动态热修复

所谓热修复,就是使用热补丁动态修复技术,通过向用户发送Patch,在用户无感知的情况下完成一些致命bug的修复。51信用卡客户端负责人汪睿认为,在移动客户端上最大的一个问题是发版,对于iOS的用户来说,整个修复流程比较漫长。需要提交审核,但是在这段时间有可能已经错过很多用户。他认为,热修复技术能够很快并及时的在线进行修复,通常在使用的过程中就完成的修复过程。

在热修复技术上,Android常用的是基于Android dex分包方案,而iOS可以利用JSPatch,它可以使得你用JavaScript书写原生iOS APP,只需要在项目中引入极小的引擎,就可以用JavaScript调用任何的Objective-C的原生接口。

总结

以上所谈到的性能优化手段基本是为了解决三种情况所造成的问题:1. 日渐复杂的业务导致功能不断迭代所突发的致命bug修复方式,2. 日益增长的用户和膨胀的数据导致流量过大,3.网络安全和内存开销的问题。

本文通过不同的场景来分析移动性能优化的模式,可以通过确定场景下解决某一类型的问题。当然,我们不能仅仅通过了解性能优化所解决的问题以及手段,更重要的是需要清楚该问题所发生的场景、原因需要的成本。

【51CTO原创稿件,合作站点转载请注明原文作者和出处为51CTO.com】

 

责任编辑:林师授 来源: 51CTO.com
相关推荐
面向大型网络可用性监控工具
没有任何一家企业能够离开网络可用性监控工具。评估和修复网络设备故障、保障它们的可用性,是现代数据中心的一个基础需求——特别是那些要求保证应用与服务持续可访问的企业。

2017-03-07 16:49:45

API网关入门放弃
假设你正在开发一个电商网站,那么这里会涉及到很多后端的微服务,比如会员、商品、推荐服务等等。那么这里就会遇到一个问题,APPBrowser怎么去访问这些后端的服务

2019-07-02 14:17:18

API网关 网关 流量
什么是系统可用性?如何提升可用性
可用性是我们在做系统设计时一个重要指标,它确保用户可以可靠且持续地访问服务。本文我们将探讨什么是可用性、如何计算可用性以及提高可用性的一些常用策略。

2024-08-13 15:42:19

ElasticSearch 如何配置Uptime 监控组件可用性
现在互联网架构随着用户的增加,而越来越复杂,可能要有成千上万个不同的组件和不同的实例,对这些组件可用性的监控是提供高可用服务的关键之一,Elastic为此推出了UptimeApp。

2021-06-02 08:11:59

ElasticSear Uptim 监控
Linux提权:入门放弃
日站就要日个彻底。往往我们能拿下服务器的web服务,却被更新地比西方记者还快的管理员把内网渗透的种子扼杀在提权的萌芽里面。Linux系统的提权过程不止涉及到了漏洞,也涉及了很多系统配置。一下是我总结的一些提权方法。

2017-03-25 20:30:15

网站首页设计可用性PET
做好网站首页是一件让人头疼事事情,PET(Persuasion,Emotion,Trust,说服、情感、信任),可能涉及到心理学,人种学,营销学等陌生的知识。本文就是从PET方面讲下如何做好网站首页。

2011-02-18 17:54:36

网站首页 PET
规划高可用性站点恢复
MicrosoftExchangeServer2010包括一个新的用于邮箱恢复的统一框架,该框架包括一些新功能,如数据库可用性组(DAG)和邮箱数据库副本。尽管可以快速简单地部署这些新功能,但是必须先进行认真规划,以确保使用这些功能的任何高可用性和站点恢复解决方案可以达到预期目的和满足业务要求。

2010-12-31 14:36:15

ExchangeSer
可用性测试权衡之道
对于可用性测试,业内人士存在一些普遍认可的原则。它们神圣地如同自然科学里的理论,似乎我们只能对其言听计从、俯首称臣才能践行出“好的可用性测试”。其实,即便是科学,它的一个特征也是“可证伪性”——理论的正确性总是存在前提条件的。真理再向前一步就成为谬误!

2012-09-07 09:57:14

Python文本分析:入门放弃
前面说了小爱同学已经初步学会了分词和画词云图,但是在这个过程中他还是遇见了一些问题的。其中最主要的两个问题是:正则表达式和同义词处理。

2020-07-07 10:50:19

Python 丄则表达 文本
JavaScript30秒, 入门放弃
最近很火的github上的库30secondsofcode,特别有意思,代码也很优雅。能学es6、自己翻译,能学英语、代码很美,很优雅,美即正义、函数式表达,享受等。

2017-12-25 11:15:06

Java Array 数组
Redis集群可用性
在本文中,我们将研究Redis集群的高可用性、Redis集群的自动故障转移及Redis集群中的脑裂问题及其解决方案三个主题。

2024-02-27 09:48:25

Redis 集群 数据库
Linux集群之高可用性
系统的可靠性越高,平均无故障时间越长。系统的可靠性越高,平均无故障时间越长。Linux集群的高可用性,对服务器正常运行起着至关重要的作用。

2012-02-13 23:20:18

linux 集群 高可用
Windows Server 2008安全可用性
自Microsoft&reg;WindowsServer&reg;2003推出后,计算环境已发生天翻地覆的变化。WindowsServer&reg;2008引入了众多新功能并扩展了WindowsServer2003的功能。

2010-06-03 15:23:48

DIY入门放弃:CPU顶盖有秘密
如果觉得CPU顶盖是普通的一块铁片,那你可就错了。CPU的顶盖不仅不是铁,而且能看出不少信息来,本期DIY从入门到放弃就带你熟悉这块小小的铜片。

2022-01-17 08:52:32

CPU CPU工具 显卡
云存储性能:可用性持久之间差异
当你打开汽车点火开关,把电器插到墙上的插座上,或者双击硬盘上的文件时,你就知道接下来会发生什么了。这些东西都会带来你想要的结果。但在云端,你宝贵的文件却掌握在别人手中。你确定每次都能指望有结果吗

2019-09-06 09:50:52

云存储 硬盘 云服务
TechED2013:云服务可靠可用性
可用性是系统运行时间和系统运行时间加系统宕机时间的比,可用性是衡量系统的主要因素之一。传统的技术,在系统宕机之后,需要将服务器或者其他设备维修好了之后才能重新提供服务,而云技术的出现,这一缺陷有效地得到了改善。

2013-12-06 15:31:49

TechEd2013
前端可用性保障实践
一般可用性都是说后端服务的可用性,都说我们的服务可用性到了几个9,很少有人把可用性放到前端来。其实对于任何一个有UI交互流程的业务,都会有前端服务可用性,后端的可用性做的再高,前端一个按钮写的有问题点击不起作用也会导致用户无法完成流程。

2017-08-24 17:05:06

MySQL:MySQL看主从架构高可用性实现
semisync在网络故障超时的情况下会退化成async,这个时候如果刚好主库掉电了,有些binlog还没有传给从库,从库无法判断数据跟主库是否一致,如果强行切换可能会导致丢数据,在金融业务场景下只能"人工智能"来做切换,服务中断时间长。

2023-12-11 07:44:36

MySQL 架构 高可用
AI提升数据中心可用性效率
随着企业开始采用经过大型数据中心运营商和托管服务提供商试用和测试过的机器学习技术,人工智能将在数据中心运营中扮演更重要的角色。

2018-06-22 09:28:22

数据中心 可用性 效率
关于云计算可用性定性定量研究
云计算在被越来越多的个人和企业所采用,但人们对于云计算服务在安全性,可靠性和服务响应确定性方面的担忧也与日俱增.虽然云服务提供商(CloudsServiceProvider)通常都会承诺SLA(ServiceLevelAgreement)的可用性(Availability)范围等,

2013-05-06 10:50:18

玻璃钢生产厂家信阳校园玻璃钢人物雕塑厂家大型商场美陈是什么意思上海艺术商场美陈怎么样西宁寺庙玻璃钢雕塑清远欧式玻璃钢雕塑云南玻璃钢浮雕房地产水景雕塑江苏户外商场美陈厂家供应商场美陈一家人武陟玻璃钢雕塑玻璃钢人物雕塑规格洛阳玻璃钢人物雕塑价格南宁泡沫玻璃钢雕塑湖州玻璃钢雕塑多少钱深圳园林玻璃钢雕塑定制丽江市玻璃钢雕塑多少钱江西特色玻璃钢雕塑供应商吉林玻璃钢座椅雕塑广西玻璃钢仿铜麒麟雕塑动物蝴蝶草坪玻璃钢雕塑上海拉丝玻璃钢雕塑销售价格房地产玻璃钢仿铜雕塑加工玻璃钢果蔬雕塑厂家联系方式大连商场美陈雕塑设计兰州景区玻璃钢雕塑厂家儋州商场美陈吉林玻璃钢卡通雕塑设计玻璃钢雕塑蒸馒头济宁玻璃钢卡通雕塑加工温州学校玻璃钢雕塑价位吉林景区玻璃钢雕塑生产厂家香港通过《维护国家安全条例》两大学生合买彩票中奖一人不认账让美丽中国“从细节出发”19岁小伙救下5人后溺亡 多方发声单亲妈妈陷入热恋 14岁儿子报警汪小菲曝离婚始末遭遇山火的松茸之乡雅江山火三名扑火人员牺牲系谣言何赛飞追着代拍打萧美琴窜访捷克 外交部回应卫健委通报少年有偿捐血浆16次猝死手机成瘾是影响睡眠质量重要因素高校汽车撞人致3死16伤 司机系学生315晚会后胖东来又人满为患了小米汽车超级工厂正式揭幕中国拥有亿元资产的家庭达13.3万户周杰伦一审败诉网易男孩8年未见母亲被告知被遗忘许家印被限制高消费饲养员用铁锨驱打大熊猫被辞退男子被猫抓伤后确诊“猫抓病”特朗普无法缴纳4.54亿美元罚金倪萍分享减重40斤方法联合利华开始重组张家界的山上“长”满了韩国人?张立群任西安交通大学校长杨倩无缘巴黎奥运“重生之我在北大当嫡校长”黑马情侣提车了专访95后高颜值猪保姆考生莫言也上北大硕士复试名单了网友洛杉矶偶遇贾玲专家建议不必谈骨泥色变沉迷短剧的人就像掉进了杀猪盘奥巴马现身唐宁街 黑色着装引猜测七年后宇文玥被薅头发捞上岸事业单位女子向同事水杯投不明物质凯特王妃现身!外出购物视频曝光河南驻马店通报西平中学跳楼事件王树国卸任西安交大校长 师生送别恒大被罚41.75亿到底怎么缴男子被流浪猫绊倒 投喂者赔24万房客欠租失踪 房东直发愁西双版纳热带植物园回应蜉蝣大爆发钱人豪晒法院裁定实锤抄袭外国人感慨凌晨的中国很安全胖东来员工每周单休无小长假白宫:哈马斯三号人物被杀测试车高速逃费 小米:已补缴老人退休金被冒领16年 金额超20万

玻璃钢生产厂家 XML地图 TXT地图 虚拟主机 SEO 网站制作 网站优化