宅米网性能优化实践(内附小强点评)
背景介绍
宅米是一家专注校园电子商务的互联网企业,目前主营校园超市O2O。公司成立于2014年11月,仅仅一年多的时间,公司即经过4轮融资,覆盖近200座城市,1000多所大中专院校,10000多栋宿舍楼,日均订单20万,峰值订单50万。
初识架构
这样的系统能不能应对今后快速的业务发展?性能问题会不会成为持续增长的交易量的瓶颈?系统能不能撑得住访问高峰期的大规模并发访问? 性能优化成为这个时候最重要的工作,于是安排专门的工程师进行性能测试和性能优化,从架构、代码、数据库、运维各个层面梳理系统状况,发现系统瓶颈,进行针对性优化。
小强点评:这种架构是初识架构,一般系统都是在这个架构上进行逐步演化的,掌握基本的架构知识对于测试工程师来说十分重要。
性能测试
校园零食购物的特点是在晚上10点左右进入高峰,在此前后一小时的交易量大概占整天交易量的一半,也就是说,如果要设计一个日订单100万的系统,其实要承受的交易压力是每小时50万单。
当初按照二八法则推算峰值每秒单量为556笔,以此为基准根据Nginx日志分析后端接口调用频率,推算出接口调用比率前20的请求,以此构造测试场景。
在执行性能测试时,我们使用Jmeter作为性能测试工具,利用了云服务提供的系统资源监控作为基础。
小强点评:很多人一直纠结并发数怎么去算,其实算法非常多,在小强性能测试培训班中就讲了大概4种算法,个人觉得根本不存在准确不准确的问题,关键是在你的应用场景,这世上哪里有绝对的准确?
架构优化
性能测试结果并不乐观,虽然系统此前使用了分布式缓存对热点数据进行缓存,但是比较随意,哪些数据需要缓存,失效策略如何设置都没有认真分析和设计。性能测试后决定规范缓存使用,尽可能将各种频繁读取的数据全部缓存起来,并将Redis服务器做集群和主从复制部署。
小强点评:缓存带来的效果是明显的,一般对于大量数据的查询我们都要首先考虑缓存方面的优化。当然,这里说的是后端缓存,对于前端的缓存也需要考虑。
此外还使用第三方CDN服务进行静态文件访问加速,产品图片、JavaScript文件、CSS文件等都通过CDN加速,同时通过Nginx反向代理服务器提供静态文件的前端缓存。
小强点评:这些都是偏向于前端性能优化方面的问题了,感兴趣的可以看我的前端性能测试视频。
性能测试发现,系统主要瓶颈点在数据库上,虽然使用Redis将热点数据缓存起来,但是数据库依然在并发量达到一定程度后表现出系统过载的情况。于是对数据库进行主从分离。
sql语句优化
性能测试过程中发现,由于此前主要精力都在关注如何快速实现业务,大量数据库查询语句写得比较随意,索引设计非常不合理。 结合性能测试中Mysql数据库slow.log分析,定位慢查询SQL追加index,然后利用解释执行计划explain优化SQL
小强点评:任何系统在sql语句方面多多少少肯定会有问题,一般我们的方法就是慢查询监控>top N语句分析>优化改进。思路基本都是这样,具体的做法各不相同,灵活应对。
数据库连接池优化
在做性能测试的时候发现在某些情况下有较为严重的性能问题。在高并发情况下,长时间施加压力,应用程序出现不能访问的状况。
上网查找资料,发现很多人也遇到了C3P0的"APPARENT DEADLOCK"问题。
将C3P0切换成国产数据库连接池Druid之后,状况明显好转,类似问题再未出现过。
小强点评:C3P0确实有一些小bug。后来我们也用了阿里开源的Druid目前来看还是不错的哦,可以尝试一下。
H5响应压缩优化
开启Nginx gzip压缩 , 降低App响应数据包大小,提高响应性能
小强点评:前端的性能优化,不论是app、h6还是web都是一样的,我们很多童鞋学的太死板,没有做到一通百通。
订单数据冷热分离
随着业务的持续发展,订单表的数据会越来越多。按我们现在日订单量20万单预估,月订单量则为600万单,年订单量则达到7200万单,而且日订单量还在不断的增加,用不了多久,数据量就会超过MySQL的极限。 一开始我们考虑使用分布式数据库的方案,对订单表进行水平切分,使用订单号进行hash,将订单数据切分到多张表上。 进一步分析后发现,订单数据具有明显的冷热不均的特点,即刚刚创建的订单是热数据,不同应用以各种方式访问修改这些订单。经过一段时间以后,特别是订单完成后,订单访问频率急剧降低,而且只有订单查询这一种操作。于是我们考虑采取冷热数据分离的策略,以控制热库中数据总量,保障订单表数据量始终维持在一个可以接受的范围内,进而提供稳定的数据访问性能。
小强点评:我们总是觉得要用高级点的技术才显得牛逼,其实这是装逼。当年在新浪的时候我们对数据库做了大量的分库分表,但最后带来的性能提升并不明显。我一直强调技术是服务于业务的,只有把业务的特性明确了,根据业务来使用合理的技术才会能大的提升,否则就是适得其反。
总结
性能问题是实打实的问题,解决办法也应该针对具体问题各个击破。通过性能测试了解系统现状,通过瓶颈分析发现具体问题,针对具体问题寻找解决方案,实现解决方案再进行性能测试,整个性能优化形成闭环,系统得以持续优化。
小强点评:性能优化是一个持续的过程,没有谁能一步优化道到位,也没有谁可以优化到极致。他需要你有完善的知识体系,各个方面都要懂一些,并不是大家想的会一个LoadRunner或jmeter就可以完成的,这些只是性能中的很小的一部分而已。让我们一起加油吧。