网易云捕性能踩坑解决之道上篇

本文由作者余宝虹授权网易云社区发布。

从零开始设计开发一个日处理数据8亿的大数据高并发实时系统,哪些性能问题需要特别注意?这里我们一起梳理一下,本文中我将以PE,SA同学戏称的DDOS系统—网易云捕设计开发实践中两年的时间里碰到的真实问题,踩过的坑及解决问题的方法和大家一起讨论如何解决这些问题。文中不会大谈特谈架构设计,只是会在提及问题出现的场景及解决方法时初略带过,没有场景的谈架构设计都是耍流氓。本文着重列举在云捕业务场景下我们碰到的一系列性能问题以及解决问题的思路,帮助一部分有类似场景的人少走弯路,抛砖引玉,欢迎各路大神批评指正。
   为了便于读者轻松的理解后续的描述,有必要开始之前先熟悉云捕的业务场景,我这里简明扼要的介绍一下。
   有统计显示,Crash的出现比率非常高:63%的用户碰到过移动APP crash,在首次启动碰到crash时,21%的用户会卸载App,另外,Crash发生在使用过程中,70%的用户会给予差评。Crash已经成为移动App开发的最大障碍,App开发中进行质量跟踪同样有很多难以解决的问题:用户投诉闪退,但却无法重现;QA投入大量时间测试,还是无法解决各类crash问题;Android机型太多太杂;产品要求快速上线,搭建一个crash收集平台耗时耗力;使用国外的产品,网络不好,崩溃上报问题很大并且使用其它公司的产品,数据安全又难以保证。在此情况下,网易云捕应运而生了,使命就是为了助力移动端的开发者打造高品质APP,精准捕捉APP的每一次质量问题。
   为了实现上述目的,在调研竞品后我们发现云捕需要实现以下功能:
     1 实时展示崩溃、异常、卡顿问题详情,设备信息,崩溃卡顿分类;
     2 实时准确统计分析各类崩溃、异常、卡顿问题次数、影响人数,启动人数,比率等多方位趋势图,实时报警让用户全面掌握产品质量状况 ;
     3 实时准确统计今日问题统计,今日Top3实时展示24小时Top3问题统计排序;
     4 实时准确统计每个崩溃累计的类型设备型号分布图,系统版本分布图;
     5 崩溃、卡顿堆栈实时自动还原; 
     6 demo实时展示;
     7 解决方案实时推荐;
     8 用户自助接入,前期不需要审核;
 看上面的需求不难发现,有几个关键词大数据,高并发,实时,准确。为了很好的实现这个需求便有了下面的架构设计图:
 了解完业务场景,看完架构设计图,下面的例子就比较好理解了,为了系统性,下面一个个组件的介绍问题及解决方案。

 DDB篇:
   案例一:某周六,数据量急剧增加,收到哨兵报警:Cause: java.sql.SQLException: Get null from pool;
   解决方案:首先通过命令show process或者show status查看链接数,检查数据库连接数设置及释放正常后,问了其它同事也没有碰到这个问题, 联系DBA同学修改连接数后恢复正常。据DBA同学描述现在一个QS最大可支持1024个链接,可以通过增加QS的数量来提高链接;

案例二:云捕需要在插入数据的时候根据数据类型实时生成一个类型,某日排查问题发现插入的记录条数和DDB节点数一致
   解决方案:仔细查阅ddb文档发现设置多节点ddb设置UNIQUE key插入不能保证唯一,只能在单节点的集群上保证唯一性。多节点集群需要业务方自己实现,利用redis提供的setnx来实现分布式锁后解决问题,读者也可以通过zookeeper来实现,请自行google;

案例三:数据插入延迟比较高
   解决方案:1 请DBA同学升级DDB硬盘为SSD硬盘; 
        2 批量插入替代单条插入,并且批量插入要控制好batch的数字否则会出现下面的异常;
   Cause: java.sql.SQLException: condition number is: 1124, exceed max value:1024 或者Cause: com.mysql.jdbc.PacketTooBigException: Packet for query is too large (26124567 > 16777216). You can change this value on the server by setting the max_allowed_packet' variable.

可以事先通过控制台可以查到部分阈值,查不到的也可以联系DBA同学确认一下。

批量插入要控制batch的大小,确保参数个数和消息体大小都在合理的范围内

注意:数据库的再提升性能,毕竟性能在哪里,能不经过数据库的就不过,能用缓存扛的就用缓存。往往总是策略来得更有效果,有时候优化不下去了,我们是不是想想换一种思维方式,为了打开一个瓶子喝水,除了打开瓶子以为,还可以把塞子推进去,换种思路有时候会海阔天空。

多线程篇:
   场景:云捕有两个对外的接口,分别用来接收十亿台左右的设备发上来的崩溃,卡顿,启动数据,并发非常大。
   案例一:某日收到哨兵报警,内存使用率100%,上服务器分析发现Java堆的eden区,survivor区,tenured区 全部堆满,接口服务处于将近瘫痪的状态,迅速dump文件后用mat分析发现队列里面塞满了对象,但是项目代码里面没有明显的使用队列。
   最后通过排查发现是因为使用多线程时excutor 内部使用了一个无界队列,如果数据处理不够快,大量的数据回堆积在内存,导致内存被撑爆,相关具体源代码如下:

