二  Redis缓存

考虑到将来服务器的升级扩展,使用redis代替.net内置缓存是比较理想的选择。redis是非常成熟好用的缓存系统,安装配置非常简单,直接上官网下载安装包 安装启动就行了。

1 配置。redis安装后默认bind 接口是127.0.0.1,也就是本地回环地址。在开发环境下为了允许多个开发机器作为客户端访问,bind配置后面加上了本机局域网ip,如  bind 127.0.0.1 192.168.1.100 。

2  配置了redis读写分离。开发web  api端的web.config件 增加配置项

<add name="RedisConnection_read" connectionString="192.168.0.100:6379" />
<add name="RedisConnection_write" connectionString="192.168.0.100:6379" />

redis 读写辅助类代码如下

  1. public class RedisCache: IRedisCache
  2. {
  3. private static string[] ReadWriteHosts = ConfigurationManager.ConnectionStrings["RedisConnection_read"].ConnectionString.Split(';');
  4. private static string[] ReadOnlyHosts = ConfigurationManager.ConnectionStrings["RedisConnection_write"].ConnectionString.Split(';');
  5.  
  6. #region -- 连接信息 --
  7. public static PooledRedisClientManager prcm = CreateManager(ReadWriteHosts, ReadOnlyHosts);
  8.  
  9. private static PooledRedisClientManager CreateManager(string[] readWriteHosts, string[] readOnlyHosts)
  10. {
  11. // 支持读写分离,均衡负载
  12. return new PooledRedisClientManager(readWriteHosts, readOnlyHosts, new RedisClientManagerConfig
  13. {
  14. MaxWritePoolSize = 5, // “写”链接池链接数
  15. MaxReadPoolSize = 5, // “读”链接池链接数
  16. AutoStart = true,
  17. });
  18. }
  19. #endregion
  20.  
  21. #region -- Item --
  22. /// <summary>
  23. /// 设置单体
  24. /// </summary>
  25. /// <typeparam name="T"></typeparam>
  26. /// <param name="key"></param>
  27. /// <param name="t"></param>
  28. /// <param name="timeSpan"></param>
  29. /// <returns></returns>
  30. public bool Item_Set<T>(string key, T t)
  31. {
  32. try
  33. {
  34. using (IRedisClient redis = prcm.GetClient())
  35. {
  36. return redis.Set<T>(key, t, new TimeSpan(1, 0, 0));
  37. }
  38. }
  39. catch (Exception ex)
  40. {
  41. throw ex;
  42. }
  43.  
  44. }
  45.  
  46. /// <summary>
  47. /// 设置单体
  48. /// </summary>
  49. /// <typeparam name="T"></typeparam>
  50. /// <param name="key"></param>
  51. /// <param name="t"></param>
  52. /// <param name="timeSpan"></param>
  53. /// <returns></returns>
  54. public bool Item_Set<T>(string key, T t, int timeout)
  55. {
  56. try
  57. {
  58. using (IRedisClient redis = prcm.GetClient())
  59. {
  60. return redis.Set<T>(key, t, new TimeSpan(0, timeout, 0));
  61. }
  62. }
  63. catch (Exception ex)
  64. {
  65. throw ex;
  66. }
  67.  
  68. }
  69.  
  70. /// <summary>
  71. /// 获取单体
  72. /// </summary>
  73. /// <typeparam name="T"></typeparam>
  74. /// <param name="key"></param>
  75. /// <returns></returns>
  76. public T Item_Get<T>(string key) where T : class
  77. {
  78. using (IRedisClient redis = prcm.GetReadOnlyClient())
  79. {
  80. return redis.Get<T>(key);
  81. }
  82. }
  83.  
  84. /// <summary>
  85. /// 设置缓存过期
  86. /// </summary>
  87. /// <param name="key"></param>
  88. /// <param name="datetime"></param>
  89. public bool Item_Remove(string key)
  90. {
  91. using (IRedisClient redis = prcm.GetClient())
  92. {
  93. return redis.Remove(key);
  94. }
  95. }
  96.  
  97. /// <summary>
  98. /// 设置缓存过期
  99. /// </summary>
  100. /// <param name="key"></param>
  101. public bool Item_SetExpire(string key, int timeout)
  102. {
  103. using (IRedisClient redis = prcm.GetClient())
  104. {
  105. return redis.ExpireEntryIn(key, new TimeSpan(0, timeout, 0));
  106. }
  107. }
  108.  
  109. #endregion
  110.  
  111. #region -- List --
  112.  
  113. public void List_Add<T>(string key, T t)
  114. {
  115. using (IRedisClient redis = prcm.GetClient())
  116. {
  117.  
  118. var redisTypedClient = redis.As<T>();
  119. redisTypedClient.AddItemToList(redisTypedClient.Lists[key], t);
  120.  
  121. }
  122. }
  123.  
  124. public void List_Set<T>(string key, List<T> list)
  125. {
  126. using (IRedisClient redis = prcm.GetClient())
  127. {
  128.  
  129. var redisTypedClient = redis.As<T>();
  130. redisTypedClient.Lists[key].RemoveAll();
  131. if (list != null)
  132. {
  133. list.ForEach(p =>
  134. {
  135. redisTypedClient.AddItemToList(redisTypedClient.Lists[key], p);
  136. });
  137. }
  138.  
  139. }
  140. }
  141.  
  142. public bool List_Remove<T>(string key, T t)
  143. {
  144. using (IRedisClient redis = prcm.GetClient())
  145. {
  146. var redisTypedClient = redis.As<T>();
  147. return redisTypedClient.RemoveItemFromList(redisTypedClient.Lists[key], t) > 0;
  148. }
  149. }
  150. public void List_RemoveAll<T>(string key)
  151. {
  152. using (IRedisClient redis = prcm.GetClient())
  153. {
  154. var redisTypedClient = redis.As<T>();
  155. redisTypedClient.Lists[key].RemoveAll();
  156. }
  157. }
  158.  
  159. public void List_RemoveRange<T>(string key,List<T> list)
  160. {
  161. using (IRedisClient redis = prcm.GetClient())
  162. {
  163. var redisTypedClient = redis.As<T>();
  164. if (list != null && list.Count > 0)
  165. {
  166. for(int i=0; i<list.Count;i++)
  167. {
  168. List_Remove<T>(key, list[i]);
  169. }
  170. }
  171. }
  172. }
  173.  
  174. public long List_Count(string key)
  175. {
  176. using (IRedisClient redis = prcm.GetReadOnlyClient())
  177. {
  178. return redis.GetListCount(key);
  179. }
  180. }
  181.  
  182. public List<T> List_GetRange<T>(string key, int start, int count)
  183. {
  184. using (IRedisClient redis = prcm.GetReadOnlyClient())
  185. {
  186. var c = redis.As<T>();
  187. return c.Lists[key].GetRange(start, start + count - 1);
  188. }
  189. }
  190.  
  191. public List<T> List_GetList<T>(string key)
  192. {
  193. RedisClient client = new RedisClient("");
  194. using (IRedisClient redis = prcm.GetReadOnlyClient())
  195. {
  196. var c = redis.As<T>();
  197. return c.Lists[key].GetRange(0, c.Lists[key].Count);
  198. }
  199. }
  200.  
  201. public List<T> List_GetList<T>(string key, int pageIndex, int pageSize)
  202. {
  203. int start = pageSize * (pageIndex - 1);
  204. return List_GetRange<T>(key, start, pageSize);
  205. }
  206.  
  207. /// <summary>
  208. /// 设置缓存过期
  209. /// </summary>
  210. /// <param name="key"></param>
  211. /// <param name="datetime"></param>
  212. public void List_SetExpire(string key, DateTime datetime)
  213. {
  214. using (IRedisClient redis = prcm.GetClient())
  215. {
  216. redis.ExpireEntryAt(key, datetime);
  217. }
  218. }
  219. #endregion
  220.  
  221. #region -- Set --
  222. public void Set_Add<T>(string key, T t)
  223. {
  224. using (IRedisClient redis = prcm.GetClient())
  225. {
  226. var redisTypedClient = redis.As<T>();
  227. redisTypedClient.Sets[key].Add(t);
  228. }
  229. }
  230. public bool Set_Contains<T>(string key, T t)
  231. {
  232. using (IRedisClient redis = prcm.GetClient())
  233. {
  234. var redisTypedClient = redis.As<T>();
  235. return redisTypedClient.Sets[key].Contains(t);
  236. }
  237. }
  238. public bool Set_Remove<T>(string key, T t)
  239. {
  240. using (IRedisClient redis = prcm.GetClient())
  241. {
  242. var redisTypedClient = redis.As<T>();
  243. return redisTypedClient.Sets[key].Remove(t);
  244. }
  245. }
  246. #endregion
  247.  
  248. #region -- Hash --
  249. /// <summary>
  250. /// 判断某个数据是否已经被缓存
  251. /// </summary>
  252. /// <typeparam name="T"></typeparam>
  253. /// <param name="key"></param>
  254. /// <param name="dataKey"></param>
  255. /// <returns></returns>
  256. public bool Hash_Exist<T>(string key, string dataKey)
  257. {
  258. using (IRedisClient redis = prcm.GetReadOnlyClient())
  259. {
  260. return redis.HashContainsEntry(key, dataKey);
  261. }
  262. }
  263.  
  264. /// <summary>
  265. /// 存储数据到hash表
  266. /// </summary>
  267. /// <typeparam name="T"></typeparam> Class1.cs
  268. /// <param name="key"></param>
  269. /// <param name="dataKey"></param>
  270. /// <returns></returns>
  271. public bool Hash_Set<T>(string key, string dataKey, T t)
  272. {
  273. using (IRedisClient redis = prcm.GetClient())
  274. {
  275. string value = ServiceStack.Text.JsonSerializer.SerializeToString<T>(t);
  276. return redis.SetEntryInHash(key, dataKey, value);
  277. }
  278. }
  279. /// <summary>
  280. /// 移除hash中的某值
  281. /// </summary>
  282. /// <typeparam name="T"></typeparam>
  283. /// <param name="key"></param>
  284. /// <param name="dataKey"></param>
  285. /// <returns></returns>
  286. public bool Hash_Remove(string key, string dataKey)
  287. {
  288. using (IRedisClient redis = prcm.GetClient())
  289. {
  290. return redis.RemoveEntryFromHash(key, dataKey);
  291. }
  292. }
  293. /// <summary>
  294. /// 移除整个hash
  295. /// </summary>
  296. /// <typeparam name="T"></typeparam>
  297. /// <param name="key"></param>
  298. /// <param name="dataKey"></param>
  299. /// <returns></returns>
  300. public bool Hash_Remove(string key)
  301. {
  302. using (IRedisClient redis = prcm.GetClient())
  303. {
  304. return redis.Remove(key);
  305. }
  306. }
  307. /// <summary>
  308. /// 从hash表获取数据
  309. /// </summary>
  310. /// <typeparam name="T"></typeparam>
  311. /// <param name="key"></param>
  312. /// <param name="dataKey"></param>
  313. /// <returns></returns>
  314. public T Hash_Get<T>(string key, string dataKey)
  315. {
  316. using (IRedisClient redis = prcm.GetReadOnlyClient())
  317. {
  318. string value = redis.GetValueFromHash(key, dataKey);
  319. return ServiceStack.Text.JsonSerializer.DeserializeFromString<T>(value);
  320. }
  321. }
  322. /// <summary>
  323. /// 获取整个hash的数据
  324. /// </summary>
  325. /// <typeparam name="T"></typeparam>
  326. /// <param name="key"></param>
  327. /// <returns></returns>
  328. public List<T> Hash_GetAll<T>(string key)
  329. {
  330. using (IRedisClient redis = prcm.GetReadOnlyClient())
  331. {
  332. var list = redis.GetHashValues(key);
  333. if (list != null && list.Count > 0)
  334. {
  335. List<T> result = new List<T>();
  336. foreach (var item in list)
  337. {
  338. var value = ServiceStack.Text.JsonSerializer.DeserializeFromString<T>(item);
  339. result.Add(value);
  340. }
  341. return result;
  342. }
  343. return null;
  344. }
  345. }
  346. /// <summary>
  347. /// 设置缓存过期
  348. /// </summary>
  349. /// <param name="key"></param>
  350. /// <param name="datetime"></param>
  351. public void Hash_SetExpire(string key, DateTime datetime)
  352. {
  353. using (IRedisClient redis = prcm.GetClient())
  354. {
  355. redis.ExpireEntryAt(key, datetime);
  356. }
  357. }
  358.  
  359. /// <summary>
  360. /// 获取Hash集合数量
  361. /// </summary>
  362. /// <param name="key">Hashid</param>
  363. public long Hash_GetCount(string key)
  364. {
  365. using (IRedisClient redis = prcm.GetReadOnlyClient())
  366. {
  367. return redis.GetHashCount(key);
  368. }
  369. }
  370. #endregion
  371.  
  372. #region -- SortedSet --
  373. /// <summary>
  374. /// 添加数据到 SortedSet
  375. /// </summary>
  376. /// <typeparam name="T"></typeparam>
  377. /// <param name="key"></param>
  378. /// <param name="t"></param>
  379. /// <param name="score"></param>
  380. public bool SortedSet_Add<T>(string key, T t, double score)
  381. {
  382. using (IRedisClient redis = prcm.GetClient())
  383. {
  384. string value = ServiceStack.Text.JsonSerializer.SerializeToString<T>(t);
  385. return redis.AddItemToSortedSet(key, value, score);
  386. }
  387. }
  388. /// <summary>
  389. /// 移除数据从SortedSet
  390. /// </summary>
  391. /// <typeparam name="T"></typeparam>
  392. /// <param name="key"></param>
  393. /// <param name="t"></param>
  394. /// <returns></returns>
  395. public bool SortedSet_Remove<T>(string key, T t)
  396. {
  397. using (IRedisClient redis = prcm.GetClient())
  398. {
  399. string value = ServiceStack.Text.JsonSerializer.SerializeToString<T>(t);
  400. return redis.RemoveItemFromSortedSet(key, value);
  401. }
  402. }
  403. /// <summary>
  404. /// 修剪SortedSet
  405. /// </summary>
  406. /// <param name="key"></param>
  407. /// <param name="size">保留的条数</param>
  408. /// <returns></returns>
  409. public long SortedSet_Trim(string key, int size)
  410. {
  411. using (IRedisClient redis = prcm.GetClient())
  412. {
  413. return redis.RemoveRangeFromSortedSet(key, size, 9999999);
  414. }
  415. }
  416. /// <summary>
  417. /// 获取SortedSet的长度
  418. /// </summary>
  419. /// <param name="key"></param>
  420. /// <returns></returns>
  421. public long SortedSet_Count(string key)
  422. {
  423. using (IRedisClient redis = prcm.GetReadOnlyClient())
  424. {
  425. return redis.GetSortedSetCount(key);
  426. }
  427. }
  428.  
  429. /// <summary>
  430. /// 获取SortedSet的分页数据
  431. /// </summary>
  432. /// <typeparam name="T"></typeparam>
  433. /// <param name="key"></param>
  434. /// <param name="pageIndex"></param>
  435. /// <param name="pageSize"></param>
  436. /// <returns></returns>
  437. public List<T> SortedSet_GetList<T>(string key, int pageIndex, int pageSize)
  438. {
  439. using (IRedisClient redis = prcm.GetReadOnlyClient())
  440. {
  441. var list = redis.GetRangeFromSortedSet(key, (pageIndex - 1) * pageSize, pageIndex * pageSize - 1);
  442. if (list != null && list.Count > 0)
  443. {
  444. List<T> result = new List<T>();
  445. foreach (var item in list)
  446. {
  447. var data = ServiceStack.Text.JsonSerializer.DeserializeFromString<T>(item);
  448. result.Add(data);
  449. }
  450. return result;
  451. }
  452. }
  453. return null;
  454. }
  455.  
  456. /// <summary>
  457. /// 获取SortedSet的全部数据
  458. /// </summary>
  459. /// <typeparam name="T"></typeparam>
  460. /// <param name="key"></param>
  461. /// <param name="pageIndex"></param>
  462. /// <param name="pageSize"></param>
  463. /// <returns></returns>
  464. public List<T> SortedSet_GetListALL<T>(string key)
  465. {
  466. using (IRedisClient redis = prcm.GetReadOnlyClient())
  467. {
  468. var list = redis.GetRangeFromSortedSet(key, 0, 9999999);
  469. if (list != null && list.Count > 0)
  470. {
  471. List<T> result = new List<T>();
  472. foreach (var item in list)
  473. {
  474. var data = ServiceStack.Text.JsonSerializer.DeserializeFromString<T>(item);
  475. result.Add(data);
  476. }
  477. return result;
  478. }
  479. }
  480. return null;
  481. }
  482.  
  483. /// <summary>
  484. /// 设置缓存过期
  485. /// </summary>
  486. /// <param name="key"></param>
  487. /// <param name="datetime"></param>
  488. public void SortedSet_SetExpire(string key, DateTime datetime)
  489. {
  490. using (IRedisClient redis = prcm.GetClient())
  491. {
  492. redis.ExpireEntryAt(key, datetime);
  493. }
  494. }
  495. #endregion
  496.  
  497. }

