进入一个新项目,如何快速入手并进行性能优化
理解、思考
1 从业务分析
- 第一步先理解工作业务(做什么,解决了什么,流程是什么)
- 了解技术栈
- 系统的业务架构是什么(有哪些模块,与哪些外部系统有交互)
- 外部接口方式,承接的协议是什么
- 内部各个模块如何划分,模块职责是什么,分层抽象的东西是什么
- 系统构建的脚本,代码的结构怎么样的
2 理解问题
项目上对接手的前人代码进行性能优化。场景大概是 创建一个项目时,因为涉及到大量数据的查询和拷贝,其中的业务逻辑又很复杂,导致拷贝时间很长影响系统使用。
动手做,多次测试,多次试探
构建保护网
- 创建测试防护网
- 逐步拆分,逐步整改,逐步替换
- 构建好独特的领域模型,利于划定不同
角色
,限定运作上下文 - 每改好一个独立微模块的功能时,运行测试
本地调试,逐步分析
1 代码级别
- 首先考虑到是代码质量的问题,大多数问题也的确如此(可能是之前项目进度赶,没有注重各个模块的解耦,紧耦合,导致很多地方出现很多重复查询),通过画流程图理清,此次
创建
的业务逻辑,分析各个模块之间数据是否重复查询,简化代码,避免因重用部分代码逻辑而造成的不必要查询。 - 使用Spring的
StopWatch
对各个模块进行调试、分析,找出重点耗费时间的地方 - 一次插入的数据量过多的话,使用批量插入。这里需要注意的是,批量插入需要注意如果使用的是
拼接sql
的方式,存在sql长度限制的问题,每个数据库都不相同,mysql可通过max_allowed_packet
设置。再对数据进行合理的分批插入。 - 对于在
foreach
的时候,频繁连接数据库查询,可预先把必要的数据 经过筛选load下来。 (减少查询数据库的频次)
2 缓存
- 空间换时间,查询频繁且数据量大的相同数据而且数据更新不频繁,添加局部缓存或缓存服务(Redis)。缓存服务涉及到几个问题,简单阐述下:
- 更新缓存的时间点是什么,他的可靠性如何保证,根据业务不同而不同
- 缓存存满了怎么办,是不是要制定一些缓存策略 - LRU
- 缓存丢失 - 设置AOF 、 RDB
- 缓存被“击穿” - loadDB 加锁避免同时因访问一个热点数据而打爆DB,可使用redis或zk的互斥锁,获取相同数据时加锁 等。
- 还有缓存雪崩 - 也可使用互斥锁,对某个key只允许一个线程查询数据和写缓存,其他线程等待。还可设置二级缓存,对某些不常更新数据设置 比较长时间的缓存。
3 服务间调用
- 如果是微服务架构,特别注意服务间调用,尽量减少调用次数,重复数据做缓存。比如我在这儿优化时,发现某个地方耗时特别长,查看代码后看到是 每循环一次,feign就会调用其他服务,而且很多重复查询数据(添加缓存,避免重复调用查询)
4 并行处理
- 对某些可并行执行任务,使用并行执行,我在优化的处理过程中使用了Spring的
Project Reactor
对数据进行并行处理 - 对于某些业务场景,用户对其中某些逻辑并不关心而且当前处理的内容并不需要当前服务完成,这时候就可以用消息队列(MQ)处理
5 sql
- 使用
explain
对 查询语句进行分析调优
网友评论