zoukankan      html  css  js  c++  java
  • memcached+net缓存

    最近对线上项目进行了一次缓存方面的优化,本来6月就该写的,但是项目一直忙,就给自己理由偷懒了

    缓存方面的思考参考代震军的文章比较多,文章地址:

    http://www.cnblogs.com/daizhj/archive/2009/11/17/1604436.html

    http://www.cnblogs.com/daizhj/archive/2009/03/23/1386652.html

    我以前项目上一直都是,直接使用memcached或者直接使用net本地缓存,二者都是单独使用

    这次对项目调整修改了下结构。主要目的是结合二者优势更有效使用缓存,二来也是为了解决网站更新代码缓解数据库查询压力的问题。

    先大致说下它们的优点缺点:

    1.memcached 优点是,稳定,受外因素影响较小,安全性高。缺点是速度方面不如net缓存,序列化和传输产生的额外开销比较大

    2.net缓存,优点是高效,速度极快。缺点是稳定性,安全性差,受应用程序池回收设置影响。

    针对以上优缺点,决定使用二级缓存模式:客户端-》NET本地缓存-》memcached缓存-》数据库  (NET本地缓存默认5分钟失效,memcached缓存时间设置,一般30分钟以上,个人觉得最后把memcached缓

    存当成个永久缓存来设置,缺点就是缓存更新方面的策略需要考虑周全)

    这样,当客户端访问本地缓存:
    有数据->直接返回
    无数据->读取下级缓存(“memcached缓存”)->有数据->返回,同步写份net缓存(无数据则数据库查询,并建立memcached缓存)

    -------------------------------------------------------------------------------------------

    以上设计经过实际应用,服务器内网和memcached之间的通讯量大大减少,CPU占用资源方面也相对保持稳定状态,不如同之前浮动从10%-30%(现在是10%-15%)。该项目网站日PV大概在250W+

    网站缓存方面算是有了个初步的完成,以上还有个很大的优点就是在站点重启的时候,尤其是高并发访问的情况下,net缓存一失效,就可直接通过memcached,而不会直接造成高并发查询数据库,导致

    数据库压力上升,如果有一句sql语句查询稍慢,就有可能导致查询死锁的状况出现。哈,这个可是很实际的优点。现在的代码部署了,在网站有用户访问的情况下更新代码不再是问题了

     ----------------------------------------------------------------

    上面说了这么多,引入正题,C#网站应用程序中,使用memcached,在windos服务重启会有个情况,网站和memcached之间的socks连接失败,需要网站也同步重启下,服务才能重新连接。那么我刚上面说

    的高并发查询情况导致数据库堵了的情况又会出现,而且是net本地缓存,和memcached缓存都丢失了,二者加起来至少3个G的数据
    需要解决上面的问题,重新启动网站,而重新启动网站无非也就重新建立了下同memcahced之间的socks连接池,所以解决这问题的关键点是重新构建网站和memcached之间的socks连接池.本着这样的思路

    ,我这对Memcached.ClientLibrary 进行了扩展
    1.
    首先扩展定义了接口 ICacheManageConfig.cs

    里面定义里个必须实现的方法 void Memcached_Restart(string LogMessage);  用来重建连接池

    2.在调用memcached客户端组件的数据层,增加了接口实现类CacheManageConfig.cs

    代码
       public class CacheManageConfig : Memcached.ClientLibrary.ICacheManageConfig
        {
            
    private static Memcached.ClientLibrary.SockIOPool pool = null;
            
            
    /// <summary>
            
    /// 实现接口方法,memcached客户端组件反射调用接口的实现方法
            
    /// </summary>
            
    /// <param name="message"></param>
            public void Memcached_Restart(string message)
            {
                _Restart(message);
            } 

            
    /// <summary>
            
    /// 初始化连接池
            
    /// </summary>
            public static void Memcached_Init()
            {
                Memcached.ClientLibrary.MemcachedSocksMonitor.CacheManageConfigPath 
    = "KM.Brand.DBLib.Cache.CacheManageConfig";
                
    //每次初始化都用新的连接池名
                Memcached.ClientLibrary.MemcachedSocksMonitor.CachePoolName = "pool" + Guid.NewGuid().ToString();
               
    string memcachedserver = System.Configuration.ConfigurationManager.AppSettings["memcachedserver"];
                
    string[] serverlist = {memcachedserver};
                pool 
    = Memcached.ClientLibrary.SockIOPool.GetInstance(Memcached.ClientLibrary.MemcachedSocksMonitor.CachePoolName);
                pool.SetServers(serverlist);
                pool.InitConnections 
    = 15;
                pool.MinConnections 
    = 15;
                pool.MaxConnections 
    = 200;
                pool.SocketTimeout 
    = 3000;
                pool.SocketConnectTimeout 
    = 1000;
                pool.MaintenanceSleep 
    = 30;
                pool.Failover 
    = true;
                pool.Nagle 
    = false;
                
    //socket单次任务的最大时间,超过这个时间socket会被强行中断掉(当前任务失败)
                pool.MaxBusy = 1000 * 10;
                pool.Initialize();
                
    //由于有旧代码使用默认的程序池名字,所以同时初始化一个默认名字的连接池
                 pool = Memcached.ClientLibrary.SockIOPool.GetInstance();
                pool.SetServers(serverlist);
                pool.InitConnections 
    =10;
                pool.MinConnections 
    = 10;
                pool.MaxConnections 
    = 50;
                pool.SocketTimeout 
    = 3000;
                pool.SocketConnectTimeout 
    = 1000;
                pool.MaintenanceSleep 
    = 30;
                pool.Failover 
    = true;
                pool.Nagle 
    = false;
                
    //socket单次任务的最大时间,超过这个时间socket会被强行中断掉(当前任务失败)
                 pool.MaxBusy = 1000 * 10;
                pool.Initialize();
             }

            
    #region  连接池重建
            
    /// <summary>
            
    /// 连接池重建
            
    /// </summary>
            
    /// <param name="message"></param>
            private static void _Restart(string message)
            {
                
    if (pool != null)
                {
    //其实可以把缓存管理模块整合到这个项目一起的。哎!               
                    pool.Shutdown(Memcached.ClientLibrary.MemcachedSocksMonitor.CachePoolName);
                }
                
    //重新初始化
                  Memcached_Init();
                KM.Brand.DBLib.Cache.CacheManage.Dispose(message);
            }
            
    #endregion
        }

    3.在网站应用global.asax中配置连接池启动

     protected void Application_Start(object sender, EventArgs e)
     {
               
    //初始化memcached连接池
                KM.Brand.DBLib.Cache.CacheManageConfig.Memcached_Init();
    }

    4。最关键点,修改memcached客户端源代码实现,回收连接池

    主要有新建立了个类,MemcachedSocksMonitor.cs 实现连接池基本操作

    代码
     public static class MemcachedSocksMonitor
        { 
            
    private static string _CacheManageConfigPath;
            
    private static int _SocksMaxErrCount;
            
    private static string _CachePoolName;
            
    /// <summary>
            
    /// 连接池名字
            
    /// </summary>
            public static string CachePoolName
            {
                
    get { return _CachePoolName; }
                
    set { _CachePoolName = value;}
            }

            
    ///<summary>
            
    ///初始化一定要设置
            
    ///实现接口ICacheManageConfig的类完整命名空间路径(包含类名),重新建立缓存管理模块单件实例的方法实现名称
            
    /// </summary>
            public static string CacheManageConfigPath
            {
                
    get { return _CacheManageConfigPath; }
                
    set { _CacheManageConfigPath = value; }
            }

            
    /// <summary>
            
    /// 执行重建的条件,该数字累加到20就重建连接池,并清零,次数累计保留1分钟
            
    /// </summary>
            public static int SocksMaxErrCount
            {
                
    get { return _SocksMaxErrCount; }
                
    set { _SocksMaxErrCount = value; }
            } 

            
    /// <summary>
            
    /// 重建连接池
            
    /// </summary>
            public  static void Restart()
            {
    //识别需要重启,看日志错误 log.Error(GetLocalizedString("set IOException"), exception5);
                ICacheManageConfig CacheDispose = (ICacheManageConfig)Assembly.Load(CacheManageConfigPath).CreateInstance("Memcached_Restart"); //(ICacheManageConfig)Create(DisposeMonthodName);
                CacheDispose.Memcached_Restart("memcached服务连接池传输数据失败,重新生成了连接池!\r\n 无法将数据写入传输连接: 远程主机强迫关闭了一个现有的连接!!一分钟内连续出错次数" + SocksMaxErrCount);
            }

            
    /// <summary>
            
    /// 记录传输错误的失败次数,并决定是否要重建连接池
            
    /// 这里用了本地缓存,一般情况下这缓存都是不存在的,该方法也很少会执行到
            
    /// </summary>
            public static void SockIOErrRestatr()
            {
                
    //执行一次就进行一次逻辑处理
                string key = "MemcachedClientLibrarySockIOErrRestatr";
                
    object value = System.Web.HttpRuntime.Cache.Get(key);
                
    if (value != null)
                {
                    
    if (SocksMaxErrCount > 20)
                    {
                        
    //执行重建memcached连接池
                        Restart();
                        SocksMaxErrCount 
    = 0;
                    }
                    
    else
                    {
                        SocksMaxErrCount 
    = SocksMaxErrCount + 1;
                    }
                }
                
    else
                {
                    SocksMaxErrCount 
    = 1;
                    System.Web.HttpRuntime.Cache.Add(key,
    1null,DateTime.Now.AddMinutes(1), System.Web.Caching.Cache.NoSlidingExpiration, System.Web.Caching.CacheItemPriority.High, null);
                } 
            } 
        }

    5.SockIOPool.cs 修改Shutdown 函授,也忘记有没其他地方修改了


     

    代码
       [MethodImpl(MethodImplOptions.Synchronized)]
            
    public void Shutdown(string poolName)
            {
                
    bool isDebugEnabled = Log.IsDebugEnabled;
                
    if ((this._maintenanceThread != null&& this._maintenanceThread.IsRunning)
                {
                    
    this.StopMaintenanceThread();
                } 
                
    bool flag2 = Log.IsDebugEnabled;
                ClosePool(
    this._availPool);
                ClosePool(
    this._busyPool);
                
    this._availPool = null;
                
    this._busyPool = null;
                
    this._buckets = null;
                
    this._hostDeadDuration = null;
                
    this._hostDead = null;
                
    this._initialized = false;
                
    bool flag3 = Log.IsDebugEnabled;
                
    //下面方法是增加的,当memcached重启后,导致当前连接池连接不上,执行停止命令后
                
    //移除失败的连接池,这样重新初始化就会重新建立sock连接池
                if (poolName == "")
                {
                    poolName 
    = GetLocalizedString("default instance");
                }
                Pools.Remove(GetLocalizedString(poolName));
            }

     6 MemcachedClient.cs修改,具体忘记改了哪些,全部复制上来好了

    代码
    namespace Memcached.ClientLibrary
    {
        
    using ICSharpCode.SharpZipLib.GZip;
        
    using log4net;
        
    using System;
        
    using System.Collections;
        
    using System.Globalization;
        
    using System.IO;
        
    using System.Resources;
        
    using System.Runtime.Serialization;
        
    using System.Runtime.Serialization.Formatters.Binary;
        
    using System.Text;
        
    using System.Text.RegularExpressions;

        
    public class MemcachedClient
        {
            
    private bool _compressEnable;
            
    private long _compressThreshold;
            
    private string _defaultEncoding;
            
    private string _poolName;
            
    private bool _primitiveAsString;//Memcached.ClientLibrary.StringMessages
            private static ResourceManager _resourceManager = new ResourceManager("Memcached.ClientLibrary.StringMessages"typeof(MemcachedClient).Assembly);
            
    private const string CLIENT_ERROR = "CLIENT_ERROR";
            
    private const int COMPRESS_THRESH = 0x7800;
            
    private const string DELETED = "DELETED";
            
    private const string END = "END";
            
    private const string ERROR = "ERROR";
            
    private const int F_COMPRESSED = 2;
            
    private const int F_SERIALIZED = 8;
            
    private static ILog log = LogManager.GetLogger(typeof(MemcachedClient));
            
    private const string NOTFOUND = "NOT_FOUND";
            
    private const string NOTSTORED = "NOT_STORED";
            
    private const string OK = "OK";
            
    private const string SERVER_ERROR = "SERVER_ERROR";
            
    private const string STATS = "STAT";
            
    private const string STORED = "STORED";
            
    private const string VALUE = "VALUE";

            
    public MemcachedClient(): this("default instance")
            {
              
            } 
            
    public MemcachedClient(string name)
            {
                
    if (name != "")
                {
                    
    this.Init(name);
                }
                
    else
                {
                    
    this.Init();
                }
            }
            
    private void Init(string key)
            {
                
    this._primitiveAsString = false;
                
    this._compressEnable = true;
                
    this._compressThreshold = 0x7800L;
                
    this._defaultEncoding = "UTF-8";
                
    this._poolName = GetLocalizedString(key);
            }
            
    public bool Add(string key, object value)
            {
                
    return this.Set("add", key, value, DateTime.MaxValue, nullthis._primitiveAsString);
            }

            
    public bool Add(string key, object value, DateTime expiry)
            {
                
    return this.Set("add", key, value, expiry, nullthis._primitiveAsString);
            }

            
    public bool Add(string key, object value, int hashCode)
            {
                
    return this.Set("add", key, value, DateTime.MaxValue, hashCode, this._primitiveAsString);
            }

            
    public bool Add(string key, object value, DateTime expiry, int hashCode)
            {
                
    return this.Set("add", key, value, expiry, hashCode, this._primitiveAsString);
            }

            
    public long Decrement(string key)
            {
                
    return this.IncrementOrDecrement("decr", key, 1Lnull);
            }

            
    public long Decrement(string key, long inc)
            {
                
    return this.IncrementOrDecrement("decr", key, inc, null);
            }

            
    public long Decrement(string key, long inc, int hashCode)
            {
                
    return this.IncrementOrDecrement("decr", key, inc, hashCode);
            }

            
    public bool Delete(string key)
            {
                
    return this.Delete(key, null, DateTime.MaxValue);
            }

            
    public bool Delete(string key, DateTime expiry)
            {
                
    return this.Delete(key, null, expiry);
            }

            
    public bool Delete(string key, object hashCode, DateTime expiry)
            {
                
    if (key == null)
                {
                    
    if (log.IsErrorEnabled)
                    {
                        log.Error(GetLocalizedString(
    "null key delete"));
                    }
                    
    return false;
                }
                SockIO sock 
    = SockIOPool.GetInstance(this._poolName).GetSock(key, hashCode);
                
    if (sock != null)
                {
                    StringBuilder builder 
    = new StringBuilder("delete ").Append(key);
                    
    if (expiry != DateTime.MaxValue)
                    {
                        builder.Append(
    " " + (GetExpirationTime(expiry) / 0x3e8));
                    }
                    builder.Append(
    "\r\n");
                    
    try
                    {
                        sock.Write(Encoding.UTF8.GetBytes(builder.ToString()));
                        sock.Flush();
                        
    string newValue = sock.ReadLine();
                        
    if ("DELETED" == newValue)
                        {
                            
    bool isInfoEnabled = log.IsInfoEnabled;
                            sock.Close();
                            sock 
    = null;
                            
    return true;
                        }
                        
    if ("NOT_FOUND" == newValue)
                        {
                            
    if (!log.IsInfoEnabled)
                            {
                            }
                        }
                        
    else if (log.IsErrorEnabled)
                        {
                            log.Error(GetLocalizedString(
    "delete key error").Replace("$$Key$$", key).Replace("$$Line$$", newValue));
                        }
                    }
                    
    catch (IOException exception)
                    {
                        
    if (log.IsErrorEnabled)
                        {
                            log.Error(GetLocalizedString(
    "delete IOException"), exception);
                        }
                        
    try
                        {
                            sock.TrueClose();
                        }
                        
    catch (IOException exception2)
                        {
                            
    if (log.IsErrorEnabled)
                            {
                                log.Error(GetLocalizedString(
    "failed to close some socket").Replace("$$Socket$$", sock.ToString()), exception2);
                            }
                        }
                        sock 
    = null;
                    }
                    
    if (sock != null)
                    {
                        sock.Close();
                    }
                }
                
    return false;
            }

            
    public bool FlushAll()
            {
                
    return this.FlushAll(null);
            }

            
    public bool FlushAll(ArrayList servers)
            {
                SockIOPool instance 
    = SockIOPool.GetInstance(this._poolName);
                
    if (instance == null)
                {
                    
    if (log.IsErrorEnabled)
                    {
                        log.Error(GetLocalizedString(
    "unable to get socket pool"));
                    }
                    
    return false;
                }
                
    if (servers == null)
                {
                    servers 
    = instance.Servers;
                }
                
    if ((servers == null|| (servers.Count <= 0))
                {
                    
    if (log.IsErrorEnabled)
                    {
                        log.Error(GetLocalizedString(
    "flushall no servers"));
                    }
                    
    return false;
                }
                
    bool flag = true;
                
    for (int i = 0; i < servers.Count; i++)
                {
                    SockIO connection 
    = instance.GetConnection((string) servers[i]);
                    
    if (connection == null)
                    {
                        
    if (log.IsErrorEnabled)
                        {
                            log.Error(GetLocalizedString(
    "unable to connect").Replace("$$Server$$", servers[i].ToString()));
                        }
                        flag 
    = false;
                    }
                    
    else
                    {
                        
    string s = "flush_all\r\n";
                        
    try
                        {
                            connection.Write(Encoding.UTF8.GetBytes(s));
                            connection.Flush();
                            
    string str2 = connection.ReadLine();
                            flag 
    = ("OK" == str2) ? flag : false;
                        }
                        
    catch (IOException exception)
                        {
                            
    if (log.IsErrorEnabled)
                            {
                                log.Error(GetLocalizedString(
    "flushall IOException"), exception);
                            }
                            
    try
                            {
                                connection.TrueClose();
                            }
                            
    catch (IOException exception2)
                            {
                                
    if (log.IsErrorEnabled)
                                {
                                    log.Error(GetLocalizedString(
    "failed to close some socket").Replace("$$Socket$$", connection.ToString()), exception2);
                                }
                            }
                            flag 
    = false;
                            connection 
    = null;
                        }
                        
    if (connection != null)
                        {
                            connection.Close();
                        }
                    }
                }
                
    return flag;
            }

            
    public object Get(string key)
            {
                
    return this.Get(key, nullfalse);
            }

            
    public object Get(string key, int hashCode)
            {
                
    return this.Get(key, hashCode, false);
            }

            
    public object Get(string key, object hashCode, bool asString)
            {
                SockIO sock 
    = SockIOPool.GetInstance(this._poolName).GetSock(key, hashCode);
                
    if (sock != null)
                {
                    
    try
                    {
                        
    string s = "get " + key + "\r\n";
                        
    bool isDebugEnabled = log.IsDebugEnabled;
                        sock.Write(Encoding.UTF8.GetBytes(s));
                        sock.Flush();
                        Hashtable hm 
    = new Hashtable();
                        
    this.LoadItems(sock, hm, asString);
                        
    bool flag2 = log.IsDebugEnabled;
                        sock.Close();
                        
    return hm[key];
                    }
                    
    catch (IOException exception)
                    { 
                        
    //##监测##
                        
    //exception.Message=无法将数据写入传输连接: 远程主机强迫关闭了一个现有的连接。。
                        
    //原因:memcached重启类造成的连接池无法再通信的错误
                        
    //解决:判断上面的message出现次数几次,就考虑重新建立连接池
                        if (exception.Message.Contains("无法将数据写入传输连接: 远程主机强迫关闭了一个现有的连接"))
                        {
                           MemcachedSocksMonitor.SockIOErrRestatr();
                        }
                        
    if (log.IsErrorEnabled)
                        {
                            log.Error(GetLocalizedString(
    "get IOException").Replace("$$Key$$", key), exception);
                        }
                        
    try
                        {
                            sock.TrueClose();
                        }
                        
    catch (IOException exception2)
                        {
                            
    if (log.IsErrorEnabled)
                            {
                                log.Error(GetLocalizedString(
    "failed to close some socket").Replace("$$Socket$$", sock.ToString()), exception2);
                            }
                        }
                        sock 
    = null;
                    }
                    
    if (sock != null)
                    {
                        sock.Close();
                    }
                }
                
    return null;
            }

            
    public long GetCounter(string key)
            {
                
    return this.GetCounter(key, null);
            }

            
    public long GetCounter(string key, object hashCode)
            {
                
    if (key == null)
                {
                    
    if (log.IsErrorEnabled)
                    {
                        log.Error(GetLocalizedString(
    "getcounter null key"));
                    }
                    
    return -1L;
                }
                
    long num = -1L;
                
    try
                {
                    num 
    = long.Parse((stringthis.Get(key, hashCode, true), new NumberFormatInfo());
                }
                
    catch (ArgumentException)
                {
                    
    if (log.IsErrorEnabled)
                    {
                        log.Error(GetLocalizedString(
    "getcounter counter not found").Replace("$$Key$$", key));
                    }
                }
                
    return num;
            }

            
    private static int GetExpirationTime(DateTime expiration)
            {
                
    if (expiration <= DateTime.Now)
                {
                    
    return 0;
                }
                TimeSpan span 
    = new TimeSpan(0x1d0x170x3b0x3b);
                
    if (expiration.Subtract(DateTime.Now) > span)
                {
                    
    return (int) span.TotalSeconds;
                }
                
    return (int) expiration.Subtract(DateTime.Now).TotalSeconds;
            }

            
    private static string GetLocalizedString(string key)
            {
                
    if (key != "default instance")
                {
                    
    return key;
                }
                
    else
                {
                    
    return _resourceManager.GetString(key);
                }
            }

            
    public Hashtable GetMultiple(string[] keys)
            {
                
    return this.GetMultiple(keys, nullfalse);
            }

            
    public Hashtable GetMultiple(string[] keys, int[] hashCodes)
            {
                
    return this.GetMultiple(keys, hashCodes, false);
            }

            
    public Hashtable GetMultiple(string[] keys, int[] hashCodes, bool asString)
            {
                
    if (keys == null)
                {
                    
    return new Hashtable();
                }
                Hashtable hashtable 
    = new Hashtable();
                
    for (int i = 0; i < keys.Length; i++)
                {
                    
    object hashCode = null;
                    
    if ((hashCodes != null&& (hashCodes.Length > i))
                    {
                        hashCode 
    = hashCodes[i];
                    }
                    SockIO sock 
    = SockIOPool.GetInstance(this._poolName).GetSock(keys[i], hashCode);
                    
    if (sock != null)
                    {
                        
    if (!hashtable.ContainsKey(sock.Host))
                        {
                            hashtable[sock.Host] 
    = new StringBuilder();
                        }
                        ((StringBuilder) hashtable[sock.Host]).Append(
    " " + keys[i]);
                        sock.Close();
                    }
                }
                
    bool isInfoEnabled = log.IsInfoEnabled;
                Hashtable hm 
    = new Hashtable();
                ArrayList list 
    = new ArrayList();
                
    foreach (string str in hashtable.Keys)
                {
                    SockIO connection 
    = SockIOPool.GetInstance(this._poolName).GetConnection(str);
                    
    try
                    {
                        
    string s = "get" + ((StringBuilder) hashtable[str]) + "\r\n";
                        
    bool flag2 = log.IsDebugEnabled;
                        connection.Write(Encoding.UTF8.GetBytes(s));
                        connection.Flush();
                        
    this.LoadItems(connection, hm, asString);
                    }
                    
    catch (IOException exception)
                    {
                        
    if (log.IsErrorEnabled)
                        {
                            log.Error(GetLocalizedString(
    "getmultiple IOException"), exception);
                        }
                        list.Add(str);
                        
    try
                        {
                            connection.TrueClose();
                        }
                        
    catch (IOException exception2)
                        {
                            
    if (log.IsErrorEnabled)
                            {
                                log.Error(GetLocalizedString(
    "failed to close some socket").Replace("$$Socket$$", connection.ToString()), exception2);
                            }
                        }
                        connection 
    = null;
                    }
                    
    if (connection != null)
                    {
                        connection.Close();
                    }
                }
                
    foreach (string str3 in list)
                {
                    hashtable.Remove(str3);
                }
                
    bool isDebugEnabled = log.IsDebugEnabled;
                
    return hm;
            }

            
    public object[] GetMultipleArray(string[] keys)
            {
                
    return this.GetMultipleArray(keys, nullfalse);
            }

            
    public object[] GetMultipleArray(string[] keys, int[] hashCodes)
            {
                
    return this.GetMultipleArray(keys, hashCodes, false);
            }

            
    public object[] GetMultipleArray(string[] keys, int[] hashCodes, bool asString)
            {
                
    if (keys == null)
                {
                    
    return new object[0];
                }
                Hashtable hashtable 
    = this.GetMultiple(keys, hashCodes, asString);
                
    object[] objArray = new object[keys.Length];
                
    for (int i = 0; i < keys.Length; i++)
                {
                    objArray[i] 
    = hashtable[keys[i]];
                }
                
    return objArray;
            }

            
    public long Increment(string key)
            {
                
    return this.IncrementOrDecrement("incr", key, 1Lnull);
            }

            
    public long Increment(string key, long inc)
            {
                
    return this.IncrementOrDecrement("incr", key, inc, null);
            }

            
    public long Increment(string key, long inc, int hashCode)
            {
                
    return this.IncrementOrDecrement("incr", key, inc, hashCode);
            }

            
    private long IncrementOrDecrement(string cmdname, string key, long inc, object hashCode)
            {
                SockIO sock 
    = SockIOPool.GetInstance(this._poolName).GetSock(key, hashCode);
                
    if (sock != null)
                {
                    
    try
                    {
                        
    string s = string.Concat(new object[] { cmdname, " ", key, " ", inc, "\r\n" });
                        
    bool isDebugEnabled = log.IsDebugEnabled;
                        sock.Write(Encoding.UTF8.GetBytes(s));
                        sock.Flush();
                        
    string input = sock.ReadLine();
                        
    if (new Regex(@"\d+").Match(input).Success)
                        {
                            sock.Close();
                            
    return long.Parse(input, new NumberFormatInfo());
                        }
                        
    if ("NOT_FOUND" == input)
                        {
                            
    if (!log.IsInfoEnabled)
                            {
                            }
                        }
                        
    else if (log.IsErrorEnabled)
                        {
                            log.Error(GetLocalizedString(
    "incr-decr key error").Replace("$$Key$$", key));
                        }
                    }
                    
    catch (IOException exception)
                    {
                        
    if (log.IsErrorEnabled)
                        {
                            log.Error(GetLocalizedString(
    "incr-decr IOException"), exception);
                        }
                        
    try
                        {
                            sock.TrueClose();
                        }
                        
    catch (IOException)
                        {
                            
    if (log.IsErrorEnabled)
                            {
                                log.Error(GetLocalizedString(
    "failed to close some socket").Replace("$$Socket$$", sock.ToString()));
                            }
                        }
                        sock 
    = null;
                    }
                    
    if (sock != null)
                    {
                        sock.Close();
                    }
                }
                
    return -1L;
            }

            
    private void Init()
            {
                
    this._primitiveAsString = false;
                
    this._compressEnable = true;
                
    this._compressThreshold = 0x7800L;
                
    this._defaultEncoding = "UTF-8";
                
    this._poolName = GetLocalizedString("default instance");
            }

            
    public bool KeyExists(string key)
            {
                
    return (this.Get(key, nulltrue!= null);
            }

            
    private void LoadItems(SockIO sock, Hashtable hm, bool asString)
            {
                
    string str;
                
    object obj2;
            Label_0000:
                str 
    = sock.ReadLine();
                
    bool isDebugEnabled = log.IsDebugEnabled;
                
    if (!str.StartsWith("VALUE"))
                {
                    
    if ("END" == str)
                    {
                        
    if (log.IsDebugEnabled)
                        {
                        }
                        
    return;
                    }
                    
    goto Label_0000;
                }
                
    string[] strArray = str.Split(new char[] { ' ' });
                
    string newValue = strArray[1];
                
    int num = int.Parse(strArray[2], new NumberFormatInfo());
                
    int num2 = int.Parse(strArray[3], new NumberFormatInfo());
                
    bool flag2 = log.IsDebugEnabled;
                
    byte[] bytes = new byte[num2];
                sock.Read(bytes);
                sock.ClearEndOfLine();
                
    if ((num & 2!= 0)
                {
                    
    try
                    {
                        
    int num3;
                        GZipInputStream stream 
    = new GZipInputStream(new MemoryStream(bytes));
                        MemoryStream stream2 
    = new MemoryStream(bytes.Length);
                        
    byte[] buffer = new byte[0x800];
                        
    while ((num3 = stream.Read(buffer, 0, buffer.Length)) > 0)
                        {
                            stream2.Write(buffer, 
    0, num3);
                        }
                        bytes 
    = stream2.ToArray();
                        stream.Close();
                    }
                    
    catch (IOException exception)
                    {
                        
    if (log.IsErrorEnabled)
                        {
                            log.Error(GetLocalizedString(
    "loaditems uncompression IOException").Replace("$$Key$$", newValue), exception);
                        }
                        
    throw new IOException(GetLocalizedString("loaditems uncompression IOException").Replace("$$Key$$", newValue), exception);
                    }
                }
                
    if ((num & 8== 0)
                {
                    
    if (this._primitiveAsString || asString)
                    {
                        
    bool isInfoEnabled = log.IsInfoEnabled;
                        obj2 
    = Encoding.GetEncoding(this._defaultEncoding).GetString(bytes);
                        
    goto Label_022A;
                    }
                    
    try
                    {
                        obj2 
    = NativeHandler.Decode(bytes);
                        
    goto Label_022A;
                    }
                    
    catch (Exception exception2)
                    {
                        
    if (log.IsErrorEnabled)
                        {
                            log.Error(GetLocalizedString(
    "loaditems deserialize error").Replace("$$Key$$", newValue), exception2);
                        }
                        
    throw new IOException(GetLocalizedString("loaditems deserialize error").Replace("$$Key$$", newValue), exception2);
                    }
                }
                
    try
                {
                    MemoryStream serializationStream 
    = new MemoryStream(bytes);
                    obj2 
    = new BinaryFormatter().Deserialize(serializationStream);
                    
    bool flag4 = log.IsInfoEnabled;
                }
                
    catch (SerializationException exception3)
                {
                    
    if (log.IsErrorEnabled)
                    {
                        log.Error(GetLocalizedString(
    "loaditems SerializationException").Replace("$$Key$$", newValue), exception3);
                    }
                    
    throw new IOException(GetLocalizedString("loaditems SerializationException").Replace("$$Key$$", newValue), exception3);
                }
            Label_022A:
                hm[newValue] 
    = obj2;
                
    goto Label_0000;
            }

            
    public bool Replace(string key, object value)
            {
                
    return this.Set("replace", key, value, DateTime.MaxValue, nullthis._primitiveAsString);
            }

            
    public bool Replace(string key, object value, DateTime expiry)
            {
                
    return this.Set("replace", key, value, expiry, nullthis._primitiveAsString);
            }

            
    public bool Replace(string key, object value, int hashCode)
            {
                
    return this.Set("replace", key, value, DateTime.MaxValue, hashCode, this._primitiveAsString);
            }

            
    public bool Replace(string key, object value, DateTime expiry, int hashCode)
            {
                
    return this.Set("replace", key, value, expiry, hashCode, this._primitiveAsString);
            }

            
    public bool Set(string key, object value)
            {
                
    return this.Set("set", key, value, DateTime.MaxValue, nullthis._primitiveAsString);
            }

            
    public bool Set(string key, object value, DateTime expiry)
            {
                
    return this.Set("set", key, value, expiry, nullthis._primitiveAsString);
            }

            
    public bool Set(string key, object value, int hashCode)
            {
                
    return this.Set("set", key, value, DateTime.MaxValue, hashCode, this._primitiveAsString);
            }

            
    public bool Set(string key, object value, DateTime expiry, int hashCode)
            {
                
    return this.Set("set", key, value, expiry, hashCode, this._primitiveAsString);
            }

            
    private bool Set(string cmdname, string key, object obj, DateTime expiry, object hashCode, bool asString)
            {
                
    byte[] bytes;
                
    if (expiry < DateTime.Now)
                {
                    
    return true;
                }
                
    if (((cmdname == null|| (cmdname.Trim().Length == 0)) || ((key == null|| (key.Length == 0)))
                {
                    
    if (log.IsErrorEnabled)
                    {
                        log.Error(GetLocalizedString(
    "set key null"));
                    }
                    
    return false;
                }
                SockIO sock 
    = SockIOPool.GetInstance(this._poolName).GetSock(key, hashCode);
                
    if (sock == null)
                {
                    
    return false;
                }
                
    if (expiry == DateTime.MaxValue)
                {
                    expiry 
    = new DateTime(0L);
                }
                
    int num = 0;
                
    int count = 0;
                
    if (NativeHandler.IsHandled(obj))
                {
                    
    if (asString)
                    {
                        
    if (obj != null)
                        {
                            
    bool flag1 = log.IsInfoEnabled;
                            
    try
                            {
                                bytes 
    = Encoding.UTF8.GetBytes(obj.ToString());
                                count 
    = bytes.Length;
                                
    goto Label_01DF;
                            }
                            
    catch (ArgumentException exception)
                            {
                                
    if (log.IsErrorEnabled)
                                {
                                    log.Error(GetLocalizedString(
    "set invalid encoding").Replace("$$Encoding$$"this._defaultEncoding), exception);
                                }
                                sock.Close();
                                sock 
    = null;
                                
    return false;
                            }
                        }
                        bytes 
    = new byte[0];
                        count 
    = 0;
                        
    goto Label_01DF;
                    }
                    
    bool isInfoEnabled = log.IsInfoEnabled;
                    
    try
                    {
                        bytes 
    = NativeHandler.Encode(obj);
                        count 
    = bytes.Length;
                        
    goto Label_01DF;
                    }
                    
    catch (ArgumentException exception2)
                    {
                        
    if (log.IsErrorEnabled)
                        {
                            log.Error(GetLocalizedString(
    "set failed to native handle object"), exception2);
                        }
                        sock.Close();
                        sock 
    = null;
                        
    return false;
                    }
                }
                
    if (obj != null)
                {
                    
    bool flag3 = log.IsInfoEnabled;
                    
    try
                    {
                        MemoryStream serializationStream 
    = new MemoryStream();
                        
    new BinaryFormatter().Serialize(serializationStream, obj);
                        bytes 
    = serializationStream.GetBuffer();
                        count 
    = (int) serializationStream.Length;
                        num 
    |= 8;
                        
    goto Label_01DF;
                    }
                    
    catch (IOException exception3)
                    {
                        
    if (log.IsErrorEnabled)
                        {
                            log.Error(GetLocalizedString(
    "set failed to serialize").Replace("$$Object$$", obj.ToString()), exception3);
                        }
                        sock.Close();
                        sock 
    = null;
                        
    return false;
                    }
                }
                bytes 
    = new byte[0];
                count 
    = 0;
            Label_01DF:
                
    if (this._compressEnable && (count > this._compressThreshold))
                {
                    
    bool flag4 = log.IsInfoEnabled;
                    
    try
                    {
                        MemoryStream baseOutputStream 
    = new MemoryStream();
                        GZipOutputStream stream3 
    = new GZipOutputStream(baseOutputStream);
                        stream3.Write(bytes, 
    0, count);
                        stream3.Finish();
                        bytes 
    = baseOutputStream.GetBuffer();
                        count 
    = (int) baseOutputStream.Length;
                        num 
    |= 2;
                        
    bool flag5 = log.IsInfoEnabled;
                    }
                    
    catch (IOException exception4)
                    {
                        
    if (log.IsErrorEnabled)
                        {
                            log.Error(GetLocalizedString(
    "set compression failure"), exception4);
                        }
                    }
                }
                
    try
                {
                    
    string s = string.Concat(new object[] { cmdname, " ", key, " ", num, " ", GetExpirationTime(expiry), " ", count, "\r\n" });
                    sock.Write(Encoding.UTF8.GetBytes(s));
                    sock.Write(bytes, 
    0, count);
                    sock.Write(Encoding.UTF8.GetBytes(
    "\r\n"));
                    sock.Flush();
                    
    string newValue = sock.ReadLine();
                    
    bool flag6 = log.IsInfoEnabled;
                    
    if ("STORED" == newValue)
                    {
                        
    bool flag7 = log.IsInfoEnabled;
                        sock.Close();
                        sock 
    = null;
                        
    return true;
                    }
                    
    if ("NOT_STORED" == newValue)
                    {
                        
    if (!log.IsInfoEnabled)
                        {
                        }
                    }
                    
    else if (log.IsErrorEnabled)
                    {
                        log.Error(GetLocalizedString(
    "set error").Replace("$$Key$$", key).Replace("$$Size$$", count.ToString(new NumberFormatInfo())).Replace("$$Line$$", newValue));
                    }
                }
                
    catch (IOException exception5)
                {
                    
    if (log.IsErrorEnabled)
                    {
                        log.Error(GetLocalizedString(
    "set IOException"), exception5);
                    }
                    
    //##监测##
                    
    //exception.Message=无法将数据写入传输连接: 远程主机强迫关闭了一个现有的连接。。
                    
    //原因:memcached重启类造成的连接池无法再通信的错误
                    
    //解决:判断上面的message出现次数几次,就考虑重新建立连接池
                    if (exception5.Message.Contains("无法将数据写入传输连接: 远程主机强迫关闭了一个现有的连接"))
                    {
                        MemcachedSocksMonitor.SockIOErrRestatr();
                    }
                    
    try
                    {
                        sock.TrueClose();
                    }
                    
    catch (IOException exception6)
                    {
                        
    if (log.IsErrorEnabled)
                        {
                            log.Error(GetLocalizedString(
    "failed to close some socket").Replace("$$Socket$$", sock.ToString()), exception6);
                        }
                    }
                    sock 
    = null
                }
                
    if (sock != null)
                {
                    sock.Close();
                }
                
    return false;
            }

            
    public Hashtable Stats()
            {
                
    return this.Stats(null);
            }

            
    public Hashtable Stats(ArrayList servers)
            {
                SockIOPool instance 
    = SockIOPool.GetInstance(this._poolName);
                
    if (instance == null)
                {
                    
    if (log.IsErrorEnabled)
                    {
                        log.Error(GetLocalizedString(
    "unable to get socket pool"));
                    }
                    
    return null;
                }
                
    if (servers == null)
                {
                    servers 
    = instance.Servers;
                }
                
    if ((servers == null|| (servers.Count <= 0))
                {
                    
    if (log.IsErrorEnabled)
                    {
                        log.Error(GetLocalizedString(
    "stats no servers"));
                    }
                    
    return null;
                }
                Hashtable hashtable 
    = new Hashtable();
                
    for (int i = 0; i < servers.Count; i++)
                {
                    SockIO connection 
    = instance.GetConnection((string) servers[i]);
                    
    if (connection == null)
                    {
                        
    if (log.IsErrorEnabled)
                        {
                            log.Error(GetLocalizedString(
    "unable to connect").Replace("$$Server$$", servers[i].ToString()));
                        }
                        
    continue;
                    }
                    
    string s = "stats\r\n";
                    
    try
                    {
                        connection.Write(Encoding.UTF8.GetBytes(s));
                        connection.Flush();
                        Hashtable hashtable2 
    = new Hashtable();
                        
    while (true)
                        {
                            
    string str2 = connection.ReadLine();
                            
    bool isDebugEnabled = log.IsDebugEnabled;
                            
    if (str2.StartsWith("STAT"))
                            {
                                
    string[] strArray = str2.Split(new char[] { ' ' });
                                
    string str3 = strArray[1];
                                
    string str4 = strArray[2];
                                
    bool flag2 = log.IsDebugEnabled;
                                hashtable2[str3] 
    = str4;
                            }
                            
    else if ("END" == str2)
                            {
                                
    if (!log.IsDebugEnabled)
                                {
                                }
                                
    goto Label_01E4;
                            }
                            hashtable[servers[i]] 
    = hashtable2;
                        }
                    }
                    
    catch (IOException exception)
                    {
                        
    if (log.IsErrorEnabled)
                        {
                            log.Error(GetLocalizedString(
    "stats IOException"), exception);
                        }
                        
    try
                        {
                            connection.TrueClose();
                        }
                        
    catch (IOException)
                        {
                            
    if (log.IsErrorEnabled)
                            {
                                log.Error(GetLocalizedString(
    "failed to close some socket").Replace("$$Socket$$", connection.ToString()));
                            }
                        }
                        connection 
    = null;
                    }
                Label_01E4:
                    
    if (connection != null)
                    {
                        connection.Close();
                    }
                }
                
    return hashtable;
            }

            
    public bool StoreCounter(string key, long counter)
            {
                
    return this.Set("set", key, counter, DateTime.MaxValue, nulltrue);
            }

            
    public bool StoreCounter(string key, long counter, int hashCode)
            {
                
    return this.Set("set", key, counter, DateTime.MaxValue, hashCode, true);
            }

            
    public long CompressionThreshold
            {
                
    get
                {
                    
    return this._compressThreshold;
                }
                
    set
                {
                    
    this._compressThreshold = value;
                }
            }

            
    public string DefaultEncoding
            {
                
    get
                {
                    
    return this._defaultEncoding;
                }
                
    set
                {
                    
    this._defaultEncoding = value;
                }
            }

            
    public bool EnableCompression
            {
                
    get
                {
                    
    return this._compressEnable;
                }
                
    set
                {
                    
    this._compressEnable = value;
                }
            }

            
    public string PoolName
            {
                
    get
                {
                    
    return this._poolName;
                }
                
    set
                {
                    
    this._poolName = value;
                }
            }

            
    public bool PrimitiveAsString
            {
                
    get
                {
                    
    return this._primitiveAsString;
                }
                
    set
                {
                    
    this._primitiveAsString = value;
                }
            }
        }
    }

    大致就以上内容,修改的地方也不算多,总结发现自己写博文很吃力,平时的缺点很明显,不知道如何去描述一个问题及解决方法,虽然自己都知道,但是就是表达不出来

    这文章算是靠代码说话了,很惭愧,有兴趣的话就给点意见以及错误的地方

  • 相关阅读:
    诺基亚为 Qt 增添 LGPL 授权选择
    Web Beans (JSR299): Q&amp;A with Specification Lead Gavin King
    Web Beans (JSR299): Q&amp;A with Specification Lead Gavin King
    诺基亚为 Qt 增添 LGPL 授权选择
    使用 Hibernate 进行大数据量的性能测试
    略谈如何在对话框创建视图类画图
    JBoss Seam 框架下的单元测试
    领域模型设计讨论与研究
    JBoss Seam 框架下的单元测试
    The use of FS/GS registers
  • 原文地址:https://www.cnblogs.com/wyxy2005/p/1806785.html
Copyright © 2011-2022 走看看