分析

解决办法:使用定制的实例,设定队列长度,及拒接策略,为了保证数据都能被完整处理,云捕使用的拒绝策略是处理不过来时利用kafka的可堆积性重新扔回kafka中.


为了保证在重启实例时数据不丢失,这里还需要注册一个钩子到JVM实现JVM退出前先把本地队列中的数据消费掉.

JVM和Tomcat篇:
    
 案例:报警项:TomcatCollector,报警内容:currentThreadsBusy数: 2000,currentThreadsBusyMax数:2000
     解决方案:Tomcat默认使用BIO模式,调整为NIO模式.并调整代码,加解密,预处理等等统一移到数据处理模块,接口模块只负责接收数据,接收数据以后啥也不做,直接扔到Kafka集群中,数据处理模块再从Kafka集群中提取数据排队处理.Tomcat三种运行模式及使用场景:

  • BIO: 同步并阻塞,服务器实现模式为一个连接一个线程,即客户端有连接请求时服务器端就需要启动一个线程进行处理,如果这个连接不做任何事情会造成不必要的线程开销,当然可以通过线程池机制改善,适用连接数较小且固定的架构,这种方式对服务器资源要求比较高,并发局限于应用中。。
  • NIO:同步非阻塞,服务器实现模式为一个请求一个线程,即客户端发送的连接请求都会注册到多路复用器上,多路复用器轮询到连接有I/O请求时才启动一个线程进行处理,适用于连接数目多且连接比较短(轻操作)的架构,比如聊天服务器,并发局限于应用中,编程比较复杂。
  • AIO:异步非阻塞,服务器实现模式为一个有效请求一个线程,客户端的I/O请求都是由OS先完成了再通知服务器应用去启动线程进行处理适用于连接数目多且连接比较长(重操作)的架构,比如相册服务器,充分调用OS参与并发操作,编程比较复杂。

   Kafka篇:
     案例一: 数据大幅度增加后部分用户反馈发送消息超时
     
调整为如下:

      解决方案: kafka的QPS据说最大能达到百万级别的QPS,但是经排查问题就出在这里,同步改异步,kafka支持批量发送数据后问题解决。   
     案例二:kafka.common.FailedToSendMessageException: Failed to send messages after 3 tries.

     解决方案:这个和kafka brocker设置有关,通过分析发现一部分上报的消息体过大,甚至达到2M,DBA专家这边后台也没有查到任何异常,但是大量的消息发送失败。通过反复Google后我得到一个信息:kafka消息体为10K的时候性能最佳,基于这个信息,让DBA同学帮忙调整后台限制batch的总大小限制,应用程序中调整批量的大小,并抛弃一部分过大的消息体,调整以后效果如下。

    注意:另外要注意kafka的一个分区只能被一个节点消费,请合理的设置kafka的节点数,当节点数<kafka分区数,会出现部分节点无法获取数据的情况。另外kafka分区过多也会导致kafka本身的可靠性降低.
  

   Redis篇:
 redis在云捕系统的地位相当重要,碰到的问题也比较多,最近才解决了一个遗留的老大难问题.由于15年的时候才接触到redis,使用过程中姿势存在比较大的问题.在这里列举下面几个问题:
案例一:CPU抖动,具体可以见DBA同学的文章
redis cpu 抖动问题分析  

redis-faina redis性能问题诊断利器
案例二:主从不同步,redis内存无法扩容,内存溢出; 
 

   改造后的效果如下:



ddb连接数限制:<property name="maxActive" value="500" />         <!-- 最大连接数量 --> ddb最大支持500个连接数

org.springframework.dao.InvalidDataAccessApiUsageException: READONLY You can't write against a read only slave.; nested exception is redis.clients.jedis.exceptions.JedisDataException: READONLY You can't write against a read only slave.

+--------------------------+------------+

2 rows in set (0.01 sec)

免费领取验证码、内容安全、短信发送、直播点播体验包及云服务器等套餐

更多网易技术、产品、运营经验分享请访问网易云社区

相关文章:
【推荐】 实现自己的前端模板轻量级框架

原文地址:https://www.cnblogs.com/163yun/p/10114154.html

时间: 2024-10-10 14:54:44

网易云捕性能踩坑解决之道上篇的相关文章

网易云,都踩过了网易20年的哪些坑儿?

(上图为网易杭州研究院执行院长汪源) 云计算的核心与本质是什么?网易杭州研究院云计算平台产品部总监.网易云基础服务(网易蜂巢)容器云研发负责人陈谔讲了一个故事:网易云基础服务(网易蜂巢)最初的版本,从申请资源开始监测到虚拟机.容器全部启动,大概需要两分半钟,陈谔认为这个速度太慢,希望20秒内启动容器. "大家觉得这个事情太困难,几乎不可能完成.于是,接下来分解阶段性目标,先优化到1分钟.再到40秒.再到20秒,让大家看自己的环节还有哪些潜力可以挖掘.最后,实现了20秒左右完成一个容器的建立(除去

