Memcache的使用(c#)

来源:互联网 发布:快递员扫码发短信软件 编辑:程序博客网 时间:2024/06/08 00:14

一、服务端安装

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();        }    }}

测试时分别用telnet链接2台安装了memcache的机器,然后用测试程序多add/set几个值,观察缓存存放的位置


踩坑如下:

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// infinityif (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 infiniteif (expiresAt == DateTime.MaxValue) return 0;uint retval = (uint)(expiresAt.ToUniversalTime() - UnixEpoch).TotalSeconds;return retval;}#endregion

GetExpiration(DateTimeexpiresAt)这个重载方法代码有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;        }






原创粉丝点击