java大并发数据保存方案
做了几年.net,如今终于要做java了。
- 需求:
线下终端会定时上传gps位置到服务端,服务端收到数据保存到mysql数据库,当线下终端过多时,问题出现了,首当其冲的是数据库连接池经常会崩溃,单个tomcat到100并发就会抛出异常。
- 解决思路:
原来是收到一条数据就保存一条数据,现在改为将收到的数据暂存到一个数据池,当满100条数据时再用saveBatch一次性保存,这样终端上传100次其实只建立了一次数据库连接,减轻数据库压力。如果只是这样还有一个不足,就是当数据池的数据一直都不满100条时,永远都不会保存到数据库,所以再加一个守护线程,每2分钟检查一次,如果数据池有数据,就全部保存到数据库。

- 该方案执行效率,如下图,共1000次请求,100次并发的情况

- 具体实现:
1、数据池代码
public class GpsPool {
private static final Logger log = Logger.getLogger(GpsPool.class.getName());
public static Queue<ClientGPS> queGps=new LinkedList<ClientGPS>();//暂存数据,等数据超过100条或者超过时间后自动保存
private static Object lock=new Object();
//private ExecutorService s=Executors.newSingleThreadExecutor();
private ThreadPoolExecutor threadPool = new ThreadPoolExecutor(1, 1, 10, TimeUnit.MILLISECONDS,
new ArrayBlockingQueue<Runnable>(1),new ThreadPoolExecutor.DiscardPolicy());
/**
* 一次性最多取出100个数据
* @return
*/
public static List<ClientGPS> poll100(){
List<ClientGPS> gpss=new ArrayList<ClientGPS>();
synchronized (lock) {
int length=100;
if(queGps.size()<100)
length=queGps.size();
for (int i = 0; i < length; i++) {
gpss.add(queGps.poll());
}
}
return gpss;
}
public void saveGps(ClientGPS gps){
if (null==gps||queGps.size()>2000) {//大于2000暂不处理
return;
}
if (queGps.size()>100) {
queGps.offer(gps);
threadPool.execute(new GpsSaveThread());
System.out.println("add2pool");
}else{
queGps.offer(gps);
}
}
}
2、数据保存线程
class GpsSaveThread implements Runnable{
private static final Logger log = Logger.getLogger(GpsTask.class.getName());
ClientGPSService gpsService;
@Override
public void run() {
gpsService=ServiceLocator.getBean(ClientGPSService.class);
try {
List<ClientGPS> gpss;
while (GpsPool.queGps.size() > 100) {
gpss = GpsPool.poll100();
if (gpss.size() > 0) {
try {
gpsService.saveBatch(gpss.toArray(), gpss.size());
} catch (Exception e) {
saveError(e);
try {//失败后再试一次
gpsService.saveBatch(gpss.toArray(), gpss.size());
} catch (Exception ex) {
}
}
}
}
} catch (Exception e) {
saveError(e);
}
}
}
3、守护线程代码
public class GpsTask implements Runnable{
private static final Logger log = Logger.getLogger(GpsTask.class.getName());
ClientGPSService gpsService;
@Override
public void run() {
gpsService=ServiceLocator.getBean(ClientGPSService.class);
while (true) {
try {
Thread.sleep(1000*60*2);//2分钟检查一次
List<ClientGPS> gpss= GpsPool.poll100();
GpsPool.queGps.clear();
if(gpss.size()>0){
try {
gpsService.saveBatch(gpss.toArray(),gpss.size());
} catch (Exception e) {
saveError(e);
}
}
} catch (InterruptedException e) {
saveError(e);
}catch(Exception e){
saveError(e);
}
}
}
}
守护线程代码
- 抛砖引玉
目前这个方案有点问题,就是并发过千时,cpu会达到100%,期待有更好的方案。
java大并发数据保存方案的更多相关文章
- JAVA大集合数据分批次进行切割处理
今天遇到一个大集合里面的数据删除问题, 因为是一个大集合,如果同时传递到数据库,那么就会造成数据库压力 所以分批次的进行批量操作 其实 也可以采用多线程来处理或者多批次加多线程来处理都是可以的 下面的 ...
- Java+MySql图片数据保存与读取的具体实例
1.创建表: drop table if exists photo;CREATE TABLE photo ( id INT NOT NULL AUTO_INCREMENT PRIMARY KEY ...
- Java读取excel数据保存入库
Java开发读取excel表格数据入库保存: List<Map<String, Object>> list = null; String filePath = filePath ...
- Java+MySql图片数据保存
之前一直没有做过涉及到图片存储的应用,最近要做的东东涉及到了这个点,就做了一个小的例子算是对图片存储的初试吧! 1.创建表: drop table if exists photo; CREATE TA ...
- java ->大的数据运算(BigInteger)
大数据运算 BigInteger java中long型为最大整数类型,对于超过long型的数据如何去表示呢.在Java的世界中,超过long型的整数已经不能被称为整数了,它们被封装成BigIntege ...
- Linux Bash 脚本:自己定义延迟代码块(裸数据保存方案)
结合 alias 和 read 使用方法.能够保存一些将要延迟执行的脚本,或者裸数据(字符串不被扩展)到一个变量中.以备后用. $ alias BEGIN='read -d "" ...
- Sqlserver 高并发和大数据存储方案
Sqlserver 高并发和大数据存储方案 随着用户的日益递增,日活和峰值的暴涨,数据库处理性能面临着巨大的挑战.下面分享下对实际10万+峰值的平台的数据库优化方案.与大家一起讨论,互相学习提高! ...
- Java大数据人才应用领域广,就业薪酬高
互联网创造了大数据应用的规模化环境,大数据应用成功的案例大都是在互联网上发生的, 互联网业务提供了数据,互联网企业开发了处理软件,互联网企业的创新带来了大数据应用 的活跃,没有互联网便没有今天的大数据 ...
- Java高并发的常见应对方案
Java高并发的常见应对方案 一.关于并发我们说的高并发是什么? 在互联网时代,高并发,通常是指,在某个时间点,有很多个访问同时到来. 高并发,通常关心的系统指标与业务指标? QPS:每秒钟查询量,广 ...
随机推荐
- kubernetes单机板
参考地址: *** http://blog.csdn.net/carter115/article/details/51121223 ** http://www.cnblogs.com/dongdong ...
- ftp文件的部署
之前在公司搭建了一个静态资源服务器,现在来记录一下 我们是通过搭建vsftp服务,然后结合apache.访问方式为http的方式 一:VSFTPD环境安装 首先我们就是要查看一下vsftpd是否有安装 ...
- mysql 多版本并发控制
查看事务隔离级别 SHOW VARIABLES LIKE "%iso%" MVCC 通过给每张表多加两个隐藏列来实现,一个保存了行的创建时间,一个保存了行的过期时间(或删除时间), ...
- 【BZOJ 4581】【Usaco2016 Open】Field Reduction
http://www.lydsy.com/JudgeOnline/problem.php?id=4581 考虑\(O(n^3)\)暴力. 实际上枚举最靠边的三个点就可以了,最多有12个点. 还是暴力= ...
- python基础补漏-01
python对象的方法 1.python的特性:一切皆对象 2 type(obj) 查看对象的类型 3 dir(obj)查看类中所有详细的功能 4 help(obj) 查看类中所有详细的功能 类中的方 ...
- IE兼容方法
其实我也觉得非常麻烦,开始的时候都用 _XXX:XXX; /* IE6支持 */ *XXX:XXX; /* IE6.IE7支持 */ *+XXX:XXX; /* IE7支持 */ XXX:XXX\9; ...
- java利用JDK调用并执行js源码
前言: 不同开发语言之间具有通用性,更具有协作调用的可能.有时候对于一些场景会有调用js的需求,因此下面展示了一个java利用自身JDK调用js函数的demo,供感兴趣的朋友参考. js函数文件 ex ...
- 【BZOJ-2653】middle 可持久化线段树 + 二分
2653: middle Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 1298 Solved: 734[Submit][Status][Discu ...
- Scrum Meeting 20161207
本周Sprint Master 史少帅 会议概要 工作总结: · 陈双: 等待BHB的下载录音文件的接口,再在服务器端存储录音材料 · 王永超: 打分功能单独测试正确,但合并到项目时出现错误,待解决 ...
- Chrome 开发工具之Sources
Sources面板主要用于查看web站点的资源列表及javascript代码的debug 熟悉面板 了解完面板之后,下面来试试这些功能都是如何使用的. 文件列表 展示当前页面内所引用资源的列表,和平常 ...