Servlet 服务器性能提高--->数据库请求频率控制(原创)
首先我要说下我实现这个功能接口涉及到的业务和实现的详细流程,然后会说此接口涉及到的相关技术,最后会贴出注释后的详细代码, 这个接口涉及到的是 app上咻一咻功能,咻一咻中奖的奖品一共有七类,其中四类是兑换券的兑换额,另外三类是咻一咻提升中奖几率的功能券,前四类兑换券当玩家咻到之后就必须去访问数据库更新对应玩家兑换券额度,而且这频率是非常高的。就应为这点,所以我今天想了这个能够对接口进行减压的方法。
一、实现流程
首先数据库中有个单独的兑换券表,表的结构为:自增id=主键,用户的登录id=外建,4类券的值以一个json的格式的字符串存放到表中的一个字段中,那么现在该表一共就有3个字段(自增id,外建id,json格式的兑换券array),下面我截该表的图出来。

这些数据都是通过单例模式调用缓存中的数据进行更新或则插入的。下面我上流程图。

二、使用技术
单例模式、缓存、timer线程控制、数据处理使用JSONArray+JSONObject.
三、代码
1、servlet部分
package Servlet;
import java.io.IOException;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import Helper.MySqlHepler;
import Helper.ResultToJsonTool;
import Helper.ShareSingleton;
@WebServlet("/GamesXiuXiuServlet")
public class GamesXiuXiuServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
protected final String USER_AGENT = "Mozilla/5.0";
public GamesXiuXiuServlet() {
super();
// TODO Auto-generated constructor stub
}
@SuppressWarnings("null")
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType( "text/html");
response.setCharacterEncoding("utf-8");
request.setCharacterEncoding("utf-8");
String token;
String account;
String[] mysqlParameter;
JSONObject returnJsonObject; //LoadType
String CheckToken=null;
ResultSet returnData;
String Type;
JSONArray returnJsonArray;
String ReplaceStr;
HttpSession session ;
JSONObject SessionSaveDic;
Type=request.getParameter("type");
account=request.getParameter("account");
token=request.getParameter("token");
try {
CheckToken= ShareSingleton.getInstance().UsrTokenDictionary.getString(account);
} catch (JSONException e2) {
e2.printStackTrace();
}
if(!token.equals(CheckToken))
{
returnJsonObject =new JSONObject();
try {
returnJsonObject.put(");
returnJsonObject.put(");
returnJsonObject.put("Msg","token错误,请重新登录!");
} catch (JSONException e) {
e.printStackTrace();
}
response.getWriter().println(returnJsonObject.toString());
return;
}
")) //更新
{
ReplaceStr=request.getParameter("replaceJsonStr");
session = request.getSession();
SessionSaveDic=(JSONObject)session.getAttribute("allMemberDuiHuanKaListData");
try {
/*先修改缓存,然后一个timer控件对数据库做间歇性的修改*/
SessionSaveDic.put(account, ReplaceStr);
session.setAttribute("allMemberDuiHuanKaListData", SessionSaveDic);
//设置sessio 永不过期
ShareSingleton.getInstance().UpdateDuiHuanKaDictionary=SessionSaveDic;
session.setMaxInactiveInterval(-);
} catch (JSONException e2) {
// TODO Auto-generated catch block
e2.printStackTrace();
}
returnJsonObject =new JSONObject();
try {
returnJsonObject.put(");
returnJsonObject.put(");
returnJsonObject.put("Msg", "修改成功");
} catch (JSONException e) {
e.printStackTrace();
}
response.getWriter().println(returnJsonObject.toString());
}
//查询出游戏表当前所有数据
"))
{
session = request.getSession();
//这个值也会自动设置为空 由于咻咻玩的人比较多,所以将抵扣券的组合json放在内存中,然后使用时间间隔方式 更新数据库
SessionSaveDic=(JSONObject)session.getAttribute("allMemberDuiHuanKaListData");
if (SessionSaveDic != null) {
String SinglePeopleJson=SessionSaveDic.optString(account);
if(SinglePeopleJson!="")
{
try {
String JsonListData= SessionSaveDic.getString(account);
returnJsonArray=new JSONArray(JsonListData) ;
returnJsonObject =new JSONObject();
returnJsonObject.put("Rows", returnJsonArray);
returnJsonObject.put(");
returnJsonObject.put(");
response.getWriter().println(returnJsonObject.toString());
} catch (JSONException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
else//下面就去数据库总查询
{
//如果缓存中没有就从数据库中取出来,然后再修改
mysqlParameter=new String[]{account};
returnData=MySqlHepler.executeQueryT("select deductionCard from deductionCardSheet where account=?", mysqlParameter);
try {
returnJsonObject =new JSONObject();
returnJsonArray=ResultToJsonTool.resultSetToJsonArry(returnData);
JSONObject tempObject=returnJsonArray.getJSONObject();
String JsonList = tempObject.getString("deductionCard");
returnJsonArray=new JSONArray(JsonList) ;
returnJsonObject.put("Rows", returnJsonArray);
returnJsonObject.put(");
returnJsonObject.put(");
SessionSaveDic.put(account, returnJsonArray);
session.setAttribute("allMemberDuiHuanKaListData", SessionSaveDic);
//设置sessio 永不过期
ShareSingleton.getInstance().UpdateDuiHuanKaDictionary=SessionSaveDic;
ShareSingleton.getInstance().KeysArray.put(account);
session.setMaxInactiveInterval(-);
response.getWriter().println(returnJsonObject.toString());
} catch (SQLException | JSONException e1) {
e1.printStackTrace();
}
}
return;
} else{
//如果缓存中没有就从数据库中取出来,然后再修改
mysqlParameter=new String[]{account};
returnData=MySqlHepler.executeQueryT("select deductionCard from deductionCardSheet where account=?", mysqlParameter);
try {
returnJsonObject =new JSONObject();
returnJsonArray=ResultToJsonTool.resultSetToJsonArry(returnData);
JSONObject tempObject=returnJsonArray.getJSONObject();
String JsonList = tempObject.getString("deductionCard");
returnJsonArray=new JSONArray(JsonList) ;
returnJsonObject.put("Rows", returnJsonArray);
returnJsonObject.put(");
returnJsonObject.put(");
SessionSaveDic=new JSONObject();
SessionSaveDic.put(account, returnJsonArray);
session.setAttribute("allMemberDuiHuanKaListData", SessionSaveDic);
//设置sessio 永不过期
ShareSingleton.getInstance().UpdateDuiHuanKaDictionary=SessionSaveDic;
synchronized(this) {
//一次只能有一个线程进入
ShareSingleton.getInstance().KeysArray.put(account);
ShareSingleton.getInstance().TastIsOrNoRun=;
}
session.setMaxInactiveInterval(-);
response.getWriter().println(returnJsonObject.toString());
} catch (SQLException | JSONException e1) {
e1.printStackTrace();
}
}
}
}
}
2、单例模式部分
package Helper;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
public class ShareSingleton
{
public JSONObject UsrTokenDictionary;
public JSONObject UpdateDuiHuanKaDictionary;
public JSONArray KeysArray;
public static int updateIndex;
public int TastIsOrNoRun;
public static ShareSingleton instance=null;
public static ShareSingleton getInstance(){
if(instance == null){
instance = new ShareSingleton();
instance.UsrTokenDictionary=new JSONObject();
instance.UpdateDuiHuanKaDictionary=new JSONObject();
instance.KeysArray=new JSONArray();
return instance;
}else{
if(instance.TastIsOrNoRun==1)
{
timerTask();
instance.TastIsOrNoRun=10;
}
else
{
}
return instance;
}
}
public static void timerTask() {
new Timer().schedule(new TimerTask(){
@Override
public void run() {
JSONObject TempDictionaryX=instance.UpdateDuiHuanKaDictionary;
JSONArray KeysArray=instance.KeysArray;
try {
// JSONObject TempDictionaryX= TempDictionary; //TempDictionary.getJSONObject("allMemberDuiHuanKaListData");
if( updateIndex== KeysArray.length()-1)
{
//这里已经有key了,可以去修改数据库了,我这里设置的10秒钟修改一条数据
String UpdateKey=(String) KeysArray.get(updateIndex);
String UpdateJson= TempDictionaryX.getString(UpdateKey);
//这个updatekey就是user的登录id也就是字典的取值id
String[] mysqlParameter=new String[]{ UpdateJson,UpdateKey};
//更新游戏
//这里要访问两次数据库,第一次修改user表第二次修改游戏表
// update userSheet set userIntegral=userIntegral-1,userTotalIntegral=userTotalIntegral+10 where account= '13983918071';
MySqlHepler.executeUpdate("update deductionCardSheet set deductionCard=? where account=?",mysqlParameter);
updateIndex=0;
}
else
{
//这里已经有key了,可以去修改数据库了,我这里设置的10秒钟修改一条数据
String UpdateKey= KeysArray.getString(updateIndex);
String UpdateJson= TempDictionaryX.getString(UpdateKey);
//这个updatekey就是user的登录id也就是字典的取值id
String[] mysqlParameter=new String[]{ UpdateJson,UpdateKey};
//更新游戏
//这里要访问两次数据库,第一次修改user表第二次修改游戏表
// update userSheet set userIntegral=userIntegral-1,userTotalIntegral=userTotalIntegral+10 where account= '13983918071';
MySqlHepler.executeUpdate("update deductionCardSheet set deductionCard=? where account=?",mysqlParameter);
updateIndex++;
}
} catch (JSONException e) {
e.printStackTrace();
}
}
},new Date(),20000);
}
}
四、总结
用户所有对数据的操作都在缓存中进行,通过单例模式里的timer控制缓存中的数据去更新数据库上的数据。
Servlet 服务器性能提高--->数据库请求频率控制(原创)的更多相关文章
- 20个Linux服务器性能调优技巧
Linux是一种开源操作系统,它支持各种硬件平台,Linux服务器全球知名,它和Windows之间最主要的差异在于,Linux服务器默认情况下一般不提供GUI(图形用户界面),而是命令行界面,它的主要 ...
- Linux服务器性能查看分析调优
一 linux服务器性能查看 1.1 cpu性能查看 1.查看物理cpu个数: cat /proc/cpuinfo |grep "physical id"|sort|uniq|wc ...
- 【转】linux服务器性能查看
转载自https://blog.csdn.net/achenyuan/article/details/78974729 1.1 cpu性能查看 1.查看物理cpu个数: cat /proc/cpuin ...
- Linux服务器性能分析与调优
一 linux服务器性能查看 1.1 cpu性能查看 1.查看物理cpu个数: cat /proc/cpuinfo |grep "physical id"|sort|uniq|wc ...
- linux服务器性能查看
1.1 cpu性能查看 1.查看物理cpu个数: cat /proc/cpuinfo |grep "physical id"|sort|uniq|wc -l 2.查看每个物理cpu ...
- [转]20个你不得不知的Linux服务器性能调优技巧
Linux是一种开源操作系统,它支持各种硬件平台,Linux服务器全球知名,它和Windows之间最主要的差异在于,Linux服务器默认情况下一般不提供GUI(图形用户界面),而是命令行界面,它的主要 ...
- T-SQL怎样提高数据库性能
总结: 1.书写问题 2.表连接方式 3.索引的抉择 4.执行计划之参数嗅探 5.子查询与表连接的效率 6.临时表.CTE.表变量的选择 7.常用sp与select的缓存命中 8.锁(善用nolock ...
- 使用SQL-Server分区表功能提高数据库的读写性能
首先祝大家新年快乐,身体健康,万事如意. 一般来说一个系统最先出现瓶颈的点很可能是数据库.比如我们的生产系统并发量很高在跑一段时间后,数据库中某些表的数据量会越来越大.海量的数据会严重影响数据库的读写 ...
- 走向DBA[MSSQL篇] - 从SQL语句的角度提高数据库的访问性能(转)
最近公司来一个非常虎的DBA,10几年的经验,这里就称之为蔡老师吧,在征得我们蔡老同意的前提下 ,我们来分享一下蔡老给我们带来的宝贵财富,欢迎其他的DBA来拍砖. 目录 1.什么是执行计划?执行计划 ...
随机推荐
- Dropzone.js实现文件拖拽上传
dropzone.js是一个开源的JavaScript库,提供 AJAX 异步文件上传功能,支持拖拽文件.支持最大文件大小.支持设置文件类型.支持预览上传结果,不依赖jQuery库. 使用Dropzo ...
- Android中的多线程断点下载
首先来看一下多线程下载的原理.多线程下载就是将同一个网络上的原始文件根据线程个数分成均等份,然后每个单独的线程下载对应的一部分,然后再将下载好的文件按照原始文件的顺序"拼接"起来就 ...
- Activity之概览屏幕(Overview Screen)
概览屏幕 概览屏幕(也称为最新动态屏幕.最近任务列表或最近使用的应用)是一个系统级别 UI,其中列出了最近访问过的 Activity 和任务. 用户可以浏览该列表并选择要恢复的任务,也可以通过滑动清除 ...
- could not initialize proxy - no Session
这是一个精典的问题:因为我们在hibernate里面load一个对象出来时,用到的是代理对象,也就是说当我们在执行load方法时并没有发sql语句,而是返回一个proxy对象.只有当们具体用到哪个ge ...
- 喜马拉雅音频下载器 V1.2 支持专辑批量下载 喜马拉雅mp3下载导出 喜马拉雅下载器
出差一个星期回来看邮箱,发现好多网友评论说网站又更新了,老程序不能用了,有热心网友放出修改版的,我就不重复造车了..大家可以去这里下载 http://blog.csdn.net/suqingheang ...
- 【番外篇】ASP.NET MVC快速入门之免费jQuery控件库(MVC5+EF6)
目录 [第一篇]ASP.NET MVC快速入门之数据库操作(MVC5+EF6) [第二篇]ASP.NET MVC快速入门之数据注解(MVC5+EF6) [第三篇]ASP.NET MVC快速入门之安全策 ...
- MongoDB基础
1.概念及特点 说明:由于部分语句中$ 符号无法正常显示,使用¥代表 概念 MongoDB是一个基于文档的分布式的开源的NoSQL数据库,文档的结构为BSON形式,每一个文档都有一个唯一的Object ...
- 我的MYSQL学习心得(十四) 备份和恢复
我的MYSQL学习心得(十四) 备份和恢复 我的MYSQL学习心得(一) 简单语法 我的MYSQL学习心得(二) 数据类型宽度 我的MYSQL学习心得(三) 查看字段长度 我的MYSQL学习心得(四) ...
- .NET深入实战系列--EF到底怎么写过滤条件
本文唯一访问地址:http://www.cnblogs.com/yubaolee/p/DynamicLinq.html 对于系统开发来说,按不同字段进行过滤查询是一种常见的需求.在EF中通常的做法是: ...
- Egret3D研究报告(二)从Unity3D导出场景到Egret3D
Egret3D暂时没有场编的计划,但是我们知道unity3D是一个很好的场编. 有一些游戏即使不是使用Unity3D开发,也使用Unity3D做场编.这里就不点名了,而且并不在少数. 我们就这么干. ...