3  用 redis实现 分布式 跨应用session共享,同样,web api 的webconfig文件里session配置为

  1. <system.web>
  2. <sessionState mode="Custom" customProvider="RedisSessionStateStore">
  3. <providers>
  4. <add name="RedisSessionStateStore" type="MyProject.RedisSessionStateStore" />
  5. </providers>
  6. </sessionState>
  7. ...
  8. <system.web>
  1. RedisSessionStateStore实现代码如下:
  1. public class RedisSessionStateStore : SessionStateStoreProviderBase
  2. {
  3. IRedisCache redis;
  4. public RedisSessionStateStore()
  5. {
  6. redis = IDAL.DALContainer.Resolve<IRedisCache>();
  7. }
  8.  
  9. public override SessionStateStoreData CreateNewStoreData(HttpContext context, int timeout)
  10. {
  11. return CreateLegitStoreData(context, null, null, timeout);
  12. }
  13.  
  14. internal static SessionStateStoreData CreateLegitStoreData(HttpContext context, ISessionStateItemCollection sessionItems, HttpStaticObjectsCollection staticObjects, int timeout)
  15. {
  16. if (sessionItems == null)
  17. sessionItems = new SessionStateItemCollection();
  18. if (staticObjects == null && context != null)
  19. staticObjects = SessionStateUtility.GetSessionStaticObjects(context);
  20. return new SessionStateStoreData(sessionItems, staticObjects, timeout);
  21. }
  22.  
  23. public override void CreateUninitializedItem(HttpContext context, string id, int timeout)
  24. {
  25. RedisSessionState state = new RedisSessionState(null, null, timeout);
  26. redis.Item_Set<string>(id, state.ToJson(), timeout);
  27. }
  28.  
  29. private SessionStateStoreData DoGet(HttpContext context, string id, bool exclusive, out bool locked, out TimeSpan lockAge, out object lockId, out SessionStateActions actionFlags)
  30. {
  31. locked = false;
  32. lockId = null;
  33. lockAge = TimeSpan.Zero;
  34. actionFlags = SessionStateActions.None;
  35. RedisSessionState state = RedisSessionState.FromJson(redis.Item_Get<string>(id));
  36. if (state == null)
  37. {
  38. return null;
  39. }
  40. redis.Item_SetExpire(id, state._timeout);
  41. return CreateLegitStoreData(context, state._sessionItems, state._staticObjects, state._timeout);
  42. }
  43.  
  44. public override SessionStateStoreData GetItem(HttpContext context, string id, out bool locked, out TimeSpan lockAge, out object lockId, out SessionStateActions actionFlags)
  45. {
  46. return this.DoGet(context, id, false, out locked, out lockAge, out lockId, out actionFlags);
  47. }
  48.  
  49. public override SessionStateStoreData GetItemExclusive(HttpContext context, string id, out bool locked, out TimeSpan lockAge, out object lockId, out SessionStateActions actionFlags)
  50. {
  51. return this.DoGet(context, id, true, out locked, out lockAge, out lockId, out actionFlags);
  52. }
  53.  
  54. public override void SetAndReleaseItemExclusive(HttpContext context, string id, SessionStateStoreData item, object lockId, bool newItem)
  55. {
  56. ISessionStateItemCollection sessionItems = null;
  57. HttpStaticObjectsCollection staticObjects = null;
  58.  
  59. if (item.Items.Count > 0)
  60. sessionItems = item.Items;
  61. if (!item.StaticObjects.NeverAccessed)
  62. staticObjects = item.StaticObjects;
  63.  
  64. RedisSessionState state2 = new RedisSessionState(sessionItems, staticObjects, item.Timeout);
  65.  
  66. redis.Item_Set<string>(id, state2.ToJson(), item.Timeout);
  67. }
  68.  
  69. #region "未实现方法"
  70.  
  71. public override void Dispose()
  72. {
  73.  
  74. }
  75.  
  76. public override void EndRequest(HttpContext context)
  77. {
  78.  
  79. }
  80.  
  81. public override void InitializeRequest(HttpContext context)
  82. {
  83.  
  84. }
  85.  
  86. public override void ReleaseItemExclusive(HttpContext context, string id, object lockId)
  87. {
  88. }
  89.  
  90. public override void RemoveItem(HttpContext context, string id, object lockId, SessionStateStoreData item)
  91. {
  92. redis.Item_Remove(id);
  93. }
  94.  
  95. public override void ResetItemTimeout(HttpContext context, string id)
  96. {
  97.  
  98. }
  99.  
  100. public override bool SetItemExpireCallback(SessionStateItemExpireCallback expireCallback)
  101. {
  102. return true;
  103. }
  104.  
  105. #endregion
  106.  
  107. }
  108. internal sealed class SessionStateItem
  109. {
  110. public Dictionary<string, SaveValue> Dict;
  111. public int Timeout;
  112. }
  113.  
  114. internal sealed class SaveValue
  115. {
  116. public object Value { get; set; }
  117.  
  118. public Type Type { get; set; }
  119. }
  120.  
  121. internal sealed class RedisSessionState
  122. {
  123. internal ISessionStateItemCollection _sessionItems;
  124. internal HttpStaticObjectsCollection _staticObjects;
  125. internal int _timeout;
  126.  
  127. internal RedisSessionState(ISessionStateItemCollection sessionItems, HttpStaticObjectsCollection staticObjects, int timeout)
  128. {
  129. this.Copy(sessionItems, staticObjects, timeout);
  130. }
  131.  
  132. internal void Copy(ISessionStateItemCollection sessionItems, HttpStaticObjectsCollection staticObjects, int timeout)
  133. {
  134. this._sessionItems = sessionItems;
  135. this._staticObjects = staticObjects;
  136. this._timeout = timeout;
  137. }
  138.  
  139. public string ToJson()
  140. {
  141. // 这里忽略_staticObjects这个成员。
  142.  
  143. if (_sessionItems == null || _sessionItems.Count == 0)
  144. {
  145. return null;
  146. }
  147.  
  148. Dictionary<string, SaveValue> dict = new Dictionary<string, SaveValue>(_sessionItems.Count);
  149.  
  150. NameObjectCollectionBase.KeysCollection keys = _sessionItems.Keys;
  151. string key;
  152. object objectValue = string.Empty;
  153. Type type = null;
  154. //2016-09-04解决存入值没有类型导致读取值是jobject问题  
  155. for (int i = 0; i < keys.Count; i++)
  156. {
  157. key = keys[i];
  158. objectValue = _sessionItems[key];
  159. if (objectValue != null)
  160. {
  161. type = objectValue.GetType();
  162. }
  163. else
  164. {
  165. type = typeof(object);
  166. }
  167. dict.Add(key, new SaveValue { Value = objectValue, Type = type });
  168. }
  169.  
  170. SessionStateItem item = new SessionStateItem { Dict = dict, Timeout = this._timeout };
  171.  
  172. return JsonConvert.SerializeObject(item);
  173. }
  174.  
  175. public static RedisSessionState FromJson(string json)
  176. {
  177. if (string.IsNullOrEmpty(json))
  178. {
  179. return null;
  180. }
  181. try
  182. {
  183. SessionStateItem item = JsonConvert.DeserializeObject<SessionStateItem>(json);
  184.  
  185. SessionStateItemCollection collections = new SessionStateItemCollection();
  186.  
  187. SaveValue objectValue = null;
  188. //2016-09-04解决读取出来的值 没有类型的问题
  189. JsonSerializer serializer = new JsonSerializer();
  190. StringReader sr = null;
  191. JsonTextReader tReader = null;
  192.  
  193. foreach (KeyValuePair<string, SaveValue> kvp in item.Dict)
  194. {
  195. objectValue = kvp.Value as SaveValue;
  196. if (objectValue.Value == null)
  197. {
  198. collections[kvp.Key] = null;
  199. }
  200. else
  201. {
  202. if (!IsValueType(objectValue.Type))
  203. {
  204. sr = new StringReader(objectValue.Value.ToString());
  205. tReader = new JsonTextReader(sr);
  206. collections[kvp.Key] = serializer.Deserialize(tReader, objectValue.Type);
  207. }
  208. else
  209. {
  210. collections[kvp.Key] = objectValue.Value;
  211. }
  212. }
  213. }
  214.  
  215. return new RedisSessionState(collections, null, item.Timeout);
  216. }
  217. catch
  218. {
  219. return null;
  220. }
  221. }
  222.  
  223. /// <summary>
  224. /// 判断是否为值类型
  225. /// </summary>
  226. /// <param name="type">Type</param>
  227. /// <returns></returns>
  228. public static bool IsValueType(Type type)
  229. {
  230. if (type.IsValueType)
  231. {
  232. return true;
  233. }
  234. //基础数据类型
  235. if (type == typeof(string) || type == typeof(char)
  236. || type == typeof(ushort) || type == typeof(short) || type == typeof(uint) || type == typeof(int)
  237. || type == typeof(ulong) || type == typeof(long) || type == typeof(double) || type == typeof(decimal)
  238. || type == typeof(bool)
  239. || type == typeof(byte))
  240. {
  241. return true;
  242. }
  243. //可为null的基础数据类型
  244. if (type.IsGenericType && !type.IsGenericTypeDefinition)
  245. {
  246. Type genericType = type.GetGenericTypeDefinition();
  247.  
  248. if (Object.ReferenceEquals(genericType, typeof(Nullable<>)))
  249. {
  250. var actualType = type.GetGenericArguments()[0];
  251. return IsValueType(actualType);
  252.  
  253. }
  254. }
  255. return false;
  256. }
  257. }

  

