天天看点

CYQ.Data V5 分布式缓存MemCached应用开发介绍前言框架集成MemCache框架的代码重构思维框架里使用MemCache功能的演示总结

今天大伙还在热议关于.net core的东西,我只想说一句:在.net 跨平台叫了这么多年间,其实人们期待的是一个知名的跨平台案例,而不是一堆能跨平台的消息。

好,回头说说框架: 

在框架完成数据库读写分离的功能后,开始回想起2年前所构思的:关于框架集成分布式缓存memcached的实现。

之前一直没动手,是因为思路比较飘,秉承着框架应该简单干净轻量引用无依赖和使用不复杂的思维:

看着memcached的服务端协议,整天思考着自己用socket写一个客户端。

后来可能是没激情,迟迟没动手。

又在某个时刻,想过偷懒,想动态反射memcached.clientlibrary库,但一看到它竟然关联了四个dll,我那纯洁的心就有点抗拒它了。

所以日子就这样飘来复去,这个功能被想起又遗忘......

这几天,翻看了往昔下载的的相关源码中,有个叫beitmemcached,扫了一下源码,发现简单轻量没外部引用。

于是就开始改造,并测试了一下,没发现问题,于是开始思考集成的方式。

框架的缓存类本来很孤单,只有一个:cachemanage.cs

现在改造完,多了10个类,编绎后dll大小多了30k,说多了也是泪~:

CYQ.Data V5 分布式缓存MemCached应用开发介绍前言框架集成MemCache框架的代码重构思维框架里使用MemCache功能的演示总结

1:原有的cachemanage类变更为localcache。

2:cachemanage类变更为抽象类

3:新增memcache,并和localcache一并实现cachemanage抽象类方法。

以上三步,就是核心的思维。

1:从原有的cachemanage里提取接口icache

2:cachemanage改名webcache并继承自icache(由于提口提取自本类,所以代码不需要怎么调整)

3:新建memcache继承并实现icache接口。

4:新建cachemanage类,并从webcache处把instance实例属性移到此类中,并返回对应的icache接口。

因为原来的代码有一小部分是这样写的:cachemanage cache=cachemanage.instance;

因为返回的类型不一样,原有代码受到影响,必须改成:icache cache=cachemanage.instance。

为了避开影响不用改动代码,所以最终改用定案里抽象类和抽象方法实现。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

<code>/// &lt;summary&gt;</code>

<code>    </code><code>/// 全局缓存类</code>

<code>    </code><code>/// &lt;/summary&gt;</code>

<code>    </code><code>/// &lt;example&gt;&lt;code&gt;</code>

<code>    </code><code>/// 使用示例:</code>

<code>    </code><code>/// 实例化: cachemanage cache=cachemanage.instance;</code>

<code>    </code><code>/// 添加:   cache.add("路过秋天",new mdatatable);</code>

<code>    </code><code>/// 判断:   if(cache.contains("路过秋天"))</code>

<code>    </code><code>///          {</code>

<code>    </code><code>/// 获取:       mdatatable table=cache.get("路过秋天") as mdatatable;</code>

<code>    </code><code>///          }</code>

<code>    </code><code>/// &lt;/code&gt;&lt;/example&gt;</code>

<code>    </code><code>public</code> <code>abstract</code> <code>class</code> <code>cachemanage</code>

