记者从上海沪剧院获悉,7月25日晚,上海沪剧院一级演员朱俭因病逝世,年仅50岁。作为著名沪剧中生代演员,朱俭1975年生于上海,从小爱唱歌,曾参加小荧...
2025-07-26 0
前言
不知道你在SpringBoot项目中,有没有遇到过下面这样的代码:
@GetMapping("/orders")public List<Order> listOrders() { return orderDao.findAll(); }
一次性查询了所有的订单,全表扫描50万数据,导致接口查询性能很差,严重的时候可能会导致OOM问题。
问题定位:
这次事故让我明白:性能优化必须贯穿开发全流程。
今天这篇文章,跟大家一起聊聊SpringBoot优化的12招,希望对你会有所帮助。
第1招:连接池参数调优
问题场景:默认配置导致连接池资源浪费,高并发时出现连接等待
错误配置:
spring: datasource: hikari: maximum-pool-size: 1000 connection-timeout: 30000
数据库连接池的最大连接数,盲目设置过大,连接超时时间设置过长。
优化方案:
spring: datasource: hikari: maximum-pool-size: ${CPU核心数*2} # 动态调整 minimum-idle: 5 connection-timeout: 3000 # 3秒超时 max-lifetime: 1800000 # 30分钟 idle-timeout: 600000 # 10分钟空闲释放
数据库连接池的最大连接数,改成根据CPU核心数动态调整。
将连接超时时间由30000,改成3000。
第2招:JVM内存优化
问题场景:频繁Full GC导致服务卡顿
我们需要优化JVM参数。
启动参数优化:
java -jar -Xms4g -Xmx4g -XX:NewRatio=1 -XX:+UseG1GC -XX:MaxGCPauseMillis=200 -XX:InitiatingHeapOccupancyPercent=35-XX:+AlwaysPreTouch
最大堆内存和初始堆内存都设置成了4G。
-XX:NewRatio=1,设置新生代和老年代各占一半。
垃圾收集器配置的是G1。
垃圾回收的最大停顿时间为200毫秒。
第3招:关闭无用组件
问题场景:自动装配加载不需要的Bean
优化方案:
@SpringBootApplication(exclude = { DataSourceAutoConfiguration.class, SecurityAutoConfiguration.class})public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); }}
如果有些功能暂时用不到,可以先排除一下。
在SpringBoot项目启动的时候,排除了DataSourceAutoConfiguration和SecurityAutoConfiguration配置类的自动装载。
第4招:响应压缩配置
问题场景:接口返回JSON数据体积过大
优化方案:
server: compression: enabled: true mime-types: text/html,text/xml,text/plain,text/css,text/javascript,application/json min-response-size: 1024
配置开启响应的压缩。
第5招:请求参数校验
问题场景:恶意请求导致资源耗尽
防御代码:
@GetMapping("/products")public PageResult<Product> list( @RequestParam @Max(value=100, message="页大小不能超过100") int pageSize, @RequestParam @Min(1) int pageNum) { //...}
在接口中做好参数校验,可以拦截很多恶意请求。
第6招:异步处理机制
问题场景:同步处理导致线程阻塞
优化方案:
@Async("taskExecutor")public CompletableFuture<List<Order>> asyncProcess() { return CompletableFuture.completedFuture(heavyProcess());}@Bean("taskExecutor")public Executor taskExecutor() { ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); executor.setCorePoolSize(5); executor.setMaxPoolSize(10); executor.setQueueCapacity(500); return executor;}
在有些业务逻辑中,使用异步处理性能可能会更好。
第7招:使用缓存
使用缓存可以提升效率。
缓存架构:
代码实现:
@Cacheable(cacheNames = "products", key = "#id", cacheManager = "caffeineCacheManager")public Product getDetail(Long id) { return productDao.getById(id);}
这里使用了内存缓存。
第8招:批量操作优化
问题场景:逐条插入导致性能低下
优化方案:
@Transactionalpublic void batchInsert(List<Product> products) { jdbcTemplate.batchUpdate( "INSERT INTO product(name,price) VALUES(?,?)", products, 500, // 每批数量 (ps, product) -> { ps.setString(1, product.getName()); ps.setBigDecimal(2, product.getPrice()); });}
每500条数据插入一次数据库。
第9招:索引深度优化
问题场景:慢查询日志频繁出现全表扫描,SQL执行时间波动大
错误案例:
-- 商品表结构CREATE TABLE products ( id BIGINT PRIMARY KEY, name VARCHAR(200), category VARCHAR(50), price DECIMAL(10,2), create_time DATETIME);-- 低效查询SELECT * FROM products WHERE category = '手机' AND price > 5000 ORDER BY create_time DESC;
问题分析:
优化方案一:联合索引设计
索引创建:
下面创建了一个分类ID,单价和时间的联合索引:
ALTER TABLE products ADD INDEX idx_category_price_create (category, price, create_time);
优化方案二:覆盖索引优化
查询改造:
只查询索引包含字段:
SELECT id, category, price, create_time FROM products WHERE category = '手机' AND price > 5000 ORDER BY create_time DESC;
这里使用了覆盖索引。
优化方案三:索引失效预防
常见失效场景:
案例修复:
错误写法:
SELECT * FROM products WHERE DATE(create_time) = '2023-01-01';
正确写法:
SELECT * FROM products WHERE create_time BETWEEN '2023-01-01 00:00:00' AND '2023-01-01 23:59:59';
查询时间范围,这里使用了BETWEEN AND关键字,代替了等于号。
优化方案四:索引监控分析
诊断命令:
查看索引使用情况:
SELECT index_name, rows_read, rows_selected FROM sys.schema_index_statistics WHERE table_name = 'products';
分析索引效率:
EXPLAIN FORMAT=JSON SELECT ...;
索引优化黄金三原则
DBA工具箱
第10招:自定义线程池
问题场景:默认线程池导致资源竞争
优化方案:
@Bean("customPool")public Executor customThreadPool() { return new ThreadPoolExecutor( 10, // 核心线程 50, // 最大线程 60, TimeUnit.SECONDS, new LinkedBlockingQueue<>(1000), new CustomThreadFactory(), new ThreadPoolExecutor.CallerRunsPolicy());}
在高并发业务场景中,使用Executors类创建默认的线程池,可能会导致OOM问题。
因此,我们需要自定义线程池。
第11招:熔断限流策略
问题场景:突发流量导致服务雪崩
解决方案:
// 使用Sentinel实现接口限流@SentinelResource(value = "orderQuery", blockHandler = "handleBlock", fallback = "handleFallback")@GetMapping("/orders/{id}")public Order getOrder(@PathVariable Long id) { return orderService.getById(id);}// 限流处理public Order handleBlock(Long id, BlockException ex) { throw new RuntimeException("服务繁忙,请稍后重试");}// 降级处理public Order handleFallback(Long id, Throwable t) { return Order.getDefaultOrder();}
为了解决重复流量导致服务雪崩的问题,我们需要增加接口熔断、限流和降级处理。
第12招:全链路监控体系
问题场景:线上问题定位困难,缺乏数据支撑
我们需要增加项目全链路的监控。
监控方案:
# SpringBoot配置management: endpoints: web: exposure: include: "*" metrics: export: prometheus: enabled: true
这里使用了prometheus监控。
监控架构:
核心监控指标:
总结
SpringBoot性能优化检查清单
三条黄金法则:
性能工具包
相关文章
记者从上海沪剧院获悉,7月25日晚,上海沪剧院一级演员朱俭因病逝世,年仅50岁。作为著名沪剧中生代演员,朱俭1975年生于上海,从小爱唱歌,曾参加小荧...
2025-07-26 0
特朗普正式签字,圈定中美主战场,不过有意思的是,他这次的行为一定程度上反而不算坏事,为什么?不再自我束缚过去那套“小院高墙”的策略,如今在万斯们眼中,...
2025-07-26 0
#头号创作者激励计划#一种前所未有的量子材料正在重新定义物理学家对物质状态的理解。中美联合研究团队在Ta₂Pd₃Te₅晶体中发现了首个天然存在的拓扑激...
2025-07-26 0
36氪获悉,小米徕卡影像大赛特展今天开幕,四届影像大赛的100幅优秀作品参展。小米集团副总裁、首席营销官许斐介绍,小米徕卡影像大赛共收获数百万张参赛作...
2025-07-26 1
不知道在座的各位读者,有多少平常喜欢用无线充电给手机充电的?之所以抛出这个问题,那是因为小雷还真就是个无线充电爱好者,自打无线充电这个配置在手机上大量...
2025-07-26 0
人民网上海7月26日电 (记者唐小丽 今天上午,以“智能时代 同球共济”为主题的2025世界人工智能大会暨人工智能全球治理高级别会议在上海世博中心开幕...
2025-07-26 0
智东西作者 | 李水青编辑 | 漠影智东西7月25日报道,昨日晚间,阿里又又又开源了!阿里通义千问团队正式推出Qwen3-235B-A22B推理模型的...
2025-07-26 0
大窑汽水卖给美国人后被抵制 老品牌接二连三被外资控制最近网上都在骂大窑汽水,说他们把85%股份卖给美国公司了。好多喝了几十年的老人说现在味道变了,喝不...
2025-07-26 0
发表评论