缓存memcachedd 可以用来缓存 json 吗

看看mina和memcached的联姻(适合不同语言客户端,高并发?) - 求贤若渴, 礼贤下士 - ITeye技术网站
博客分类:
[size=medium]/**
* 作者:张荣华
看看mina和memcached的联姻
先来解释一下这两个东东的身世
Mina,是什么?
Minan是一个network 应用框架,她能很方便的帮助用户开发出高性能和高可扩展性的网络应用程序。官方地址请看:
Memcached是什么?
memcached一个remote cache,它只提供数据存储服务,不过它得java客户端比较不错,还有很多其他语言的客户端,也就是说其周边比较丰富。Memcached的文章太多了,随便一搜一大堆。
现在相信大家对这两个东西有点了解了,接着转入正题吧,我估计猛一看标题,很多童鞋估计都有那么一点云中子的感觉(因为云中子一般在云里或者雾里,所以云中子==云里雾里),从上面的解释来看mina和memcached好像是八竿子打不到一起去的东西。这两个东西怎么能走到一起呢。先看他们能解决什么样的需求。
需求:我们知道,所有的互联网服务几乎都离不开connection这个东东,比如我们打开一个网页,从浏览器发起请求到tomcat接受请求并返回数据,这个过程就开启了一个短连接,数据返回之后这个连接就关闭了,也就是说每个请求其实都是一个新连接的开启和关闭。然后,tomcat中的application向数据库发送一个查询语句,它需要从连接池中拿到一个connection,这个connection一直在pool中,显然这个connection是一个长连接,由此可见一次请求,从浏览器到db再到浏览器既经过了短连接有经过了长连接,我们的生活是离不开连接的。
上面说的这个例子是一个请求的最简单模型,因为我们的application可不只是依赖数据库,尤其在互联网应用中,通常我们的application还依赖于其他的server,比如说我们的互联网应用可能还连接着memcached server,通常,这里也有一个连接池,维护着一堆长连接,那么结束了吗,不,再通常我们的application还依赖于其他的application。好及了,一个相对有点复杂的应用网络,接着往下说,快到重点了
重点:
一般情况下,我们的application依赖于其他application的的时候我们会直接使用http协议,或者再次封装过的http协议(诸如webservice之流),而且这种情况是大多数情况,但是不是全部情况,因为在互联网上我们会遇到各种各样的需求。因为http连接是短连接,每次发起连接的3次握手不可避免,这是造成其并发量不高的重要原因之一(有的人也许会说,即使http并发高有什么用,你的application还是撑不住,但是我想说的是不是所有的应用都是这样的,只是你没有遇到过而已)。那么假设我有一个数据中心,这个数据中心可以提供common数据的服务,这些common的数据会被网站的各个地方获取,这些common的数据之间可能还有一些计算,我可以通过请求的参数来执行对应的操作,比如查询,统计等等(哇,看来能有效的降低数据库的压力啊),那么看来memcached是不行了(不能定制计算),只能自己写这样的应用了,不过以什么样的形势发布接口呢,短连接不行,并发量有限,只能长连接,还要考虑到一点,我的服务的客户端是不定的,有可能是php,也有可能是java,也有可能是python,也有可能是ruby,如何是好啊。
首先长连接是不二选择,高并发,高连接数是我们最中意的,有了这两个特性,我们这个application就可以被其他很多app使用了,就象共享memcached server一样。
其次支持多客户端语言最好是能够有效利用现有资源,比如说不需要自己去开发客户端。
这时候memcached就可以抱着mina出场了。理由:
1 Memcached有众多的客户端,可谓周边齐全,看来非它莫数。
2 mina可以非常方便的开发出server端程序,好姑娘啊。
来吧,看看最简单的示例:
Server端主类:
import java.io.IOE
import java.net.InetSocketA
import java.nio.charset.C
import org.mon.ByteB
import org.mon.IoA
import org.mon.SimpleByteBufferA
import org.apache.mina.filter.codec.ProtocolCodecF
import org.apache.mina.filter.codec.textline.TextLineCodecF
import org.apache.mina.transport.socket.nio.SocketA
import org.apache.mina.transport.socket.nio.SocketAcceptorC
* @author ahuaxuan(aaron zhang)
* @version $Id$
public class MinaServer {
private static final int PORT = 11211;
public static void main(String[] args) throws IOException {
// code will go here next
ByteBuffer.setUseDirectBuffers(false);
ByteBuffer.setAllocator(new SimpleByteBufferAllocator());
IoAcceptor acceptor = new SocketAcceptor();
SocketAcceptorConfig cfg = new SocketAcceptorConfig();
cfg.getFilterChain().addLast("logger", new LoggingFilter());
cfg.getFilterChain().addLast(
new ProtocolCodecFilter(new TextLineCodecFactory(Charset
.forName("UTF-8"))));
acceptor.bind(new InetSocketAddress(PORT), new ServerHandler(), cfg);
System.out.println("------------ Mina Server start up -----------");
}
这样,启动这个main方法,就可以建立一个socket server的实例了,欢迎大家来连!!!
相当简单啊,再看看一个重要的ServerHandler类
其中有一个重要的方法:
public void messageReceived(IoSession session, Object msg) throws Exception {
String str = msg.toString();
String[] parts = str.split(" ");
if (parts != null && "get".equals(parts[0])) {
StringBuilder sb = new StringBuilder();
sb.append("VALUE").append(" key ");
sb.append("1").append(" ");
sb.append(str.length()).append(" \r\n ");
sb.append(str + "\r\n").append("");
//看看这里吧
session.write(sb.toString());
session.write("END\r\n");
System.out.println("Message written..." + sb.toString());
throw new IOException("unsupportoperation");
}
哟,这么多\r\n,还有”END\r\n”这种东西?不好意思,这个是memcached协议定的我也没有办法(说到这里大家终于知道了本文其实只不过是用mina来实现memcached协议而已,前面被我那么多废话解释弄晕了吧,嘿嘿)。
看到这里,我想要提醒一下,msg通常是这样的get aaabbbccc,其中aaabbbccc是key,但是用在我们自己的server上,它就可以不是key了,比如说它可以是/getDistrict.do?name=xx&cc=yy`````````,server拿到这样的字符串之后,一解析就知道客户端要什么了,那么就可以返回数据了,是我的话我会用json序列化我的对象,然后返回。只是一定要告诉客户端我的数据包括哪些内容,又快并发又高(再次提醒,我的application可以高并行计算,比如说大多数数据都在内存中哦),hoho,而且任何一个客户端语言都可以享受这种服务哦。
&&&& 好了,数据成功返回之后,为了让memcached的客户端能够成功解析,我们必须使用memcacached协议,看一段get协议的解释吧(目前主要是使用这个):
一行取回命令如下:
get &key&*\r\n
&key&* 表示一个或多个键值,由空格隔开的字串
这行命令以后,客户端的等待0个或多个项目,每项都会收到一行文本,然后跟着数据区块。所有项目传送完毕后,服务器发送以下字串:
"END\r\n"来指示回应完毕。
服务器用以下形式发送每项内容:VALUE &key& &flags& &bytes&\r\n
&data block&\r\n
&key& 是所发送的键名
- &flags& 是存储命令所设置的记号
&bytes& 是随后数据块的长度,*不包括* 它的界定符“\r\n”
- &data block& 是发送的数据如果在取回请求中发送了一些键名,而服务器没有送回项目列表,这意味着服务器没这些键名(可能因为它们从未被存储,或者为给其他内容腾出空间而被删除,或者到期,或者被已客户端删除)。
这样就可以了,注意,这里只不过是很简单的测试代码(正式代码不便给出),也只不过是提供一个思路而已,大家如果也需要用到这样的场景可以沿着这个思路走下去。
声明:由于ahuaxuan水平有限,文中难免有不妥之处,希望大家不吝赐教。
ps:如果你没有memcached的客户端,最快的见效的是通过telnet,在windows console里输入telnet localhost 11211,就可以了
[/size]
描述: 源代码
下载次数: 887
论坛回复 /
(36 / 27712)
memcached没有接触过,所以不是很明白楼主这种机制的用处何在。
不过这段时间做的一个项目里面遇到一个问题,大概的场景是这样的,由于客户端太多,因此我在服务端之前加了LVS来做负载均衡,但是这样就遇到了一个问题,客户端连到哪台服务器不是固定的,同时又有另外一个应用(同一个系统内的应用,但不是服务端)需要发消息给客户端,这个应用与各个服务端之间是通过MQ队列来通信的,每次它需要发消息给客户端,就发一个消息到队列里面,每个服务端都阻塞等待队列上消息的到达,因此应用发出来的消息被哪个服务端取到是随机的,但某个服务端取到消息之后,会先检查自己本机上的连接会话表,检查相应的客户端是否连接到本机,如果没有,就需要将消息转发给其他服务端。
最后实现的时候采用了Sun的Shoal来实现分布式的连接会话表,每次在本机的会话表插入记录的时候,会同时在Shoal维持的分布式缓存中插入相应的一条记录,当服务端在本机上的会话表中查不到相应的客户端时,会到Shoal维持的分布式缓存中去查找记录,若是找到记录,则将消息发给客户端当前连接到的那台服务端。
不知道大家有没有用过Shoal?我之所以用它,是因为它是Sun的Glassfish服务器的集群的实现基础,感觉应该性能不会太差,不过在网上貌似找不到测试评论,目前我自己也没有对Shoal的分布式缓存的性能做过测试。
刚搜了一下memcached的资料,感觉memcached也可以用在我上面的解决方案中用来替代Shoal。有没有什么资料对比过memcached和Shoal?
另外,对于我遇到的这个问题,我总感觉我这种解决方案不是太好,不知各位有没有遇到过相类似的场景,有没有什么更好的解决方案呢?
很久的老帖子了,刚才不小心翻到,忍不住要发言,虽然现在时过境迁,已经无效了。
你遇到的这种需求其实与网络底层协议是一致的,譬如局域网的广播机制。
这本质上是个寻址问题,在IP协议里就要解决。
方案如下:发送消息的应用主动推送到所有服务器,服务器接收到消息后比对自己的连接表,如果不存在对应客户则马上丢弃信息,有则响应一下。就这么简单。
bingobird 写道
最后那个性能非常关键,之前我们做过测试,cache型的存取1K的数据耗时在0.7ms,而且与数据包大小呈线性关系。楼主的0.2ms不知是在哪个场景下(请求答应报文大小?)
很显然,我这里出来的是并发之后的结果,并不是单次请求的结果,如果1ms内有5个请求都过来,每个请求实际的请求时间是1ms,那么也就是说1ms之后,5个请求都返回了,所以,平均下来一个请求就是0.2ms了
你说的cache型存取用的是什么cache,是local cache还是memcached之类内,而且你这个数据是怎么看出来的,单线程计算平均还是通过jprofile之类的内,如果是后者,那么你这个测试结果就是不准确的,jprofile在测试的时候速度会降低很多
0.7ms是采用memcache在多线程情况下的处理能力(pc),测试结果是通过简单地压力测试取平均值的做法。即每秒处理1400左右的请求(包长1k)。当报文长度为100字节,每秒处理数也会上升到1w。
因此我对ahuaxuan测试用例中的报文长度比较关心。如果0.2ms是基于100字节以上的报文交换,那还是不错的。
bingobird 写道
最后那个性能非常关键,之前我们做过测试,cache型的存取1K的数据耗时在0.7ms,而且与数据包大小呈线性关系。楼主的0.2ms不知是在哪个场景下(请求答应报文大小?)
很显然,我这里出来的是并发之后的结果,并不是单次请求的结果,如果1ms内有5个请求都过来,每个请求实际的请求时间是1ms,那么也就是说1ms之后,5个请求都返回了,所以,平均下来一个请求就是0.2ms了
你说的cache型存取用的是什么cache,是local cache还是memcached之类内,而且你这个数据是怎么看出来的,单线程计算平均还是通过jprofile之类的内,如果是后者,那么你这个测试结果就是不准确的,jprofile在测试的时候速度会降低很多
我倒是觉得,一个重要的测试数据标准是这个Server在同1秒内能够接受的最大连接数。
最后那个性能非常关键,之前我们做过测试,cache型的存取1K的数据耗时在0.7ms,而且与数据包大小呈线性关系。楼主的0.2ms不知是在哪个场景下(请求答应报文大小?)
很显然,我这里出来的是并发之后的结果,并不是单次请求的结果,如果1ms内有5个请求都过来,每个请求实际的请求时间是1ms,那么也就是说1ms之后,5个请求都返回了,所以,平均下来一个请求就是0.2ms了
你说的cache型存取用的是什么cache,是local cache还是memcached之类内,而且你这个数据是怎么看出来的,单线程计算平均还是通过jprofile之类的内,如果是后者,那么你这个测试结果就是不准确的,jprofile在测试的时候速度会降低很多
fanzaiqiang 写道从memecached server中存取数据都非常快速,因而连接都很短暂,短暂的连接可以满足较高的并发
你这个结论是从哪里得出来得?
如果是短连接每次请求都要开连接,你觉得并发会高吗,比如你访问tomcat,你得tomcat支持多少
fanzaiqiang 写道
如果想在服务器端支持条件查询,个人觉得这种方式对查询的支持毕竟有限,还不如推翻memcached,引入内存数据库机制实现分布式缓存,并支持强大的查询(SQL).
我不就是抛弃了memcached server吗(其实不是抛弃,而是不同得场景选择不同得技术而已)?
难道我说得不够清楚,有空再写一篇文章把
--------------------------------------------
随便提供一下我得测试结果(基础框架:xwork2.0+mina1.17+spring2.5)
每秒钟支持得请求数量为5500次(而且我觉得测试得客户端不够,否则这个数字还可以更大),也就是平均0.2ms就可以处理返回,这个统计是客户端得统计,也就是包括网络消耗在内平均一个请求是0.2ms
最后那个性能非常关键,之前我们做过测试,cache型的存取1K的数据耗时在0.7ms,而且与数据包大小呈线性关系。楼主的0.2ms不知是在哪个场景下(请求答应报文大小?)
从memecached server中存取数据都非常快速,因而连接都很短暂,短暂的连接可以满足较高的并发
你这个结论是从哪里得出来得?
如果是短连接每次请求都要开连接,你觉得并发会高吗,比如你访问tomcat,你得tomcat支持多少
fanzaiqiang 写道
如果想在服务器端支持条件查询,个人觉得这种方式对查询的支持毕竟有限,还不如推翻memcached,引入内存数据库机制实现分布式缓存,并支持强大的查询(SQL).
我不就是抛弃了memcached server吗(其实不是抛弃,而是不同得场景选择不同得技术而已)?
难道我说得不够清楚,有空再写一篇文章把
--------------------------------------------
随便提供一下我得测试结果(基础框架:xwork2.0+mina1.17+spring2.5)
每秒钟支持得请求数量为5500次(而且我觉得测试得客户端不够,否则这个数字还可以更大),也就是平均0.2ms就可以处理返回,这个统计是客户端得统计,也就是包括网络消耗在内平均一个请求是0.2ms
memcached的java客户端好像可以设置连接池呀!这个连接池里的东西不就是长连接吗?
连接池的并发性能应该比不上NIO这种机制的并发性能。
dennis_zane 写道nickcen 写道感觉就是用nio实现了一个memcache的java client吧。跟多语言一点关系都没有把。
是吗?你认真看了吗?
楼主这个思路可以作为WS、REST的替代品,做内部应用(异构同构皆可)间的交互。
多语本来就是memcache自己就能做到的。需要mina掺和吗?
内部应用会有很多异构吗?而且不要把Cache太泛化了,这东西跟WS,REST不是一个概念,不要玩弄概念了。
无语了,您想争论至少搞明白楼主在说什么?太无语了。人家根本不是在说cache,只是借memcached协议这个壳。
对的,是我看错了,这是服务器端,你用mina实现了一个能响应memcache get请求的server。你的这个server能比memcached的性能好?有report?
如果你有兴趣,我当然愿意和你讨论下去,不过前提是你需要理解我在说什么,否则就讨论不到一块儿去了。
引用
首先谢谢大家的回帖,该贴质量的提高正式得益于你们的回帖,下面我进一步阐述我的观点
codeutil 写道
已经有现成的jmemcached,也是基于mina:
/projects/jmemcached
linzongkao 写道
已经有现成的GMemcached,是基于Grizzly:
/p/gmemcached/
谢谢两位给出jmemcached和gmemcached的介绍连接,让我们开阔了眼界,但是我的想法不是完全再次实现一个memcached server,因为我觉得这样做意义不大,现有的c版本的memcached 的server已经是非常的优秀了。只不过memcached的server不能适合一些特殊场景,就是我文中提到的那些,所以我并不是实现了一个 memcached server,我只是利用memcached的协议而已,这样做的好处是能利用memcached的丰富的周边(比如说现成的多语言客户端)。
从我上面这段回帖就已经可以看出,本文并不是要实现一个一摸一样的memcached server,我已经说的很清楚很明了,还要我怎么说。
javaeyename 写道memcached的java客户端好像可以设置连接池呀!这个连接池里的东西不就是长连接吗?
这篇文章并没有说是开发客户端的东西,跟客户端没有直接联系。
& 上一页 1
浏览: 461774 次
来自: 杭州
优化算法与原来需求不符
生成的area图有时候 标签的数值和图标上看上去的数值不一致。 ...
大神,请教一个问题,按名称排序为何无效,用的2.4.3 XPA ...
改成精确匹配可以了& filter-mapping &g ...
& filter-mapping &memcached 常见问题_百度文库
两大类热门资源免费畅读
续费一年阅读会员,立省24元!
文档贡献者
评价文档:
memcached 常见问题
大小:21.45KB
登录百度文库,专享文档复制特权,财富值每天免费拿!
你可能喜欢2274人阅读
& memcached, Enyim, log4net, Newtonsoft.Json
& &注意Enyim,log4net,memcached的版本,如果与下面不一至,调试运行中有可能出现问题
<span style="color:#.memcached客户端
& &Enyim.Caching.dll &v2.12.0.0
& &Enyim.Caching.Log4NetAdapter.dll &v2.12.0.0
& &log4net.dll & v1.2.10.0
2.memcached服务端
& &memcached-win32 &v1.4.4-14
3.数据输出及提供
& &数据输出&#26684;式:json
& &数据提供:WebService
4.dataSet转json
& &组件:Newtonsoft.Json.dll &v4.0.8.14612&
5.开发工具
& &visual studio 2010
& &开发版本:.net &v3.5
& &运行版本:.net &v2.0.50727
二 memcached安装启动
& memcached.exe -d install
& 服务启动后, memcached 默认使用 64M 内存和 11211 端口作为服务器参数。
& 如果你希望调整参数,请参考: memcached.exe -h
& memcached.exe -m 512 -p 33000 -d start
& -d为守护进程启动
& -m为指定内存大小
& -p指定端口,默认端口11211
3.测试memcached
d:\&telnet localhost 11211 &
add firstKey 0 0 15 &
Hello Memcached &
get firstKey &
VALUE firstKey 0 15 &
Hello Memcached &
三 memcached及log4net配置(Web.config)
&!--配置memcached服务器及log4net日志--&
&configuration&
&configSections&
... 其它配置 --&
&!--log4net日志配置--&
&section name=&log4net& type=&log4net.Config.Log4NetConfigurationSectionHandler,log4net&/&
&!--缓存客户端配置--&
&sectionGroup name=&&&
&section name=&memcached& type=&Enyim.Caching.Configuration.MemcachedClientSection, Enyim.Caching&/&
&section name=&log& type=&Enyim.Caching.Configuration.LoggerSection, Enyim.Caching&/&
&/sectionGroup&
&section name=&memcached& type=&Enyim.Caching.Configuration.MemcachedClientSection, Enyim.Caching&/&
&/configSections&
&!--缓存客户端配置--&
&log factory=&Enyim.Caching.Log4NetFactory, Enyim.Caching.Log4NetAdapter&/&
&memcached&
&add address=&192.168.0.45& port=&11211&/&
&/servers&
&socketPool minPoolSize=&1000& maxPoolSize=&2000& connectionTimeout=&00:00:10& deadTimeout=&00:05:00&/&
&/memcached&
&memcached&
&add address=&192.168.0.45& port=&11211&/&
&/servers&
&socketPool minPoolSize=&1000& maxPoolSize=&2000& connectionTimeout=&00:00:10& deadTimeout=&00:05:00&/&
&/memcached&
&!--log4net日志配置--&
&!--Basic log4net config. Don't forget to call log4net.Config.XmlConfigurator.Configure(); at the start of your app.--&
&level value=&ALL&/&
&appender-ref ref=&RollingLogFileAppender&/&
&appender-ref ref=&ConsoleAppender&/&
&appender-ref ref=&TraceAppender&/&
&logger name=&Enyim.Caching.Memcached.DefaultNodeLocator&&
&level value=&Debug&/&
&logger name=&Enyim.Caching.Memcached.PooledSocket&&
&level value=&Info&/&
&logger name=&Enyim.Caching.Memcached.Protocol&&
&level value=&Info&/&
&logger name=&Membase.VBucketAwareOperationFactory&&
&level value=&Info&/&
&logger name=&Enyim.Caching.Memcached.MemcachedNode&&
&level value=&Info&/&
&appender name=&RollingLogFileAppender& type=&log4net.Appender.RollingFileAppender&&
&param name=&File& value=&LogFiles/&/&
&param name=&AppendToFile& value=&true&/&
&param name=&MaxSizeRollBackups& value=&10&/&
&param name=&StaticLogFileName& value=&false&/&
&param name=&DatePattern& value=&yyyy-MM-dd&.txt&&/&
&param name=&RollingStyle& value=&Date&/&
&layout type=&log4net.Layout.PatternLayout&&
&param name=&ConversionPattern& value=&%d{yyyy-MM-dd HH:mm:ss}[%thread] %-5level %c %L %F - %message%newline&/&
&footer value=&by anyx&/&
&/appender&
&appender name=&ConsoleAppender& type=&log4net.Appender.ConsoleAppender&&
&layout type=&log4net.Layout.PatternLayout,log4net&&
&param name=&ConversionPattern& value=&%d [%t] %-5p %c %m%n&/&
&/appender&
&appender name=&TraceAppender& type=&log4net.Appender.TraceAppender&&
&layout type=&log4net.Layout.PatternLayout,log4net&&
&param name=&ConversionPattern& value=&%d [%t] %-5p %c %m%n&/&
&/appender&
&/log4net&
&!-- 缓存期限 --&
&appSettings&
&add key=&cachingTime& value=&120&/&
&/appSettings&
&!-- 数据库连接 --&
&connectionStrings&
&add name=&dbConnStr& connectionString=&Data Source=APPCUser ID=Password=appuser123;Integrated Security = false& providerName=&System.Data.OracleClient&/&
&/connectionStrings&
&system.web&
&!-- 用于跨域调用 --&
&webServices&
&protocols&
&add name=&HttpGet&/&
&add name=&HttpPost&/&
&/protocols&
&/webServices&
... 其它配置 --&
&/system.web&
... 其它配置 --&
&/configuration&
四 log4net初始化
& 初始化Web.config中配置的log4net
& 在Global.asax下:protected void Application_Start(object sender, EventArgs e)
//log4net初始化
//程序启动加入,在Web.config log4net:RollingLogFileAppender:file对应的日志目录或日志文件
log4net.Config.XmlConfigurator.Configure();
}五 读取写入缓存的类
& & 注意,以下读取写入Memcached是基于memcached v1.4以后的版本
& & 建一个类,用于读取和写入Memcached.public class CachedService
private static MemcachedClient mc = new MemcachedClient();
/// &summary&
/// 从缓存服务器取出数据
/// &/summary&
/// &param name=&key&&&/param&
/// &returns&&/returns&
public static object getObjectFromCached(string key)
Object obj =
IGetOperationResult result = mc.ExecuteGet(key);
if (result.HasValue)
obj = result.V
/// &summary&
/// 存入数据到缓存服务器
/// &/summary&
/// &param name=&key&&&/param&
/// &returns&&/returns&
public static bool setObjectToCached(string key, object obj)
//读取Web.config配置中的缓存时间
double cachintTime = 0;
string ct = System.Configuration.ConfigurationManager.AppSettings[&cachingTime&];
if (!string.IsNullOrEmpty(ct))
cachintTime = Convert.ToDouble(ct);
//缓存数据
IStoreOperationResult result = mc.ExecuteStore(StoreMode.Set, key, obj, DateTime.Now.AddMinutes(cachintTime));
if (result.Success)
string me = result.M
int code = Convert.ToInt32(result.StatusCode);
}六 缓存与数据库
& &取数据首先查看Memcached缓存服务器是否有对应键的数据对象,如果有,就直接取出,如果没有,就从数据库取出,再按相应键存入Memcached.
/// &summary&
/// 每日龙虎榜:最近交易日:缺省数据:分页(缓存服务器)
/// &/summary&
/// &returns&返回Json格式字符串&/returns&
public class SomeClass
public string getSomeData(int start,int limit,string sf,string sr)
if (string.IsNullOrEmpty(sf) || string.IsNullOrEmpty(sr))
//某些参数为空,返回
return &{\&total\&:0,\&rows\&:[]}&; ;
string json = &&;
//缓存服务器唯一标识,命名很重要
//在这里我采用的是查询条件作为缓存标识
string key = &edaylhb:& + start + &:& + limit + &:& + sf + &:& +
//从缓存服务器中取对应key的数据
Object obj = CachedService.getObjectFromCached(key);
if (obj != null)
//缓存服务器中有数据
json = (string)
//缓存服务器中无数据,去数据库取,再保存到缓存服务器
//查询数据库,返回dataset ds
//...各种sql查询
string ds2Str = &&;
//如果ds不为空,转换为Json格式
ds2Str = DbUtil.dataSet2Json(ds);
ds.Dispose();
//拼接成Json格式
if (ds.Tables[0].Rows.Count == 0)
json = &{\&total\&:0,\&rows\&:[]}&;
json = &{\&total\&:& + ds.Tables[0].Rows.Count + &,\&rows\&:& + ds2Str + &}&;
//保存数据到缓存服务器
CachedService.setObjectToCached(key, json);
catch (Exception ex)
//异常记录到日志
Log4netService.log4netFatal(MethodBase.GetCurrentMethod().DeclaringType, ex);
}七 dataSet转jsonpublic static string dataSet2Json(DataSet ds)
string jsonStr =
//Newtonsoft.Json在转换日期的时候,会出现格式和时区(差8小时)差别
Trade_Status_Name
//如果不作如下格式转换,会出现形如Date(0+0800)/的日期
IsoDateTimeConverter timeConverter = new IsoDateTimeConverter();
//这里使用自定义日期格式,如果不使用的话,默认是ISO8601格式
timeConverter.DateTimeFormat = &yyyy'-'MM'-'dd' 'HH':'mm':'ss&;
jsonStr = JsonConvert.SerializeObject(ds.Tables[0], Formatting.Indented, timeConverter);
//jsonStr = &[{Stk_Code:'601398',Stk_name:'工商银行'},{Stk_Code:'500999',Stk_name:'农业银行'}]&;
return jsonS
}八 &WebService调用及返回Json数据[System.Web.Script.Services.ScriptService]
public class TestWebService : System.Web.Services.WebService
/// &summary&
/// &/summary&
[WebMethod]
public void getTestData()
string cb = Context.Request[&callback&];
//跨域服务器发送jsonp的参数key
int start = Convert.ToInt32(string.IsNullOrEmpty(Context.Request[&start&]) ? &1& : Context.Request[&start&]);
//从第几页开始:默认第一次从1开始,next_start=start+limit
int limit = Convert.ToInt32(string.IsNullOrEmpty(Context.Request[&limit&]) ? &20& : Context.Request[&limit&]);
//每次取的条数(步进):默认每页20条
string sf = string.IsNullOrEmpty(Context.Request[&sf&]) ? &se_code& : Context.Request[&sf&]; //sortField 排序字段,默认:se_code
string sr = string.IsNullOrEmpty(Context.Request[&sr&]) ? &asc& : Context.Request[&sr&];
//sortRule 排序规则,默认:asc
SomeClass svr = new SomeClass();
string json = svr.getSomeData(start, limit, sf, sr);
Context.Response.ContentType = &text/ charset=utf-8&;
//Context.Response.Write(cb + &({\&total\&:30,\&rows\&:[{\&ID\&:1,\&NAME\&:\&John\&},{\&ID\&:2,\&NAME\&:\&Mike\&}]})&);
Context.Response.Write(cb + &(& + json + &)&);
版权声明:本文为博主原创文章,未经博主允许不得转载。
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场

我要回帖

更多关于 memcached 刷新缓存 的文章

 

随机推荐