memcached缓存服务器.net开发应用
要点memcached, Enyim, log4net, Newtonsoft.Json
一 环境
注意Enyim,log4net,memcached的版本,如果与下面不一至,调试运行中有可能出现问题
1.memcached客户端
Enyim.Caching.dllv2.12.0.0
Enyim.Caching.Log4NetAdapter.dllv2.12.0.0
log4net.dll v1.2.10.0
2.memcached服务端
memcached-win32v1.4.4-14
3.数据输出及提供
数据输出格式:json
数据提供:WebService
4.dataSet转json
组件:Newtonsoft.Json.dllv4.0.8.14612
5.开发工具
visual studio 2010
6.dotNet
开发版本:.netv3.5
运行版本:.netv2.0.50727
二 memcached安装启动
1.安装
memcached.exe -d install
服务启动后, memcached 默认使用 64M 内存和 11211 端口作为服务器参数。
如果你希望调整参数,请参考: memcached.exe -h
2.启动
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
STORED
get firstKey
VALUE firstKey 0 15
Hello Memcached
END
quit
三 memcached及log4net配置(Web.config)
<!--配置memcached服务器及log4net日志-->
<configuration>
<configSections>
<!--... 其它配置 -->
<!--log4net日志配置-->
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler,log4net"/>
<!--缓存客户端配置-->
<sectionGroup name="enyim.com">
<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>
<!--缓存客户端配置-->
<enyim.com>
<log factory="Enyim.Caching.Log4NetFactory, Enyim.Caching.Log4NetAdapter"/>
<memcached>
<servers>
<add address="192.168.0.45" port="11211"/>
</servers>
<socketPool minPoolSize="1000" maxPoolSize="2000" connectionTimeout="00:00:10" deadTimeout="00:05:00"/>
</memcached>
</enyim.com>
<memcached>
<servers>
<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.-->
<log4net>
<root>
<level value="ALL"/>
<appender-ref ref="RollingLogFileAppender"/>
<appender-ref ref="ConsoleAppender"/>
<appender-ref ref="TraceAppender"/>
</root>
<logger name="Enyim.Caching.Memcached.DefaultNodeLocator">
<level value="Debug"/>
</logger>
<logger name="Enyim.Caching.Memcached.PooledSocket">
<level value="Info"/>
</logger>
<logger name="Enyim.Caching.Memcached.Protocol">
<level value="Info"/>
</logger>
<logger name="Membase.VBucketAwareOperationFactory">
<level value="Info"/>
</logger>
<logger name="Enyim.Caching.Memcached.MemcachedNode">
<level value="Info"/>
</logger>
<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"/>
</layout>
<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"/>
</layout>
</appender>
<appender name="TraceAppender" type="log4net.Appender.TraceAppender">
<layout type="log4net.Layout.PatternLayout,log4net">
<param name="ConversionPattern" value="%d [%t] %-5p %c %m%n"/>
</layout>
</appender>
</log4net>
<!-- 缓存期限 -->
<appSettings>
<add key="cachingTime" value="120"/>
</appSettings>
<!-- 数据库连接 -->
<connectionStrings>
<add name="dbConnStr" connectionString="Data Source=APPCtl;User ID=appuser;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 = null;
IGetOperationResult result = mc.ExecuteGet(key);
if (result.HasValue)
{
obj = result.Value;
}
return obj;
//...
}
/// <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)
{
return true;
}
else
{
string me = result.Message;
int code = Convert.ToInt32(result.StatusCode);
return false;
}
}
}六 缓存与数据库
取数据首先查看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 + ":" + sr;
//从缓存服务器中取对应key的数据
Object obj = CachedService.getObjectFromCached(key);
if (obj != null)
{
//缓存服务器中有数据
json = (string)obj;
}
else
{
//缓存服务器中无数据,去数据库取,再保存到缓存服务器
//查询数据库,返回dataset ds
//...各种sql查询
try{
string ds2Str = "";
//如果ds不为空,转换为Json格式
ds2Str = DbUtil.dataSet2Json(ds);
ds.Dispose();
//拼接成Json格式
if (ds.Tables.Rows.Count == 0)
{
json = "{\"total\":0,\"rows\":[]}";
}
else
{
json = "{\"total\":" + ds.Tables.Rows.Count + ",\"rows\":" + ds2Str + "}";
}
//保存数据到缓存服务器
CachedService.setObjectToCached(key, json);
}
catch (Exception ex)
{
//异常记录到日志
Log4netService.log4netFatal(MethodBase.GetCurrentMethod().DeclaringType, ex);
throw ex;
}
}
return json;
}
}七 dataSet转jsonpublic static string dataSet2Json(DataSet ds)
{
string jsonStr = null;
//Newtonsoft.Json在转换日期的时候,会出现格式和时区(差8小时)差别Trade_Status_Name
//如果不作如下格式转换,会出现形如Date(1335247957000+0800)/的日期
IsoDateTimeConverter timeConverter = new IsoDateTimeConverter();
//这里使用自定义日期格式,如果不使用的话,默认是ISO8601格式
timeConverter.DateTimeFormat = "yyyy'-'MM'-'dd' 'HH':'mm':'ss";
jsonStr = JsonConvert.SerializeObject(ds.Tables, Formatting.Indented, timeConverter);
//jsonStr = "[{Stk_Code:'601398',Stk_name:'工商银行'},{Stk_Code:'500999',Stk_name:'农业银行'}]";
return jsonStr;
}八WebService调用及返回Json数据
public class TestWebService : System.Web.Services.WebService
{
/// <summary>
/// </summary>
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/plain; charset=utf-8";
//Context.Response.Write(cb + "({\"total\":30,\"rows\":[{\"ID\":1,\"NAME\":\"John\"},{\"ID\":2,\"NAME\":\"Mike\"}]})");
Context.Response.Write(cb + "(" + json + ")");
}
}
版权声明:本文为博主原创文章,未经博主允许不得转载。
页:
[1]