memcached缓存服务器.net开发应用

25 篇文章 0 订阅
7 篇文章 0 订阅
要点

  memcached, Enyim, log4net, Newtonsoft.Json

 一 环境
   注意Enyim,log4net,memcached的版本,如果与下面不一至,调试运行中有可能出现问题

1.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.数据输出及提供
   数据输出格式:json
   数据提供:WebService
4.dataSet转json
   组件:Newtonsoft.Json.dll  v4.0.8.14612 
5.开发工具
   visual studio 2010
6.dotNet
   开发版本:.net  v3.5
   运行版本:.net  v2.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[0].Rows.Count == 0)
                    {
                        json = "{\"total\":0,\"rows\":[]}";
                    }
                    else
                    {
                        json = "{\"total\":" + ds.Tables[0].Rows.Count + ",\"rows\":" + ds2Str + "}";
                    }
                    //保存数据到缓存服务器
                    CachedService.setObjectToCached(key, json);
                }
                catch (Exception ex)
                {
                    //异常记录到日志
                    Log4netService.log4netFatal(MethodBase.GetCurrentMethod().DeclaringType, ex);
                    throw ex;
                }
            }
            return json;
        }
    }
七 dataSet转json
public 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[0], Formatting.Indented, timeConverter);
            //jsonStr = "[{Stk_Code:'601398',Stk_name:'工商银行'},{Stk_Code:'500999',Stk_name:'农业银行'}]";
            
            return jsonStr;
        }
八  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/plain; charset=utf-8";
            //Context.Response.Write(cb + "({\"total\":30,\"rows\":[{\"ID\":1,\"NAME\":\"John\"},{\"ID\":2,\"NAME\":\"Mike\"}]})");
            Context.Response.Write(cb + "(" + json + ")");
        }
    }





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值