系统性能优化解决方案

上传人:学*** 文档编号:231086382 上传时间:2021-12-28 格式:DOCX 页数:4 大小:16.03KB
返回 下载 相关 举报
系统性能优化解决方案_第1页
第1页 / 共4页
系统性能优化解决方案_第2页
第2页 / 共4页
系统性能优化解决方案_第3页
第3页 / 共4页
系统性能优化解决方案_第4页
第4页 / 共4页
亲,该文档总共4页,全部预览完了,如果喜欢就下载吧!
资源描述

《系统性能优化解决方案》由会员分享,可在线阅读,更多相关《系统性能优化解决方案(4页珍藏版)》请在金锄头文库上搜索。

1、系统性能优化解决方案 系统性能优化解决方案 环境背景: 1.单台40TPS,加到4 台服务器能到60TPS,扩展性几乎没有。 2.在实际生产环境中,经常出现数据库死锁导致整个服务中断不可用。 3.数据库事务乱用,导致事务占用时间太长。 4.在实际生产环境中,服务器经常出现内存溢出和CPU 时间被占满。 5.程序开发的过程中,考虑不全面,容错很差,经常因为一个小bug 而导致服务不可用。 6.程序中没有打印关键日志,或者打印了日志,信息却是无用信息没有任何参考价值。 7.配置信息和变动不大的信息依然会从数据库中频繁读取,导致数据库IO 很大。 8.项目拆分不彻底,一个tomcat 中会布署多个项

2、目WAR 包。 9.因为基础平台的bug,或者功能缺陷导致程序可用性降低。 10.程序接口中没有限流策略,导致很多vip 商户直接拿我们的生产环境进行压测,直接影响真 正的服务可用性。 11.没有故障降级策略,项目出了问题后解决的时间较长,或者直接粗暴的回滚项目,但是不一定 能解决问题。 12.没有合适的监控系统,不能准实时或者提前发现项目瓶颈。 优化解决方案缓存优化方案 针对配置信息和变动不大的信息可以放到缓存中,提高并发能力也能够降低IO 缓存。 程序容错优化方案 在这一块我要先举一个程序的例子说明一下什么才是容错,先看程序: 注: 那么如果service 层的方法调用dao 层的方法,一

3、旦数据插入失败,那么这种异常处理的方式是容错吗? 把异常给吃掉了,在service 层调用的时候,虽然没有打印报错信息,但是这能是容错吗? 所谓容错是指在故障存在的情况下计算机系统不失效,仍然能够正常工作的特性。 我们拿使用缓存来作为一个案例讲解,先看一个图: 这是一个最简单的图,应用服务定期从redis 中获取配置信息,可能会有朋友认为这样已经很稳定了,但是如果Redis 出现问题呢?可能会有朋友说,Redis 会是集群,分片或者主从,确保不会出现问题。其实我是这样的认为的,虽然应用服务程序尽量的保持轻量级是不错的,但是不能因此而把 希望全部寄托在中间组件上面,换句话说,如果此时的Redis

4、 是单点,那么后果会是什么样的,那么随着大量的并发请求到来的时候,程序中会报大量的错误,同时正常的流程也不能进行下去了业务也可能由此而中断。 那么在此种场景下我的解决方案是,要把缓存的使用分级别,有的缓存同步要求时效性非常高,比如支付限额配置,在后台修改完成以后前台立刻就能够获得感知,并且能够成功切换,这种情况只能实时的从Redis 中获取最新数据,但是每次获取完最新的数据后都可以同步更新本地缓存,当单点的Redis 挂掉后,应用程序至少还能从本地读取信息而不至于服务瞬间挂掉。有的缓存对时效性要求不高,允许有一定延迟,那么在这种情况下我采用的方案是,利用本地缓存和远程缓存相结合的方式,如下图所

5、示: 方案一: 这种方式通过应用服务器的Ehcache 定时轮询Redis 缓存服务器更同步更新本地缓存,缺点是因为每台服务器定时Ehcache 的时间不一样,那么不同服务器刷新最新缓存的时间也不一样,会产生数据不一致问题,对一致性要求不高可以使用。 方案二: 通过引入了MQ 队列,使每台应用服务器的Ehcache 同步侦听MQ 消息,这样在一定程度上可以达到准同步更新数据,通过MQ 推送或者拉取的方式,但是因为不同服务器之间的网络速度的原因,所以也不能完全达到强一致性。基于此原理使用Zookeeper 等分布式协调通知组件也是如此。部分项目拆分不彻底 拆分前 注: 一个Tomcat 中布署多

