• C#链接阿里云OCS


    一、阿里云OCS简单介绍

      阿里云OCS兼容Memcached,因为OCS就相当于Memcached的服务器端,我们代码只是当作客户端,链接上服务器端就行了。阿里云OCS介绍详情见 http://www.aliyun.com/product/ocs?spm=5176.2020520107.0.0.s2zgFk#Help 。

    二、C#客户端链接OCS

      1.阿里云文档上介绍的是用Enyim.Caching去链接OCS。那我们项目中就用nuget去下载Enyim.Caching包。nuget搜索Enyim,搜索到的结果如下图,第一个是nolog版本的,第二个是带log的,随便一个都可以。

      nuget搜索结果如下:

      

      2.安装成功以后,再链接OCS,写个初始化memcached的代码,代码如下。

     1 using Enyim.Caching;
     2 using Enyim.Caching.Configuration;
     3 using Enyim.Caching.Memcached;
     4 using System;
     5 using System.Collections.Generic;
     6 using System.Linq;
     7 using System.Net;
     8 using System.Text;
     9 using System.Threading.Tasks;
    10 
    11 namespace OCS
    12 {
    13     public class MemCached
    14     {
    15         private static MemcachedClient MemClient;
    16 
    17         static readonly object padlock = new object();
    18         //线程安全的单例模式
    19         public static MemcachedClient getInstance(string hostName,string userName,string password)
    20         {
    21             if (MemClient == null)
    22             {
    23                 lock (padlock)
    24                 {
    25                     if (MemClient == null)
    26                     {
    27                         MemClientInit(hostName,userName,password);
    28                     }
    29                 }
    30             }
    31             return MemClient;
    32         }
    33 
    34         static void MemClientInit(string hostName,string userName,string password)
    35         {
    36             try
    37             {
    38                 //初始化缓存
    39                 MemcachedClientConfiguration memConfig = new MemcachedClientConfiguration();
    40                 IPAddress newaddress = IPAddress.Parse(Dns.GetHostEntry(hostName).AddressList[0].ToString());
    41                 IPEndPoint ipEndPoint = new IPEndPoint(newaddress, 11211);
    42 
    43                 // 配置文件 - ip
    44                 memConfig.Servers.Add(ipEndPoint);
    45                 // 配置文件 - 协议
    46                 memConfig.Protocol = MemcachedProtocol.Binary;
    47                 // 配置文件-权限
    48                 memConfig.Authentication.Type = typeof(PlainTextAuthenticator);
    49                 memConfig.Authentication.Parameters["zone"] = "";
    50                 memConfig.Authentication.Parameters["userName"] = userName;
    51                 memConfig.Authentication.Parameters["password"] = password;
    52                 //下面请根据实例的最大连接数进行设置
    53                 memConfig.SocketPool.MinPoolSize = 5;
    54                 memConfig.SocketPool.MaxPoolSize = 200;
    55                 MemClient = new MemcachedClient(memConfig);
    56             }
    57             catch (Exception)
    58             {
    59                 MemClient = null;
    60             }
    61         }
    62     }
    63 }

      3.再写个服务去调用上面的初始化代码,创建MemcachedClient的实例去调用客户端代码。下面代码中的构造函数中的_setting.HostAddress, _setting.AccessId, _setting.AccessKey分别对应的是,OCS的链接地址,链接密码和OCS的实例ID。

      1 using Enyim.Caching;
      2 using Enyim.Caching.Memcached;
      3 using Enyim.Caching.Memcached.Results;
      4 using System;
      5 using System.Collections.Generic;
      6 using System.Linq;
      7 using System.Text;
      8 using System.Text.RegularExpressions;
      9 using System.Threading.Tasks;
     10 using System.Web.Script.Serialization;
     11 using Zupo.Core.Caching;
     12 using ServiceStack.Text;
     13 using Newtonsoft.Json;
     14 
     15 namespace OCS
     16 {
     17     public class OCSService
     18     {
     19         IOCSSetting _setting;
     20 
     21         private MemcachedClient client;
     22 
     23         public OCSService(IOCSSetting setting)
     24         {
     25             this._setting = setting;
     26             this.client = MemCached.getInstance(_setting.HostAddress, _setting.AccessId, _setting.AccessKey);
     27         }
     28 
     29         /// <summary>
     30         /// 是否链接上服务器
     31         /// </summary>
     32         protected bool LinkServer
     33         {
     34             get
     35             {
     36                 return client == null ? false : true;
     37             }
     38         }
     39 
     40         protected IGetOperationResult ExecuteGet(string key)
     41         {
     42             return client.ExecuteGet(key);
     43         }
     44 
     45         /// <summary>
     46         /// 根据key获得缓存
     47         /// </summary>
     48         /// <param name="key"></param>
     49         /// <returns></returns>
     50         protected object Get(string key)
     51         {
     52             return client.Get(key);
     53         }
     54 
     55         /// <summary>
     56         /// 根据key获得缓存 泛型方法
     57         /// </summary>
     58         /// <typeparam name="T"></typeparam>
     59         /// <param name="key"></param>
     60         /// <returns></returns>
     61         protected T Get<T>(string key)
     62         {
     63             try
     64             {
     65                 //JavaScriptSerializer jsonSerializer = new JavaScriptSerializer();
     66                 //string objectStr = client.Get(key).ToString();
     67                 var obj = client.Get(key);
     68                 if (obj != null)
     69                 {
     70                     return JsonConvert.DeserializeObject<T>(obj.ToString());
     71                 }
     72                 return default(T);
     73                 //return objectStr.FromJson<T>();
     74             }
     75             catch (Exception)
     76             {
     77                 this.Remove(key);
     78                 return default(T);
     79             }
     80         }
     81 
     82         /// <summary>
     83         /// 根据key获得缓存 泛型方法
     84         /// </summary>
     85         /// <typeparam name="T"></typeparam>
     86         /// <param name="key"></param>
     87         /// <returns></returns>
     88         protected List<T> GetList<T>(string key)
     89         {
     90             var objectStr = client.Get(key).ToString();
     91 
     92             //return objectStr.FromJson<List<T>>();
     93             return JsonConvert.DeserializeObject<List<T>>(objectStr);
     94         }
     95 
     96         /// <summary>
     97         /// 根据数组key获得数据 IDictionary
     98         /// </summary>
     99         /// <param name="keys"></param>
    100         /// <returns></returns>
    101         protected IDictionary<string, object> GetByKeys(string[] keys)
    102         {
    103             return client.Get(keys);
    104         }
    105 
    106         /// <summary>
    107         /// 该key值缓存是否存在
    108         /// </summary>
    109         /// <param name="key"></param>
    110         /// <returns></returns>
    111         public bool Contains(string key)
    112         {
    113             object value;
    114 
    115             return client.TryGet(key, out value);
    116         }
    117 
    118         /// <summary>
    119         /// 存储,有的话直接覆盖
    120         /// </summary>
    121         /// <param name="key"></param>
    122         /// <param name="value"></param>
    123         /// <returns></returns>
    124         protected bool Set(string key, object value)
    125         {
    126             return client.Store(StoreMode.Set, key, value);
    127         }
    128 
    129         /// <summary>
    130         /// 存储,有的话直接覆盖
    131         /// </summary>
    132         /// <param name="key"></param>
    133         /// <param name="value"></param>
    134         /// <returns></returns>
    135         protected bool Set<T>(string key, T value)
    136         {
    137             try
    138             {
    139                 //执行序列化
    140                 //string objectStr = value.ToJson();
    141                 string objectStr = JsonConvert.SerializeObject(value, Formatting.Indented, new JsonSerializerSettings { ReferenceLoopHandling = ReferenceLoopHandling.Ignore });
    142                 return client.Store(StoreMode.Set, key, objectStr);
    143             }
    144             catch(Exception)
    145             {
    146                 return false;
    147             }
    148             
    149         }
    150 
    151         /// <summary>
    152         /// 存储,有的话直接覆盖
    153         /// </summary>
    154         /// <param name="key"></param>
    155         /// <param name="value"></param>
    156         /// <returns></returns>
    157         protected bool Set<T>(string key, List<T> value)
    158         {
    159             //执行序列化
    160             //string objectStr = value.ToJson();
    161             string objectStr = JsonConvert.SerializeObject(value, Formatting.Indented, new JsonSerializerSettings { ReferenceLoopHandling = ReferenceLoopHandling.Ignore });
    162             return client.Store(StoreMode.Set, key, objectStr);
    163         }
    164 
    165         /// <summary>
    166         /// 存储,有的话直接覆盖
    167         /// </summary>
    168         /// <param name="key"></param>
    169         /// <param name="value"></param>
    170         /// <param name="expire">失效时间:TimeSpan</param>
    171         /// <returns></returns>
    172         protected bool SetExpires(string key, object value, TimeSpan expire)
    173         {
    174             try
    175             {
    176                 //string objectStr = value.ToJson();
    177                 string objectStr = JsonConvert.SerializeObject(value, Formatting.Indented, new JsonSerializerSettings { ReferenceLoopHandling = ReferenceLoopHandling.Ignore });
    178                 return client.Store(StoreMode.Set, key, objectStr, expire);
    179             }
    180             catch(Exception)
    181             {
    182                 return false;
    183             }
    184             
    185         }
    186 
    187         /// <summary>
    188         /// 存储,有的话直接覆盖
    189         /// </summary>
    190         /// <param name="key"></param>
    191         /// <param name="value"></param>
    192         /// <param name="expire">失效时间:TimeSpan</param>
    193         /// <returns></returns>
    194         protected bool SetExpires<T>(string key, T value, TimeSpan expire)
    195         {
    196             //执行序列化
    197             //string objectStr = value.ToJson();
    198             string objectStr = JsonConvert.SerializeObject(value, Formatting.Indented, new JsonSerializerSettings { ReferenceLoopHandling = ReferenceLoopHandling.Ignore });
    199             return client.Store(StoreMode.Set, key, objectStr, expire);
    200         }
    201 
    202         /// <summary>
    203         /// 删除cached
    204         /// </summary>
    205         /// <param name="key"></param>
    206         /// <returns></returns>
    207         public void Remove(string key)
    208         {
    209             client.Remove(key);
    210         }
    211 
    212         /// <summary>
    213         /// Removes items by pattern
    214         /// 该方法未实现
    215         /// </summary>
    216         /// <param name="pattern">pattern</param>
    217         public virtual void RemoveByPattern(string pattern)
    218         {
    219             var regex = new Regex(pattern, RegexOptions.Singleline | RegexOptions.Compiled | RegexOptions.IgnoreCase);
    220             //var keysToRemove = new List<String>();
    221 
    222             //var allkeys = client.
    223             //foreach (var key in allkeys)
    224             //    if (regex.IsMatch(key))
    225             //        keysToRemove.Add(key);
    226 
    227             //foreach (string key in keysToRemove)
    228             //{
    229             //    Remove(key);
    230             //}
    231         }
    232 
    233         /// <summary>
    234         /// 清空ocs缓存
    235         /// </summary>
    236         /// <returns></returns>
    237         public void Clear()
    238         {
    239             client.FlushAll();
    240         }
    241     }
    242 }
    MemcachedClient


    三、使用注意点

      因为OCS只支持key/value的格式进行存储,所以我项目中先运用了Newtonsoft.Json去先对对象序列化,再存入到OCS上,读取的时候再反序列化读取。代码如下:

     1 /// <summary>
     2         /// 存储,有的话直接覆盖
     3         /// </summary>
     4         /// <param name="key"></param>
     5         /// <param name="value"></param>
     6         /// <returns></returns>
     7         protected bool Set<T>(string key, T value)
     8         {
     9             try
    10             {
    11                 //执行序列化
    12                 string objectStr = JsonConvert.SerializeObject(value, Formatting.Indented, new JsonSerializerSettings { ReferenceLoopHandling = ReferenceLoopHandling.Ignore });
    13                 return client.Store(StoreMode.Set, key, objectStr);
    14             }
    15             catch(Exception)
    16             {
    17                 return false;
    18             }
    19             
    20         }
    View Code

    代码中设置了JsonSerializerSettings,因为项目用的是EF,一些对象里面的属性可能是另外一个对象还有是一些死循环的属性,所以数据量会比较大,直接执行序列化会内存溢出的,所以要在对象里面不需要序列化的属性上加上[JsonIgnore],忽略此属性或字段序列化。
    那么反序列化获取数据代码如下:

     1 /// <summary>
     2         /// 根据key获得缓存 泛型方法
     3         /// </summary>
     4         /// <typeparam name="T"></typeparam>
     5         /// <param name="key"></param>
     6         /// <returns></returns>
     7         protected T Get<T>(string key)
     8         {
     9             try
    10             {
    11                 var obj = client.Get(key);
    12                 if (obj != null)
    13                 {
    14                     return JsonConvert.DeserializeObject<T>(obj.ToString());
    15                 }
    16                 return default(T);
    17             }
    18             catch (Exception)
    19             {
    20                 this.Remove(key);
    21                 return default(T);
    22             }
    23         }
    View Code
  • 相关阅读:
    C++ promise
    C++ shared_future
    C++包装对象packaged_task
    C++ wait_for
    assert
    虚函数表构建时机
    C++ timed_mutex
    C++异步async
    C++原子操作atomic
    C++ typeid获取类型信息
  • 原文地址:https://www.cnblogs.com/xijianyao/p/4845936.html
Copyright © 2020-2023  润新知