一、服务端安装
1.本机windows环境安装
memcached-win64-1.4.29-msys2.0.zip
文件上传到csdn备份下http://download.csdn.net/detail/shujudeliu/9921782
cmd进入memcache文件目录
安装:memcached.exe -d install
启动:memcached.exe -d start
停止:memcached.exe -d stop
卸载:memcached.exe -d uninstall
ps,因为win环境的memcache是以服务形式安装的,因此测试卸载时候需先执行停止然后才能卸载
2.虚拟机Linux-Centos 6环境下(本例IP:192.168.200.133)
安装:yum -y install memcached
启动:service memcached start
测试telnet连接不上时注意防火墙是否关闭(或开启允许11211端口访问)
二、客户端调用
1.nuget添加EnyimMemcached的引用,本文使用EnyimMemcached 2.16.0
2.web.config配置
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<sectionGroup name="enyim.com">
<section name="memcached" type="Enyim.Caching.Configuration.MemcachedClientSection, Enyim.Caching" />
</sectionGroup>
</configSections>
<enyim.com>
<memcached protocol="Text">
<servers>
<add address="127.0.0.1" port="11211" />
<add address="192.168.200.133" port="11211" />
</servers>
<socketPool minPoolSize="10" maxPoolSize="20" connectionTimeout="00:00:10" deadTimeout="00:02:00" />
</memcached>
</enyim.com>
</configuration>
3.Memcache操作类
public class MemCachedHelper
{
private static readonly MemcachedClient _uniqueInstance = new MemcachedClient();
/// <summary>
/// 添加缓存
/// </summary>
/// <param name="key">缓存key</param>
/// <param name="obj">缓存value</param>
/// <param name="timeout">超时时间</param>
public static bool Add(string key, object value, TimeSpan timeout)
{
return _uniqueInstance.Store(StoreMode.Add, key, value, timeout);
}
/// <summary>
/// 设置缓存
/// </summary>
/// <param name="key">缓存key</param>
/// <param name="obj">缓存value</param>
/// <param name="timeout">过期时间</param>
public static bool Set(string key, object value, TimeSpan timeout)
{
return _uniqueInstance.Store(StoreMode.Set, key, value, timeout);
}
/// <summary>
/// 获取缓存
/// </summary>
/// <param name="key">缓存key</param>
public static T Get<T>(string key)
{
return _uniqueInstance.Get<T>(key); ;
}
/// <summary>
/// 获取缓存
/// </summary>
/// <param name="key">缓存key</param>
public static object Get(string key)
{
return _uniqueInstance.Get(key); ;
}
/// <summary>
/// 删除缓存
/// </summary>
/// <param name="key">缓存key</param>
public static bool Remove(string key)
{
return _uniqueInstance.Remove(key);
}
}
调用代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
MemCachedHelper.Add("test", "1111", new TimeSpan(0, 0, 300));
var test = MemCachedHelper.Get("test");
Console.ReadKey();
}
}
}
踩坑如下:
Store(StoreMode mode, string key, object value, DateTime expiresAt)
调用该重载方法时返回结果一直为true,实际却get不到值,查看了源码以后找到了问题如下:
public bool Store(StoreMode mode, string key, object value, DateTime expiresAt)
{
int num2;
ulong cas = 0L;
return this.PerformStore(mode, key, value, GetExpiration(expiresAt), ref cas, out num2).Success;
}
public bool Store(StoreMode mode, string key, object value, TimeSpan validFor)
{
int num2;
ulong cas = 0L;
return this.PerformStore(mode, key, value, GetExpiration(validFor), ref cas, out num2).Success;
}
#region [ Expiration helper ]
protected const int MaxSeconds = 60 * 60 * 24 * 30;
protected static readonly DateTime UnixEpoch = new DateTime(1970, 1, 1);
protected static uint GetExpiration(TimeSpan validFor)
{
// convert timespans to absolute dates
// infinity
if (validFor == TimeSpan.Zero || validFor == TimeSpan.MaxValue) return 0;
uint seconds = (uint)validFor.TotalSeconds;
if (seconds > MaxSeconds)
return GetExpiration(DateTime.Now.Add(validFor));
return seconds;
}
protected static uint GetExpiration(DateTime expiresAt)
{
if (expiresAt < UnixEpoch) throw new ArgumentOutOfRangeException("expiresAt", "expiresAt must be >= 1970/1/1");
// accept MaxValue as infinite
if (expiresAt == DateTime.MaxValue) return 0;
uint retval = (uint)(expiresAt.ToUniversalTime() - UnixEpoch).TotalSeconds;
return retval;
}
#endregion
GetExpiration(DateTime expiresAt)这个重载方法代码有bug,设置的过期时间是与1970/1/1的毫秒差值,
过期时间值过大导致无效,memcache的缓存有效期最大为30天
在github上也找到了相关问题描述:https://github.com/enyim/EnyimMemcached/pull/172/commits/94021c56c2bf335977c0e63392ced655a0912a47
修改后的方法如下:
protected static uint GetExpiration(DateTime expiresAt)
{
if (expiresAt < UnixEpoch) throw new ArgumentOutOfRangeException("expiresAt", "expiresAt must be >= 1970/1/1");
// accept MaxValue as infinite
if (expiresAt == DateTime.MaxValue) return 0;
//uint retval = (uint)(expiresAt.ToUniversalTime() - UnixEpoch).TotalSeconds;//bug代码
uint retval = (uint)(expiresAt.ToUniversalTime() - DateTime.Now.ToUniversalTime()).TotalSeconds;
return retval;
}