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
原文地址:https://www.cnblogs.com/xijianyao/p/4845936.html