memcachedキャッシュサーバNet開発応用


要点
  memcached, Enyim, log4net, Newtonsoft.Json
Enyim,log 4 net,memcachedのバージョンに注意してください.以下と一致しない場合、デバッグ実行中に問題が発生する可能性があります.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-win 32 v 1.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はデフォルトで64 Mメモリと11211ポートをサーバパラメータとして使用します.パラメータを調整する場合は、「memcached」を参照してください.exe -h 2.memcachedを起動します.exe-m 512-p 33000-d start-dデーモン起動-mメモリサイズ-pポート、デフォルトポート11213.テストmemcached:>telnet localhost 11211 add firstKey 0 0 15 Hello Memcached STORED get firstKey VALUE firstKey 0 15 Hello Memcached END quit
三memcachedおよびlog 4 net構成(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>

四log 4 net初期化
Webを初期化する.configで構成されたlog 4 net
Globalでasaxの下:
protected void Application_Start(object sender, EventArgs e)
  {
      //log4net   
      //      , Web.config log4net:RollingLogFileAppender:file            
       log4net.Config.XmlConfigurator.Configure();
  }

5ライトキャッシュのクラスを読み込む
なお、以下の読み書きMemcachedはmemcached v 1に基づく.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;
        }
    }

7 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;
        }

8 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 + ")");
        }
    }