【How to】浅谈 Java web应用的优化
前言
- 最近项目快要上线了,趁着现在有点想法、有时间就写点文字记录一下
web应用优化之数据库
- web应用最最最明显、最最最重要的优化点就是SQL语句了。大家经常自嘲后端不就是个 CRUD boy嘛,增删改查就完事了。其实说的完全没错,能把CRUD 弄好,那web 应用其实就解决了80%的问题。那CRUD 的可优化点在哪里呢?
SQL 查询优化
- 表的查询自然是第一位,良好的查询语句是高性能的第一步。建立合适、良好的索引可以使查询效率成倍的增长。但是错误的,不良的索引会使数据库性能下降,应用变慢。比如像一些字段的值基本可以用枚举来描述(例如state字段有2个合法值:0、1),说明这个值变化非常少,不适合建立索引。
- 注意索引失效的问题:按照索引的最左匹配原则,如果最左的值一旦没有被包含在查询条件,那么这个复合索引将直接失效,查询类型则从
type=ref
降级为type=all
的全表扫描。例如:表的复合索引为index(A+B)
,此时查询语句为query_condition(B)
,那么这个索引会直接失效,降级为全表扫描。这对于大表来说就是噩梦,如果表的数据量非常大,查询的时间会非常漫长。 - 索引失效2:使用聚合函数会使索引失效,如:A字段为索引,使用的聚合函数
SUBSTRING(A,...)
处理之后的指作为查询条件,那么索引就会失效。 - 案例1:项目中我曾经2次遇到了索引的问题导致查询时间非常的长。一次是测试环境中QA反馈整个交易耗时非常长,经常超时,感觉很卡。我便去看了日志,摸索了一下,发现有张业务流水表的索引没有建立,导致查询是全表扫描,耗时大概在10几秒,其实表的数据量才200W,并不算太多,添加索引之后就没有超时的情况了。
- 案例2:在项目的性能测试阶段,QA 反馈登录、注册接口的性能压测不能达到指标,很多接口的耗时达到了2s,但是性能测试环境的数据量其实才模拟了50w,并不是太多,于是我还是照例查看日志,发现有一条SQL语句的耗时非常久。我看了代码发现这个查询的字段是包含在一个复合索引里面的,但是还是超时了,很是奇怪。于是在测试环境使用
explain
语句分析语句的查询类型是type=ALL
,这时我意识到这个复合索引失效了,按照最左匹配原则,由于少了第一个字段,于是整个索引就失效。所以我及时将索引调整,保证查询的条件能匹配到索引,整个查询的耗时从1700ms
降低到2-4ms
。
大表优化 - 分区
- 面对一些流水表,记录不断的增加,可能单张表就能达到了千万的级别。这里可以采用mysql 的数据分区(paratition)来优化查询和数据管理。
大表优化 - 分表
- 这个也是一个项目上的问题,我这里简单描述一下:系统有张业务表每天有20W的增量数据,一段时间之后,数据量已经达到了1700W的数据量。由于每天的日终,有数据清理策略,基本稳定在2000W左右,系统只会批量处理表里每天新增的那部分新数据,每条数据都有不同的业务属性。
- 优化分析:其实可以见到,这个表里面虽然数据量很大,但是大部分的数据其实是没有什么用的,类似于那种用户的订单流水,过了1年可能就再也没啥用了。而且,每个数据都有业务属性,可以按照业务属性来区分。
- 优化方案1.1:优化索引,发现所有的数据都查询SQL都是带有索引的,这部分已经不能再优化了。
- 优化方案1.2:按照上文描述的业务属性拆表。按照不同的业务,存储到不同的表中。最后是拆成了4张表,单表的数据规模降低下来了。
- 优化方案1.3:陈旧的数据要及时清理,如果只增不减,那会随着时间的推进,系统会慢慢走向死亡。
web应用优化之日志
日志优化
- 其实日志这边我在压测之前没有怎么关注,直到压测一晚之后产生了大概几G的日志,于是我这边调高了日志等级,将
DEBUG
调整为INFO
,保证在压测环境下磁盘不会拖TPS
的后腿,又能有全面的分析日志可以看。 - 日志的写入不要开启同步的写入,配置一个缓冲区来一次性写入一个缓冲区大小的日志,避免多次磁盘的IO操作。
web应用优化之JVM
JVM 参数
- 其实在JVM 层面能优化的东西不太多,最多就是按照机器来调调参数,最常见的就是调整堆的大小
Xmx Xms
这些参数,堆的大小也不能太大,推荐一个JVM
的配置为4C 8G
,采用集群式的部署,外部请求访问使用负载均衡轮训的模式,避免GC
在FULL GC
的时候STW
的时间太长,应用的响应时间太长会有种假死的感觉。用户体验也不好 - 对于不同的业务可以选择不同的
GC
回收器,Java web 主要面临的业务就是及时响应的接口类任务和批量数据处理的定时类任务。接口类的任务对响应时间敏感(CMS 回收器组合
),批量数据处理类的任务对吞吐量敏感(parallel 回收器组合
),这里可以选用不同类型的GC
回收器来应对不同的业务场景需求。
web 应用优化之工具
arthas
- 性能优化不得不提一下阿里的 GitHub-Arthas 这个工具啦,文档Arthas 在线文档写的非常清晰明了,还有在线教程,手把手来教你,真的太良心了好嘛。追踪单个方法的性能问题,用
trace
定位每个方法的耗时,一秒定位问题。还能在测试环境直接看函数的变量值,class 热部署等等黑魔法,简直不要太香。
【How to】浅谈 Java web应用的优化
https://www.lewismind.site/2020/01/01/20250006/