memcache实现公共计数器网站
在反问题的过程中遇到的最近项目。网上查了很多资料并没有完全实现。
因此,要找到适合自己的xmemcache client和memcache关联API和说明,我们发现了一个比较完美的实现。
键类:net.rubyeye.xmemcached.Counter
相关API
实现思路:
获取:
获取的时候默认从memcache中获取,初次获取没获得的话载入数据库获取值,并初始化计数器的值。
更新
先从memcache中获取计数器的值,没有获取到得的话载入数据库获取值,并初始化计数器的值。
然后将计数器加1,获取操作后的返回值,假设是100的整数倍就更新到数据库
下面是关键实现类的代码
package com.liu.memcache.tools;
import java.io.IOException;
import net.rubyeye.xmemcached.Counter;
import net.rubyeye.xmemcached.MemcachedClient;
import net.rubyeye.xmemcached.MemcachedClientBuilder;
import net.rubyeye.xmemcached.XMemcachedClientBuilder;
import net.rubyeye.xmemcached.impl.KetamaMemcachedSessionLocator;
import net.rubyeye.xmemcached.utils.AddrUtil;
public class MemCachedTools {
private static final MemCachedTools instance = new MemCachedTools();
/**
* instance
*
* @return
*/
public static MemCachedTools getInstance() {
return instance;
}
private static String memcached_address = ConfigUtil.getInstance()
.getString("memcached_address");
private static String memcached_head=ConfigUtil.getInstance()
.getString("memcached_head");
/**
* 值添加1
* @param key
* @return
*/
public long increaseValue(String key){
long addResult=0;
String memKey=memcached_head+":"+Md5Hex.getDigestMD5(key);
try {
MemcachedClientBuilder builder = new XMemcachedClientBuilder(
AddrUtil.getAddresses(memcached_address));
builder.setSessionLocator(new KetamaMemcachedSessionLocator());
MemcachedClient memcachedClient = builder.build();
Counter counter=memcachedClient.getCounter(memKey);
addResult=counter.incrementAndGet();
try {
// close memcached client
memcachedClient.shutdown();
} catch (IOException e) {
System.err.println("Shutdown MemcachedClient fail");
e.printStackTrace();
}
} catch (Exception ex) {
ex.printStackTrace();
// return ERROR;
}
System.out.println("================"+addResult);
return addResult;
}
/**
* 初始化计数器
* @param key
* @param defaultValue
*/
public void initCounter(String key,long defaultValue){
String memKey=memcached_head+":"+Md5Hex.getDigestMD5(key);
try {
MemcachedClientBuilder builder = new XMemcachedClientBuilder(
AddrUtil.getAddresses(memcached_address));
builder.setSessionLocator(new KetamaMemcachedSessionLocator());
MemcachedClient memcachedClient = builder.build();
Counter counter=memcachedClient.getCounter(memKey,defaultValue);
counter.set(defaultValue);
try {
// close memcached client
memcachedClient.shutdown();
} catch (IOException e) {
System.err.println("Shutdown MemcachedClient fail");
e.printStackTrace();
}
} catch (Exception ex) {
ex.printStackTrace();
// return ERROR;
}
}
/**
* 获取计数器的值
* @param key
* @return
*/
public long getCounterValue(String key){
String memKey=memcached_head+":"+Md5Hex.getDigestMD5(key);
long ret=0;
try {
MemcachedClientBuilder builder = new XMemcachedClientBuilder(
AddrUtil.getAddresses(memcached_address));
builder.setSessionLocator(new KetamaMemcachedSessionLocator());
MemcachedClient memcachedClient = builder.build();
Counter counter=memcachedClient.getCounter(memKey);
ret= counter.get();
try {
// close memcached client
memcachedClient.shutdown();
} catch (IOException e) {
System.err.println("Shutdown MemcachedClient fail");
e.printStackTrace();
}
} catch (Exception ex) {
ex.printStackTrace();
// return ERROR;
}
return ret;
}
}
操作计数器实现类
package com.liu.counter;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import com.liu.memcache.tools.MemCachedTools;
/**
* @author chao.liu
* @date 2015-03-06
*
*/
public class CounterService {
protected Log log = LogFactory.getLog(getClass());
public long getStatisticsData() {
String memKey = "count";
Long count = null;
try {
count = (Long) MemCachedTools.getInstance().getCounterValue(memKey);
} catch (Exception e) {
}
if (count == 0) {
try {
// TODO:从数据库载入,此处省略
count = 120L;
} catch (Exception e) {
}
MemCachedTools.getInstance().initCounter(memKey, count);
} else {
// TODO:输出到前台的处理
log.info("StatisticsService.getStatisticsData get data to memcached ...............");
}
return count;
}
/**
* 更新统计数据
*
* @param channelID
* @param moduleID
* @return
*/
public String updateStatisticsData() {
String memKey = "count";
String res = "1";
Long count = null;
try {
count = (Long) MemCachedTools.getInstance().getCounterValue(memKey);
} catch (Exception e) {
}
if (count == 0) {// 空的时候从数据库载入
// TODO:从数据库载入,此处省略
count = 120L;
MemCachedTools.getInstance().initCounter(memKey, count);
}
long addRes = MemCachedTools.getInstance().increaseValue(memKey);
try {
if (addRes != 0) {
if (addRes % 100 == 0) {
// 每100条更新到数据库一次
// update to DB operation
}
}
} catch (Exception e) {
res = "0";
}
return res;
}
public static void main(String[] args) {
CounterService ss=new CounterService();
System.out.println("当前计数条数是:"+ss.getStatisticsData());
ss.updateStatisticsData();
System.out.println("加1后计数条数是:"+ss.getStatisticsData());
}
}
执行效果:
当前计数条数是:123
================124
加1后计数条数是:124
版权声明:本文博主原创文章。博客,未经同意不得转载。
memcache实现公共计数器网站的更多相关文章
- 最全免费CDN公共库——网站提速
开源静态文件 CDN 我们的目标是提供这样一个仓库,让它尽可能全面收录优秀的开源库,并免费为之提供 CDN 加速服务,使之有更好的访问速度和稳定的环境.同时,我们也提供开源库源接入的入口,让所有人都可 ...
- 免费CDN公共库——网站提速 静态资源库
原文链接:https://blog.geekzhao.me/cdnjs.html 新浪SAE公共资源 推荐指数★★★ 支持https http://lib.sinaapp.com/js/jquery/ ...
- memcache的windows下的安装和简单使用
原文:memcache的windows下的安装和简单使用 memcache是为了解决网站访问量大,数据库压力倍增的解决方案之一,由于其简单实用,很多站点现在都在使用memcache,但是memcach ...
- RDBMS,memcache
1.RDBMS即关系数据库管理系统(Relational Database Management System),是将数据组织为相关的行和列的系统,而管理关系数据库的计算机软件就是关系数据库管理系统, ...
- memcache缓存雪崩、缓存无底洞、缓存穿透、永久数据被踢现象
一.缓存雪崩现象 缓存雪崩一般是由某个缓存节点失效,导致其他节点的缓存命中率下降, 缓存中缺失的数据去数据库查询,短时间内造成数据库服务器崩溃, 重启DB短期又被压跨,但新数据的缓存也更新一些,DB反 ...
- hihocoder1069 最近公共祖先·三(tarjin算法)(并查集)
#1069 : 最近公共祖先·三 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 上上回说到,小Hi和小Ho使用了Tarjan算法来优化了他们的“最近公共祖先”网站,但是 ...
- 最近公共祖先-三(RMQ-ST)
描述 上上回说到,小Hi和小Ho使用了Tarjan算法来优化了他们的"最近公共祖先"网站,但是很快这样一个离线算法就出现了问题:如果只有一个人提出了询问,那么小Hi和小Ho很难决定 ...
- Jmeter系列(34)- 详解 Counter 计数器
如果你想从头学习Jmeter,可以看看这个系列的文章哦 https://www.cnblogs.com/poloyy/category/1746599.html 简单介绍 计数器的作用:循环递增生成数 ...
- 最常见的 20 个 jQuery 面试问题及答案
jQuery 面试问题和答案 JavaScript 是客户端脚本的标准语言,而 jQuery 使得编写 JavaScript 更加简单.你可以只用写几行的jQuery 代码就能实现更多的东西. 它是最 ...
随机推荐
- C# WinFrom 编写正则表达式验证类
public class ValidationRegex { /// <summary> /// 正则表达式字符串 /// </summary> public static s ...
- php学习代码杂记
16/2/22 字符串连接 (1)连接运算符(“.”):它返回将右参数附加到左参数后面所得的字符串. (2)连接赋值运算符(“.=”):它将右边参数附加到左边的参数后. 相当于JS里面的 += . $ ...
- php 之 查询 投票练习(0508)
练习题目: 解题: 方法一: 1. 投票主页面: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" ...
- JS判断是否为一个数组
function isArray(object){ return object && typeof object==='object' && Array == obje ...
- Apache虚拟站点配置
简单虚拟站点配置: <VirtualHost 127.0.0.2:80> DocumentRoot E:/wamp/www/yue ServerName 127.0.0.2:80</ ...
- Windows环境下安装PHPUnit
Windows环境下安装PHPUnit,在此整理一下,以便大家参考. 本人测试安装环境:Windows7(win32) + Apache(2.2.13) + PHP(5.3.6) 1. 以管理员 ...
- 单例模式在Unity中的应用
起因:每个游戏场景中都会有许多的游戏对象,而各个游戏场景之间也是同等的关系.如何去管理它们,是我们要解决的问题. 场景中各脚本间的直接访问,会在各脚本间形成一个巨大而又混乱的网络,这给以后代码的维护带 ...
- BZOJ 1503 郁闷的出纳员
Description OIER公司是一家大型专业化软件公司,有着数以万计的员工.作为一名出纳员,我的任务之一便是统计每位员工的工资.这本来是一份不错的工作,但是令人郁闷的是,我们的老板反复无常,经常 ...
- Iphone6 LightBlue测试BT4GMD-Q25P透传模块
安装LightBlue后,连接透传模块之后,显示如下: 注意:0xFF01是写通道,0xFF02是读通道 BLE透传模块与PL2303相连,在PC端用串口调试助手显示数据. 一.lightblue向B ...
- 禁用窗体关闭按钮(使用GetWindowLong修改GWL_STYLE)
一般我们不想让窗体能够关闭, 首先想到的是在OnCloseQuery事件里设置CanClose := False, 不过在某些情况下这个会和程序关闭窗体的业务逻辑产生冲突 所以写了下面这个函数, 可以 ...