Java后台服务慢优化杂谈
Java后台服务慢优化杂谈
前言
你是否遇到过这样的场景,当我们点击页面某个按钮后,页面一直loading,要等待好几分钟才出结果的画面,有时直接502或504,作为一个后台开发,看到自己开发的系统是这个样子,就问你惭愧吗。
这种问题其实是性能问题,当用户量少数据少的时候,处理还是很快的,数据量一旦大起来,后台处理时间就会延长,前端大部分直接超时或无限等待直接死掉。
方案
解决数据量大的性能问题,要根据实际业务场景来针对分析。但归根结底,只有一条最终方案,即减少与数据库交互次数,尤其是在for循环里面。我们所有慢的场景,按这个方式优化,之前好几分钟,十几分钟的功能都优化到了3秒内。
For循环内查询数据库优化
我们很多场景如新增,修改,上传,下载报表,都会有for循环内查询数据库的操作,而且一次循环有的与数据库要交互好次操作,这样下来如果循环是以用户列表来处理的,一个租户下1000个用户,每个用户要与数据库交互几次,再乘以1000,想想得多耗时。
这种场景的优化很简单,直接将循环体内与数据库的交互全部拿到循环外,通过业务逻辑,表结构关系是可以做到的,然后在循环体内只做内存计算,实验证明,循环体内与数据库交互的次数越少,耗时越小,可能有人会那你循环体内Java处理也慢啊,非也,Java纯内存处理其实一点都不慢。
//声明for循环处理结果集
List<?> list = new ArrayList<>();
//循环前提前向数据库查询要用到的数据
List<?> userList = userMapper.selectList(xxx);
for(User user: userList){
//处理单个用户业务逻辑,避免多次查库
list.add(xxx);
}
For循环内修改数据库优化
上面说的是循环体内查询数据库,这里要说的场景就是循环体内插入或修改数据库记录,还是1000个用户循环插入或修改关联表,与数据库的交互次数也庞大的,这里的优化也很简单,将要变更到数据库对象全部封装到集体中,循环处理完成后 ,再一次性或分批将集合数据插入数据库,这也会大大提高修改操作的性能的。
//定义待插入数据库的集合
List<User> list = new ArrayList();
for(User u : userList){
//处理待插入数据库的User对象
list.add(u);
}
//批量(也可以设置分批次)插入数据库
userMapper.batchInsert(list);
多线程并发处理
增加线程池这种优化方案就不用多说了吧
threadPoolTaskExecutor.submit(()->{
try {
//业务逻辑处理
} catch (Exception e) {
}
});
缓存
在以上业务代码优化完毕,如果还要再提升性能,那就可以对多查询的业务加缓存处理,如Redis,Memcached。
异步
缓存也加了,并发性能还上不来,就可以使用异步处理了,将请求放入消息队列MQ,然后多线程异步消费队列处理请求。
服务器集群
在生产环境一般都不会是单节点部署,要保障系统稳定性肯定是要多节点部署,这也能在优化代码代码的基础上提高并发性能,尤其是当使用中间件如缓存,MQ,更是要使用多节点集群,才能发挥中间件的作用,如上篇 Redis+Kafka异步提高并发,可以将接口并发能力提升到3000-5000QPS。
作者介绍:小林,狐小E资深开发工程师,专注移动协同办公平台的SAAS软件开发以及轻应用开发
最近开发了一款移动办公软件 狐小E
Java后台服务慢优化杂谈的更多相关文章
- android支付宝app支付(原生态)-包括android前端与java后台
本文讲解了 android开发的原生态app集成了支付宝支付, 还提供了java后台服务器处理支付宝支付的加密代码, app前端与java后台服务器使用json数据格式交互信息,java后台服务主要用 ...
- android 集成支付宝app支付(原生态)-包括android前端与java后台
本文讲解了 android开发的原生态app集成了支付宝支付, 还提供了java后台服务器处理支付宝支付的加密代码, app前端与java后台服务器使用json数据格式交互信息,java后台服务主要用 ...
- 【JavaService】部署Java jar为Windows后台服务
将Java jar文件部署为Windows后台服务有多种方法:Service Installer.Java service Wrapper.JavaService.exe等等.这里介绍下使用JavaS ...
- 将java打jar包成linux后台服务service
将java打jar包成linux后台服务service 第一步:将java程序打成jar包 build.gradle配置文件中加spring-boot-gradle-plugin插件,具体配置如下(配 ...
- 【POI】java服务生成List数据集合,后台服务生成xlsx临时文件,并将临时文件上传到腾讯云上
场景: java服务生成List数据集合,后台服务生成xlsx临时文件,并将临时文件上传到腾讯云上 今日份代码: 1.先是一个变量,作为文件名 private static final String ...
- 如何用CropBox实现头像裁剪并与java后台交互
如何用CropBox实现头像裁剪并与java后台交互 参考网站:https://developer.mozilla.org/zh-CN/docs/Web/API/Blob 参考: http://blo ...
- 非科班双非本科投的337家Java后台(励志)
考试结束,班级平均分只拿到了年级第二,班主任于是问道:大家都知道世界第一高峰珠穆朗玛峰,有人知道世界第二高峰是什么吗?正当班主任要继续发话,只听到角落默默想起来一个声音:”乔戈里峰” 前言 文章出自h ...
- Java后台面试记录
腾讯一面: 总结:考基础和代码(网址A是不是网址B的子域) + SQL(选出重复邮箱)(以下是没回答上来的) 逻辑回归公式(简历上写了协同过滤) 详见:https://blog.csdn.net/ma ...
- Android 三级联动选择城市+后台服务加载数据库
技术渣,大家将就着看 首先我们需要一个xml数据保存到数据库,这里我从QQ下面找到一个loclist.xml文件 <CountryRegion Name="中国" Code= ...
随机推荐
- Python os.remove() 方法
概述 os.remove() 方法用于删除指定路径的文件.如果指定的路径是一个目录,将抛出OSError.高佣联盟 www.cgewang.com 在Unix, Windows中有效 语法 remov ...
- Python os.mkfifo() 方法
概述 os.mkfifo() 方法用于创建指令路径的管道,并设置权限模式.默认的模式为 0666 (八进制).高佣联盟 www.cgewang.com 语法 mkfifo()方法语法格式如下: os. ...
- PHP decoct() 函数
实例 把十进制转换为八进制: <?phpecho decoct("30") . "<br>";echo decoct("10&quo ...
- HDU 6787 Chess 2020百度之星 初赛三 T5 题解 dp
传送门:HDU 6787 Chess Problem Description 你现在有一个棋盘,上面有 n 个格子,格子从左往右,1,-,n 进行标号.你可以在棋盘上放置恰好 m 个传送器,并且对于每 ...
- efcore 新特性 SaveChanges Events
efcore 新特性 SaveChanges Events Intro 昨天早上看到之前关注的一个 efcore 的 issue 被 closed ,于是看了一眼, ef core 新合并了一个 PR ...
- python5.2文件写入
fh=open(r"C:\55.txt","w")#文件编写新的文字,替代原有的文字!w:writedata = "努力让生活更美好!"fh ...
- kubeadm部署1.17.3[基于Ubuntu18.04]
基于 Ubuntu18.04 使用 kubeadm 部署Kubernetes 1.17.3 高可用集群 环境 所有节点初始化 # cat <<EOF>> /etc/hosts ...
- MySQL数据库——查询数据
增加数据: insert into "表名" values( '字段'',字段'); 或insert into '表名'( '字段'',字段') values( '字段'',字段 ...
- C#LeetCode刷题-队列
队列篇 # 题名 刷题 通过率 难度 363 矩形区域不超过 K 的最大数值和 27.2% 困难 621 任务调度器 40.9% 中等 622 设计循环队列 C#LeetCode刷题之#622 ...
- 装机备忘录:VS Code 常用插件
VS Code 常用插件推荐 1.基本的代码补全 2.git 扩展工具,可以看到代码的每一行 是谁修改?什么时候修改? 修改的版本号? 修改的注释? 非常好的一个工具 3.括号颜色改变工具,可以改变括 ...