前些天发过一篇帖子,是关于memcached如何用于轮询数据显示的一个想法,今天在自己的项目中实现了这个想法。其实这个东西可以扩展到很多的应用中,不多说了,下面是这个想法的原型实现。有点对不起大家了,这是个jsp,只是个思路而已,可以变形扩展到其他地方去。前提:需要有spring框架的支持,memcached客户端用的是java_memcached 2.0.1,是通过spring依赖注入的,服务端需要自己去在服务器配置一下。
其实思路很简单,下面的例子是通过简单提交的userid来作为key,value保存最近一次访问的集合索引值,从0开始的,大于等于集合个数时候返回到0位置继续轮询,设置了每隔10s显示下一个元素,10s内同一个用户看到的内容是相同的。
不用数据库或者文件作为存储介质,所有操作都在内存中进行,这样速度明显要有很大的提升,但是如何合理的利用memcached,想要做的完善还是有很多细节要考虑的。
其实思路很简单,下面的例子是通过简单提交的userid来作为key,value保存最近一次访问的集合索引值,从0开始的,大于等于集合个数时候返回到0位置继续轮询,设置了每隔10s显示下一个元素,10s内同一个用户看到的内容是相同的。
不用数据库或者文件作为存储介质,所有操作都在内存中进行,这样速度明显要有很大的提升,但是如何合理的利用memcached,想要做的完善还是有很多细节要考虑的。
<%@ page contentType="text/html; charset=UTF-8"%>
<%@ page import="java.util.*"%>
<%@ page import="org.springframework.web.context.support.*,org.springframework.context.*"%>
<%@ page import="com.danga.MemCached.MemCachedClient"%>
<%@ page import="org.apache.log4j.Logger"%>
<%@ page import="com.sharppointgroup.ad.util.ADUtil"%>
<!DOCTYPE html PUBLIC "-//WAPFORUM//DTD XHTML Mobile 1.0//EN" "http://www.wapforum.org/DTD/xhtml-mobile10.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="application/xhtml+xml; charset=UTF-8"/>
<meta name="viewport" content="width=device-width; initial-scale=1.3; minimum-scale=1.0; maximum-scale=2.0"/>
<meta name="MobileOptimized" content="240"/>
<meta name="format-detection" content="telephone=no" />
<title>Memcached Test</title>
</head>
<%!
private static final Logger memcacheLogger = Logger.getLogger("memcache");
private String userid = null;
private String result = null;
private static List<String> v = new ArrayList<String>();
static{
v.add("1");
v.add("2");
v.add("3");
v.add("4");
v.add("5");
}
%><%
request.setCharacterEncoding("utf-8");
if(request.getParameter("user") != null){
userid = request.getParameter("user");
ApplicationContext ctx = WebApplicationContextUtils.getWebApplicationContext(getServletContext());
MemCachedClient memCache = (MemCachedClient) ctx.getBean("memCache");
String cacheKey = "userid_" + userid;
String timeStampKey = cacheKey + "_lasttime_";
Object cacheObj = memCache.get(cacheKey);
out.print("isHasCacheKey:"+memCache.keyExists(cacheKey)+"<br/>");
out.print("isHasTimeStampKey:"+memCache.keyExists(timeStampKey)+"<br/>");
if(cacheObj == null){
result = v.get(0);
memCache.add(cacheKey, 0, 24*60*60);
memCache.add(timeStampKey, System.currentTimeMillis(), 24*60*60);
}
else{
if(memCache.keyExists(timeStampKey) && (System.currentTimeMillis()-Long.parseLong(memCache.get(timeStampKey).toString())) >= 10000){
memCache.set(cacheKey, Integer.parseInt(memCache.get(cacheKey).toString())+1);
memCache.set(timeStampKey, System.currentTimeMillis());
}
if(Integer.parseInt(memCache.get(cacheKey).toString()) >= v.size())
memCache.set(cacheKey, 0);
result = v.get(Integer.parseInt(memCache.get(cacheKey).toString()));
}
out.println("cacheKey:"+cacheKey+" value:"+result + "<br/>");
out.println("timeStampKey:"+timeStampKey+" value:"+memCache.get(timeStampKey) + "<br/>");
String logInfo = ADUtil.createLogInfo("cacheKey="+cacheKey,"cacheValue="+memCache.get(cacheKey),
"timeStamp="+new Date(Long.parseLong(memCache.get(timeStampKey).toString())));
memcacheLogger.info(logInfo);
}
%>
<body>
<% if(request.getParameter("user") == null){%>
<form action="test.jsp" method="post">
<input type="text" name="user" size="15" value="" /><input name="submit" type="submit" value="提交" />
</form>
<%}%>
</body>
</html>