在反问题的过程中遇到的最近项目。网上查了很多资料并没有完全实现。

因此,要找到适合自己的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

代码下载:

http://download.csdn.net/detail/shanhuhau/8508929

版权声明:本文博主原创文章。博客,未经同意不得转载。

memcache实现公共计数器网站的更多相关文章

  1. 最全免费CDN公共库——网站提速

    开源静态文件 CDN 我们的目标是提供这样一个仓库,让它尽可能全面收录优秀的开源库,并免费为之提供 CDN 加速服务,使之有更好的访问速度和稳定的环境.同时,我们也提供开源库源接入的入口,让所有人都可 ...

  2. 免费CDN公共库——网站提速 静态资源库

    原文链接:https://blog.geekzhao.me/cdnjs.html 新浪SAE公共资源 推荐指数★★★ 支持https http://lib.sinaapp.com/js/jquery/ ...

  3. memcache的windows下的安装和简单使用

    原文:memcache的windows下的安装和简单使用 memcache是为了解决网站访问量大,数据库压力倍增的解决方案之一,由于其简单实用,很多站点现在都在使用memcache,但是memcach ...

  4. RDBMS,memcache

    1.RDBMS即关系数据库管理系统(Relational Database Management System),是将数据组织为相关的行和列的系统,而管理关系数据库的计算机软件就是关系数据库管理系统, ...

  5. memcache缓存雪崩、缓存无底洞、缓存穿透、永久数据被踢现象

    一.缓存雪崩现象 缓存雪崩一般是由某个缓存节点失效,导致其他节点的缓存命中率下降, 缓存中缺失的数据去数据库查询,短时间内造成数据库服务器崩溃, 重启DB短期又被压跨,但新数据的缓存也更新一些,DB反 ...

  6. hihocoder1069 最近公共祖先·三(tarjin算法)(并查集)

    #1069 : 最近公共祖先·三 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 上上回说到,小Hi和小Ho使用了Tarjan算法来优化了他们的“最近公共祖先”网站,但是 ...

  7. 最近公共祖先-三(RMQ-ST)

    描述 上上回说到,小Hi和小Ho使用了Tarjan算法来优化了他们的"最近公共祖先"网站,但是很快这样一个离线算法就出现了问题:如果只有一个人提出了询问,那么小Hi和小Ho很难决定 ...

  8. Jmeter系列(34)- 详解 Counter 计数器

    如果你想从头学习Jmeter,可以看看这个系列的文章哦 https://www.cnblogs.com/poloyy/category/1746599.html 简单介绍 计数器的作用:循环递增生成数 ...

  9. 最常见的 20 个 jQuery 面试问题及答案

    jQuery 面试问题和答案 JavaScript 是客户端脚本的标准语言,而 jQuery 使得编写 JavaScript 更加简单.你可以只用写几行的jQuery 代码就能实现更多的东西. 它是最 ...

随机推荐

  1. C# WinFrom 编写正则表达式验证类

    public class ValidationRegex { /// <summary> /// 正则表达式字符串 /// </summary> public static s ...

  2. php学习代码杂记

    16/2/22 字符串连接 (1)连接运算符(“.”):它返回将右参数附加到左参数后面所得的字符串. (2)连接赋值运算符(“.=”):它将右边参数附加到左边的参数后. 相当于JS里面的 += . $ ...

  3. php 之 查询 投票练习(0508)

    练习题目: 解题: 方法一: 1. 投票主页面: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" ...

  4. JS判断是否为一个数组

    function isArray(object){ return object && typeof object==='object' && Array == obje ...

  5. Apache虚拟站点配置

    简单虚拟站点配置: <VirtualHost 127.0.0.2:80> DocumentRoot E:/wamp/www/yue ServerName 127.0.0.2:80</ ...

  6. Windows环境下安装PHPUnit

    Windows环境下安装PHPUnit,在此整理一下,以便大家参考. 本人测试安装环境:Windows7(win32) + Apache(2.2.13) + PHP(5.3.6) 1.    以管理员 ...

  7. 单例模式在Unity中的应用

    起因:每个游戏场景中都会有许多的游戏对象,而各个游戏场景之间也是同等的关系.如何去管理它们,是我们要解决的问题. 场景中各脚本间的直接访问,会在各脚本间形成一个巨大而又混乱的网络,这给以后代码的维护带 ...

  8. BZOJ 1503 郁闷的出纳员

    Description OIER公司是一家大型专业化软件公司,有着数以万计的员工.作为一名出纳员,我的任务之一便是统计每位员工的工资.这本来是一份不错的工作,但是令人郁闷的是,我们的老板反复无常,经常 ...

  9. Iphone6 LightBlue测试BT4GMD-Q25P透传模块

    安装LightBlue后,连接透传模块之后,显示如下: 注意:0xFF01是写通道,0xFF02是读通道 BLE透传模块与PL2303相连,在PC端用串口调试助手显示数据. 一.lightblue向B ...

  10. 禁用窗体关闭按钮(使用GetWindowLong修改GWL_STYLE)

    一般我们不想让窗体能够关闭, 首先想到的是在OnCloseQuery事件里设置CanClose := False, 不过在某些情况下这个会和程序关闭窗体的业务逻辑产生冲突 所以写了下面这个函数, 可以 ...