电商系统架构总结2(Redis)的更多相关文章

  1. 电商系统架构总结1(EF)

    最近主导了一个电商系统的设计开发过程,包括前期分析设计,框架搭建,功能模块的具体开发(主要负责在线支付部分),成功上线后的部署维护,运维策略等等全过程. 虽然这个系统不是什么超大型的电商系统 数亿计的 ...

  2. 电商系统架构总结4(webapi 版本控制)

    为了 顺利迭代升级,web api 在维护过程是不断升级的,但用户是不能强迫他们每次都跟随你去升级,这样会让用户不胜其烦.为了保证不同版本的客户端能同时兼容,在web api接口上加入版本控制就很有必 ...

  3. 电商系统架构总结3(webapi授权机制)

    三 Web API 授权方式 web api的客户端,包括 android,ios,h5,自然对访问权限要加上授权机制.对于h5,要求把h5站点和web api部署在同一个域名下,然后对web api ...

  4. SpringBoot+Security+MyBatis+ES+MQ+Redis+Docker+Vue的电商系统

    今天鹏哥给大家推荐的项目是一套电商系统,包括前台商城系统及后台管理系统,基于SpringBoot+MyBatis实现. 前台商城系统包含首页门户.商品推荐.商品搜索.商品展示.购物车.订单流程.会员中 ...

  5. 电商系统的演变可以看出架构演变 Dubbo入门 远程过程调用 需要解决的问题

    Dubbo入门---搭建一个最简单的Demo框架 - CSDN博客 https://blog.csdn.net/noaman_wgs/article/details/70214612 Dubbo背景和 ...

  6. 属性 每秒10万吞吐 并发 架构 设计 58最核心的帖子中心服务IMC 类目服务 入口层是Java研发的,聚合层与检索层都是C语言研发的 电商系统里的SKU扩展服务

    小结: 1. 海量异构数据的存储问题 如何将不同品类,异构的数据统一存储起来呢? (1)全品类通用属性统一存储: (2)单品类特有属性,品类类型与通用属性json来进行存储: 2. 入口层是Java研 ...

  7. 通过Dapr实现一个简单的基于.net的微服务电商系统

    本来想在Dpar 1.0GA时发布这篇文章,由于其他事情耽搁了放到现在.时下微服务和云原生技术如何如荼,微软也不甘示弱的和阿里一起适时推出了Dapr(https://dapr.io/),园子里关于da ...

  8. 通过Dapr实现一个简单的基于.net的微服务电商系统(十)——一步一步教你如何撸Dapr之绑定

    如果说Actor是dapr有状态服务的内部体现的话,那绑定应该是dapr对serverless这部分的体现了.我们可以通过绑定极大的扩展应用的能力,甚至未来会成为serverless的基础.最开始接触 ...

  9. 集DDD,TDD,SOLID,MVVM,DI,EF,Angularjs等于一身的.NET(C#)开源可扩展电商系统–Virto Commerce

    今天一大早来看到园友分享的福利<分享一个前后端分离方案源码-前端angularjs+requirejs+dhtmlx 后端asp.net webapi>,我也来分享一个吧.以下内容由笔者写 ...

随机推荐

  1. Python基础_私有变量访问限制

    Python内置了一些特殊变量,以前后上下划线标注,同时我们自己要想定义一些变量,不想让外部访问,又该怎么做呢?更多内容请参考:Python学习指南 访问限制 在class内部,可以有属性和方法,而外 ...

  2. 读懂 PetaLinux:让 Linux 在 Zynq 上轻松起“跑”(转)

    对于Zynq这样一个“ARM+可编程逻辑”异构处理系统我们已经不陌生,其创新性大家也有目共睹.不过想要让更多的应用享受到这一“创新”带来的红利,让其真正“落地”则需要大量系统性的工作,去营造一个完善的 ...

  3. win7重装系统笔记

    制作U盘启动盘:链接 原文链接:链接 开机进入bios界面(华硕:F2) 按方向左右键进入:Boot选项,将“Lunch CSM”设置为“Enabled” 方向键选择“Security”,将“Secu ...

  4. Linux vi文本编辑器

    vi文本编辑器 1.最基本用法 vi  somefile.4 1/ 首先会进入“一般模式”,此模式只接受各种命令快捷键,不能编辑文件内容 2/ 按i键,就会从一般模式进入编辑模式,此模式下,敲入的都是 ...

  5. [视频播放] M3U8文件格式说明

    M3U文件中可以包含多个tag,每个tag的功能和属性如下: #EXTM3U 每个M3U文件第一行必须是这个tag,请标示作用 #EXT-X-MEDIA-SEQUENCE:140651513 每一个m ...

  6. ALGO-152_蓝桥杯_算法训练_8-2求完数

    记: 掌握完数的概念 AC代码: #include <stdio.h> int main(void) { int i,j,sum; ; i <= ; i ++) { sum = ; ...

  7. ghost之后仍然中病毒----与病毒的斗争

    ghost之后仍然中病毒----与病毒的斗争我的电脑系统是XP,从来都没有安装任何杀毒软件,所有的软件都是安装在C盘的,感觉系统卡顿就用Windows一键还原(基于DOS下的ghost)还原一下,一直 ...

  8. 2、以自定义struct或struct指针作为map的Key

    若干问题: struct Node { int k, b; friend bool operator <(Node a, Node b) { return a.k < b.k; } }no ...

  9. 函数,lambda函数,递归函数,内置函数(map,filter),装饰器

    1. 集合 主要作用: 去重 关系测试, 交集\差集\并集\反向(对称)差集 2. 元组 只读列表,只有count, index 2 个方法 作用:如果一些数据不想被人修改, 可以存成元组,比如身份证 ...

  10. opengl 入门浅学(一)

    因为要做图形学的实验,又是要以OPENGL为基础,所以就稍微在网上查了一些资料. 我是带着目的去学习的,所以就没有打基础之类的学很深,浅尝. 今天试着搭简单框架,画出一个图形.大神请出门左转. #in ...