6、个应用war 包,彼此之间互相牵制在并发量非常大的情况下性能降低非常明显。 拆分后 注: 拆分前的这种情况其实还是挺普遍,之前我一直认为项目中不会存在这种情况但是事实上还是存在了。解决的方法很简单,每一个应用war 只布在一个tomcat 中,这样应用程序之间就不会存在资源和连接数的竞争情况,性能和并发能力提交较为明显。 因基础平台组件功能不完善导致性能下降 先看一段代码: 注: 首先我们先不说这段代码的格式如何如何,先看功能实现,使用Future 来做超时控制,这是为何呢?原因其实是在我们调用的Dubbo 接口上面,因为是Dubbo 已经经过二次封装,结果把自带的timeout 给淹沫了,程

7、序员只能通过这种方式来控制超时,可以看到这种用法非常差劲,对程序性能造成一定的影响。 如何快速定位程序性能瓶颈 我相信在定位程序性能问题的时候,大家有很多种办法,比如用jdk 自带的命令,如Jcmd,Jstack,jmap,jhat,jstat,iostat,vmstat 等等命令,还可以用VisualVM,MAT,JRockit 等可视化工具,我今天想说的是利用一个最简单的命令就能够定位到哪段程序可能存在性能问题,请看下面介绍: 由此可以判断出来在LWP 30222 这个线程产生了性能问题,执行时间长达31.4 毫秒的时间,再观察无非就是下面的几个语句出现的问题,只需要简单排查就知道了问题瓶

8、颈。 关于索引的优化 组合索引的原则是偏左原则,所以在使用的时候需要多加注意; 索引的数量不需要过多的添加,在添加的时候要考虑聚集索引和辅助索引,这二者的性能是有区别的;索引不会包含有NULL 值的列:只要列中包含有NULL 值都将不会被包含在索引中,复合索引中只要有一列含有NULL 值,那么这一列对于此复合索引就是无效的。所以我们在数据库设计时不要让字段的默认值为NULL。 MySQL 索引排序:MySQL 查询只使用一个索引,因此如果where 子句中已经使用了索引的话,那么order by 中的列是不会使用索引的。因此数据库默认排序可以符合要求的情况下不要使用排序操作;尽量不要包含多个列

9、的排序,如果需要最好给这些列创建复合索引。 使用索引的注意事项 以下操作符可以应用索引: ?大于等于 ?Between ?IN ?LIKE 不以% 开头 以下操作符不能应用索引: ?NOT IN ?LIKE %_ 开头 索引技巧 ?同样是1234567890,数值类型存储远比字符串节约存储空间。 ?节约存储就是节约IO,减少IO 就是提升性能 ?通常对数字的索引和检索要比对字符串的索引和检索效率更高。 使用Redis 需要注意的一些点 ?在增加key 的时候尽量设置过期时间,不然Redis Server 的内存使用会达到系统物理内存的最大值,导致Redis 使用VM 降低系统性能 ?Redis

10、 Key 设计时应该尽可能短,Value 尽量不要使用复杂对象。 ?将对象转换成JSON 对象(利用现成的JSON 库)后存入Redis, ?将对象转换成Google 开源二进制协议对象(Google Protobuf,和JSON 数据格式类似,但是因为是二进制表现,所以性能效率以及空间占用都比JSON 要小;缺点是Protobuf 的学习曲线比JSON 大得多) ?Redis 使用完以后一定要释放连接,如下图示例: 不管是返回到连接池中还是直接释放掉,总之就是要将连接还回去。 关于长耗时方法的拆分 我们拆分长耗时方法的一般技巧是: ?寻找业务的冗余点,代码中有很多重复性的代码,可以适当简化。 ?检查库表索引是否合理加入。 ?利用单元测试或者压力测试长耗时的操作进行算法级别优化,比如从库中大批量读取数据,或者长时间循环操作,或者死循环操作等等。 ?寻找业务的拆分点,根据业务需求拆分同步操作为异步,比如可以使用消息队列或者多线程异步化。 经过以上几个分析后如果方法执行时间仍然非常的长,这样可能就是业务方面的需求使然,如下图: 那么我们是否可以考虑将一个长耗时方法进行拆分,拆分为多个短耗时方法由发起端分别调用,这样在高并发的情况下不会造成某一个方法的长时间阻塞,在一定程度上能够提高并发能力,如下图: 4 / 4

展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 大杂烩/其它

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号