Windows利用Swarm原生Docker集群踩坑总结

环境: 角色 机器名称 操作系统 IP 备注 Mater Web30 Windows Server 2016 GUI 192.168.2.30 安装最新推荐补丁 Node Web31 Windows Server 2016 Core 192.168.2.31 安装最新推荐补丁 Node Web32 Windows Server 2016 Core 192.168.2.32 安装最新推荐补丁 第一坑:Windows Server 2016 Core 1.操作系统分区坑 由于我们使用的Windows

软工书面作业1——分析网易云音乐的创新

在音乐APP中,网易云音乐算是地地道道的后发者,它的诞生比酷狗音乐.酷我音乐.QQ音乐等晚了数年,却以其卓越的创新能力.非凡的用户体验,很快超越了诸多先发者,成为如今国内数一数二的移动音乐应用软件.以下,我将从几方面分析网易云音乐的创新致胜之道. 1.功能创新:云歌单与音乐社交 在酷狗音乐.QQ音乐等巨头早早占据移动音乐市场的背景下,2013年才姗姗来迟的网易云音乐以功能创新突破桎梏.赢得市场.它从已有音乐APP的"歌曲列表"模块获得灵感,将这样的列表转化为"云列表"

【踩坑经历】一次Asp.NET小网站部署踩坑和解决经历

2013年给1个大学的小客户部署过一个小型的Asp.NET网站,非常小,用的sqlite数据库,今年人家说要换台服务器,要重新部署一下,好吧,虽然早就过了服务时间,但无奈谁叫人家是客户了,二话不说,上,源代码和以前的文件都有,部署还不是分分钟的事情,打开IIS挂上去就行了.谁知道,这个部署将近花了2天的时间.看看踩坑过程和解决方法. 本文原文地址:http://www.cnblogs.com/asxinyu/p/4380380.html 1.居然拿XP系统做服务器 第一个坑其实和我没关系,客户以

微信小程序性能测试之jmeter踩坑秘籍(前言)

最近要做个微信小程序的性能压测,虽然之前只做过web端的,但想一想都是压后端的接口,所以果断答应了下来,之前对jmeter都是小打小闹,所以趁着这次机会好好摆弄摆弄. --------------------------------------------------------------------------------踩坑前总结哈理论,这篇写给自己的----------------------------------------------------------------------

避免踩坑:易盾安全老司机起底Android九大漏洞,附解决建议

Android应用会遇到各种各样的漏洞,如何从细节上了解各种安全隐患,积极采取适当的防御措施便变得尤为重要.为了让大家对Android漏洞有一个非常全面的认识,网易云易盾资深安全工程师徐从祥为大家详细解读常见九大的Android漏洞,供各位学习参考.(如果下面干货内容没有让各位尽兴,欢迎来官网申请相关产品试用,面对面交流,保证解决你的安全难题. ? 第一大类:AndroidManifest配置相关的风险或漏洞 程序可被任意调试 风险详情:安卓应用apk配置文件Android Manifest.x

ubuntu解决网易云无法打开

最近首次入手ubuntu18 摸索了很久,当然网易云是不可缺少的一部分,在配置好各种环境+程序后,也找到了解决网易云的方法了. 首先安装好网易云 默认情况下需要在终端使用 sudo 才能运行 解决的办法其实也很简单, sudo mv /usr/bin/netease-cloud-music /usr/bin/netease-cloud-music-old sudo vim /usr/bin/netease-cloud-music #!/bin/bash echo password | sudo 

ubuntu18.04 完美解决网易云音乐双击启动

Ubuntu的主题界面我一直很喜欢,一直想做一个双系统,因为电脑硬盘里的资料多,害怕失误导致资料丢失,所以一直在用win7,但是好奇心害死猫,忍不住找了一篇双系统的博客,结果一步一步,做了全盘..... 所以现在只有Ubuntu了,于是试一试这个被吹上天的ubuntu吧,首先装个网易云音乐happy一下,结果发现双击无法启动,居然要通过命令行启动,命令是 sudo netease-cloud-music 然后弹出shell对话框,当时的心里是What the f**k,于是一路搜索,看网上一顿b

记录某项目中的踩坑与解决(持续更新)

前言 最近参加了某个比赛, 我所选的赛题就是个类似知乎这样的安卓app,由于着手近一个月了,踩了不少坑,之前没怎么记录,估计事后也会忘记干净. 因此特开一帖,在此记录下相关的坑. 记录 写完某个Recyclerview的item布局和相关适配器后, 然后展示的时候, 发现显示出来的Item数量小于List中绑定的数据量: 首先是检查了一遍适配器中的逻辑,发现没啥问题.然后在onCreateViewHolder中打log,发现只创建了两次就没了(而实际应该创建6次). 最后百度才发现是外面的Scr