做了几年.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大并发数据保存方案的更多相关文章

  1. JAVA大集合数据分批次进行切割处理

    今天遇到一个大集合里面的数据删除问题, 因为是一个大集合,如果同时传递到数据库,那么就会造成数据库压力 所以分批次的进行批量操作 其实 也可以采用多线程来处理或者多批次加多线程来处理都是可以的 下面的 ...

  2. Java+MySql图片数据保存与读取的具体实例

    1.创建表: drop table if exists photo;CREATE TABLE photo (    id INT NOT NULL AUTO_INCREMENT PRIMARY KEY ...

  3. Java读取excel数据保存入库

    Java开发读取excel表格数据入库保存: List<Map<String, Object>> list = null; String filePath = filePath ...

  4. Java+MySql图片数据保存

    之前一直没有做过涉及到图片存储的应用,最近要做的东东涉及到了这个点,就做了一个小的例子算是对图片存储的初试吧! 1.创建表: drop table if exists photo; CREATE TA ...

  5. java ->大的数据运算(BigInteger)

    大数据运算 BigInteger java中long型为最大整数类型,对于超过long型的数据如何去表示呢.在Java的世界中,超过long型的整数已经不能被称为整数了,它们被封装成BigIntege ...

  6. Linux Bash 脚本:自己定义延迟代码块(裸数据保存方案)

    结合 alias 和 read 使用方法.能够保存一些将要延迟执行的脚本,或者裸数据(字符串不被扩展)到一个变量中.以备后用. $ alias BEGIN='read -d "" ...

  7. Sqlserver 高并发和大数据存储方案

    Sqlserver 高并发和大数据存储方案 随着用户的日益递增,日活和峰值的暴涨,数据库处理性能面临着巨大的挑战.下面分享下对实际10万+峰值的平台的数据库优化方案.与大家一起讨论,互相学习提高!   ...

  8. Java大数据人才应用领域广,就业薪酬高

    互联网创造了大数据应用的规模化环境,大数据应用成功的案例大都是在互联网上发生的, 互联网业务提供了数据,互联网企业开发了处理软件,互联网企业的创新带来了大数据应用 的活跃,没有互联网便没有今天的大数据 ...

  9. Java高并发的常见应对方案

    Java高并发的常见应对方案 一.关于并发我们说的高并发是什么? 在互联网时代,高并发,通常是指,在某个时间点,有很多个访问同时到来. 高并发,通常关心的系统指标与业务指标? QPS:每秒钟查询量,广 ...

随机推荐

  1. C/C++的基本数据类型

    数据类型决定数据的空间分配, 及能对其做什么操作. C语言中的四种基本数据类型: char,int,float,double. C与C++定义这些类型时都只是限定它们的最大最小值, 而不是它们的siz ...

  2. Masonry tableviewCell布局(转)

    转载自:http://www.henishuo.com/masonry-tableviewcell-layout/ 前言 说到iOS自动布局,有很多的解决办法.有的人使用xib/storyboard自 ...

  3. bat转exe工具 Bat To Exe Converter v2.4.7 绿色版

    一款非常小巧的工具,从它的名称便能知道它的功能:它能将BAT或CMD文件转换成 EXE 文件.使用它,你可以保护由自己开发的软件的软件代码,创建一个漂亮的图标,让软件看起来更专业. 下载地址: htt ...

  4. javascript中正则实现读取当前url中指定参数值方法。

    getQueryString:function(name) { var reg = new RegExp("(^|&)"+ name +"=([^&]*) ...

  5. 神秘代理-Proxy

    前言: 代理模式作为常见的设计模式之一,在项目开发中不可或缺.本文就尝试着揭开代理的神秘面纱,也欢迎各路人批评指正! 1.如何实现代理: [假设有个关于汽车移动(move)的计时需求]设计:Movea ...

  6. Ajax操作如何实现跨域请求 (JSONP和CORS实现Ajax跨域的原理)

    由于浏览器存在同源策略机制,同源策略阻止ajax (XMLHttpRequest) 从一个源加载的文档或脚本获取或设置另一个源加载的文档的属性. 特别的:由于同源策略是浏览器的限制,所以请求的发送和响 ...

  7. Python字符串输入输出简述

    字符串输入 Python用到的输入一般有两种方式,input() 和 raw_input() ,区别是,前者只能输入数字,后者输入的是字符串,使用如下: In [226]: help(input) H ...

  8. JAVA源码分析-HashMap源码分析(一)

    一直以来,HashMap就是Java面试过程中的常客,不管是刚毕业的,还是工作了好多年的同学,在Java面试过程中,经常会被问到HashMap相关的一些问题,而且每次面试都被问到一些自己平时没有注意的 ...

  9. JS原生ajax与Jquery插件ajax深入学习

    序言: 近来随着项目的上线实施,稍微有点空闲,闲暇之时偶然发现之前写的关于javascript原生xmlHttpRequest ajax方法以及后来jquery插件ajax方法,于是就行了一些总结,因 ...

  10. Windows下搭建PHP开发环境

    PHP集成开发环境有很多,如XAMPP.AppServ......只要一键安装就把PHP环境给搭建好了.但这种安装方式不够灵活,软件的自由组合不方便,同时也不利于学习.所以我还是喜欢手工搭建PHP开发 ...