<code>    </code><code>{</code>

<code>        </code><code>#region 对外实例</code>

<code>        </code><code>/// &lt;summary&gt;</code>

<code>        </code><code>/// 返回唯一实例(根据是否配置appconfig.cache.memcacheservers的服务器决定启用本地缓存或分布式缓存)</code>

<code>        </code><code>/// &lt;/summary&gt;</code>

<code>        </code><code>public</code> <code>static</code> <code>cachemanage instance</code>

<code>        </code><code>{</code>

<code>            </code><code>get</code>

<code>            </code><code>{</code>

<code>                </code><code>if</code> <code>(</code><code>string</code><code>.isnullorempty(appconfig.cache.memcacheservers))</code>

<code>                </code><code>{</code>

<code>                    </code><code>return</code> <code>localshell.instance;</code>

<code>                </code><code>}</code>

<code>                </code><code>else</code>

<code>                    </code><code>return</code> <code>memshell.instance;</code>

<code>            </code><code>}</code>

<code>        </code><code>}</code>

<code>        </code><code>/// 单机本地缓存</code>

<code>        </code><code>public</code> <code>static</code> <code>cachemanage localinstance</code>

<code>                </code><code>return</code> <code>localshell.instance;</code>

<code>        </code><code>class</code> <code>localshell</code>

<code>            </code><code>internal</code> <code>static</code> <code>readonly</code> <code>localcache instance = </code><code>new</code> <code>localcache();</code>

<code>        </code><code>class</code> <code>memshell</code>

<code>            </code><code>internal</code> <code>static</code> <code>readonly</code> <code>memcache instance = </code><code>new</code> <code>memcache();</code>

<code>        </code><code>#endregion</code>

<code>        </code><code>/// 添加一个cache对象</code>

<code>        </code><code>public</code> <code>abstract</code> <code>void</code> <code>add(</code><code>string</code> <code>key, </code><code>object</code> <code>value);</code>

<code>        </code><code>public</code> <code>abstract</code> <code>void</code> <code>add(</code><code>string</code> <code>key, </code><code>object</code> <code>value, </code><code>double</code> <code>cacheminutes);</code>

<code>        </code><code>public</code> <code>abstract</code> <code>void</code> <code>add(</code><code>string</code> <code>key, </code><code>object</code> <code>value, </code><code>string</code> <code>filename);</code>

<code>        </code><code>public</code> <code>abstract</code> <code>void</code> <code>add(</code><code>string</code> <code>key, </code><code>object</code> <code>value, </code><code>string</code> <code>filename, </code><code>double</code> <code>cacheminutes);</code>

<code>        </code><code>public</code> <code>abstract</code> <code>void</code> <code>add(</code><code>string</code> <code>key, </code><code>object</code> <code>value, </code><code>string</code> <code>filename, </code><code>double</code> <code>cacheminutes, cacheitempriority level);</code>

<code>        </code><code>public</code> <code>abstract</code> <code>dictionary&lt;</code><code>string</code><code>, cachedependencyinfo&gt; cacheinfo { </code><code>get</code><code>; }</code>

<code>        </code><code>public</code> <code>abstract</code> <code>mdatatable cachetable { </code><code>get</code><code>; }</code>

<code>        </code><code>/// 清除所有缓存</code>

<code>        </code><code>public</code> <code>abstract</code> <code>void</code> <code>clear();</code>

<code>        </code><code>public</code> <code>abstract</code> <code>bool</code> <code>contains(</code><code>string</code> <code>key);</code>

<code>        </code><code>/// 获和缓存总数</code>

<code>        </code><code>public</code> <code>abstract</code> <code>int</code> <code>count { </code><code>get</code><code>; }</code>

<code>        </code><code>/// 获得一个cache对象</code>

<code>        </code><code>public</code> <code>abstract</code> <code>object</code> <code>get(</code><code>string</code> <code>key);</code>

<code>        </code><code>public</code> <code>t get&lt;t&gt;(</code><code>string</code> <code>key)</code>

<code>            </code><code>object</code> <code>o = get(key);</code>

<code>            </code><code>if</code> <code>(o != </code><code>null</code><code>)</code>

<code>                </code><code>type t = </code><code>typeof</code><code>(t);</code>

<code>                </code><code>try</code>

<code>                    </code><code>return</code> <code>(t)statictool.changetype(o, t);</code>

<code>                </code><code>catch</code> <code>(exception err)</code>

<code>                    </code><code>log.writelogtotxt(err);</code>

<code>                    </code><code>return</code> <code>default</code><code>(t);</code>

<code>            </code><code>return</code> <code>default</code><code>(t);</code>

<code>        </code><code>/// 获取目标的文件依赖是否发生更改</code>

<code>        </code><code>/// &lt;param name="key"&gt;&lt;/param&gt;</code>

<code>        </code><code>/// &lt;returns&gt;&lt;/returns&gt;</code>

<code>        </code><code>public</code> <code>abstract</code> <code>bool</code> <code>getfiledependencyhaschanged(</code><code>string</code> <code>key);</code>

<code>        </code><code>/// 获取缓存对象是否被手工标识为已更改</code>

<code>        </code><code>public</code> <code>abstract</code> <code>bool</code> <code>gethaschanged(</code><code>string</code> <code>key);</code>

<code>        </code><code>/// 还可用的缓存字节数</code>

<code>        </code><code>public</code> <code>abstract</code> <code>long</code> <code>remainmemorybytes { </code><code>get</code><code>; }</code>

<code>        </code><code>/// 还可用的缓存百分比</code>

<code>        </code><code>public</code> <code>abstract</code> <code>long</code> <code>remainmemorypercentage { </code><code>get</code><code>; }</code>

<code>        </code><code>/// 删除一个cache对象</code>

<code>        </code><code>public</code> <code>abstract</code> <code>void</code> <code>remove(</code><code>string</code> <code>key);</code>

<code>        </code><code>/// 缓存设置:有则更新,无则添加</code>

<code>        </code><code>public</code> <code>abstract</code> <code>void</code> <code>set(</code><code>string</code> <code>key, </code><code>object</code> <code>value);</code>

<code>        </code><code>public</code> <code>abstract</code> <code>void</code> <code>set(</code><code>string</code> <code>key, </code><code>object</code> <code>value, </code><code>double</code> <code>cacheminutes);</code>

<code>        </code><code>/// 手动对缓存象标识为已更改</code>

<code>        </code><code>public</code> <code>abstract</code> <code>void</code> <code>setchange(</code><code>string</code> <code>key, </code><code>bool</code> <code>ischange);</code>

<code>        </code><code>/// 更新缓存,缓存存在则更更新,不存在则跳过</code>

<code>        </code><code>public</code> <code>abstract</code> <code>void</code> <code>update(</code><code>string</code> <code>key, </code><code>object</code> <code>value);</code>

<code>        </code><code>public</code> <code>abstract</code> <code>string</code> <code>workinfo { </code><code>get</code><code>; }</code>

<code>    </code><code>}</code>

