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= ...
随机推荐
- 2020牛客暑期多校训练营 第二场 K Keyboard Free 积分 期望 数学
LINK:Keyboard Free 我要是会正经的做法 就有鬼了. 我的数学水平没那么高. 三个同心圆 三个动点 求围成三角形面积的期望. 不会告辞. 其实可以\(n^2\)枚举角度然后算出面积 近 ...
- windows:shellcode 远程线程hook/注入(一)
https://www.cnblogs.com/theseventhson/p/13199381.html 上次分享了通过APC注入方式,让目标线程运行shellcode.这么做有个前提条件:目标线程 ...
- Linux的VMWare中Centos7文件系统挂载和开启网卡及简单命令
一.路径 挂载磁盘/etc/fastab 开启网卡 vi .bash_profile ---更改PATH环境变量 可设置 mysql提示符 cd /etc/yum.rep ...
- 用大白话解释什么是Socket
好好学习,天天向上 本文已收录至我的Github仓库DayDayUP:github.com/RobodLee/DayDayUP,欢迎Star,更多文章请前往:目录导航 前言 我在去年就学习过Java中 ...
- python爬虫学习05-爬取图片
python爬虫学习05-爬取图片 确定要爬取的网址:https://shenan.tuchong.com/20903415/#image309854686 要爬取的内容:使用浏览器插件xpath对图 ...
- 【JZOJ4726】种花 题解(贪心+堆)
题目大意:在一个长度为$n$的环型序列中取出$m$个数使这$m$个数的和最大,且要求这$m$个数互不相邻. ---------------------- 考虑维护$nxt$和$lst$,即一个数的前驱 ...
- jquery的父级和兄弟级能做多少网页特效
这里说的父级就是parent 兄弟级就是siblings 我这里说一个导航栏用到的特效 主要jquery代码$(this).parent().addClass(“active”).siblings( ...
- Error: Cannot perform an interactive login from a non TTY device
zhangjiawen@zhangjiawen-PC MINGW64 /d/Docker Toolbox$ docker login --username=绝世随机变量 registry.cn-han ...
- python flask构建小程序订餐系统--centos下项目开发环境的搭建
1.项目开发环境的搭建(Linux环境) 1)软件的安装 我们搭建整个项目的过程中,我们需要用到下面的一些软件,但是这些软件的安装过程我们在这里不用说明.(因为windows软件的安装比较的简单,类似 ...
- 001_go语言中的hello world
代码演示: package main import "fmt" func main() { fmt.Println("hello world") } 代码解读: ...