这里新增对外一个属性:localinstance,是因为一但配置了appconfig.cache.memcacheservers后:

原有的本机缓存就自动切换到分布式缓存,为了使用本机缓存依旧可以使用,所以提供localinstance属性。

一开始是对外三个:instance(自动切换型)、localinstance、meminstance。

大伙可以思考一下,为什么meminstance被去掉了?感觉有点说不清道不明的感觉。

由于localcache是变更名称自cachemanage,而cachemanage在以前文章贴过源码,所以不重复了。

CYQ.Data V5 分布式缓存MemCached应用开发介绍前言框架集成MemCache框架的代码重构思维框架里使用MemCache功能的演示总结
CYQ.Data V5 分布式缓存MemCached应用开发介绍前言框架集成MemCache框架的代码重构思维框架里使用MemCache功能的演示总结

讲完实现的过程和贴完源码,下面讲一下使用过程了:

服务端的文件是这样的:

CYQ.Data V5 分布式缓存MemCached应用开发介绍前言框架集成MemCache框架的代码重构思维框架里使用MemCache功能的演示总结

运行后的服务是这样的,这里开了两个服务进程,分别对应:11211和11212端口:

CYQ.Data V5 分布式缓存MemCached应用开发介绍前言框架集成MemCache框架的代码重构思维框架里使用MemCache功能的演示总结
CYQ.Data V5 分布式缓存MemCached应用开发介绍前言框架集成MemCache框架的代码重构思维框架里使用MemCache功能的演示总结

原有的使用方式不变,只是增加了一行配置,就自动切换到分布式了,是不是从单机过渡到分布式太简单了。

通常我们不在代码里配置,而是配置在:

CYQ.Data V5 分布式缓存MemCached应用开发介绍前言框架集成MemCache框架的代码重构思维框架里使用MemCache功能的演示总结

运行的结果是这样的:

CYQ.Data V5 分布式缓存MemCached应用开发介绍前言框架集成MemCache框架的代码重构思维框架里使用MemCache功能的演示总结

使用此框架,不管是进化到数据库读写分离,还是演进到分布式缓存,整个架构的升级过程,只需增加1行配置文件。

几年前就一直在构思,浮浮沉沉地随着框架的演进,如今顺水推舟地实现了,想想都觉得有点不可思议。

另外最后top150大神群里,有人问我,最近写的文章有人打赏么?我只弱弱的回了一句:还没。

本文原创发表于博客园,作者为路过秋天,原文链接:http://www.cnblogs.com/cyq1162/p/5617761.html

继续阅读