分布式缓存HttpRuntime.cache应用到单点登陆中_优化登陆

分布式缓存+集群的解决方案图:

 

 

  

大概就是这样设计的。。。四台服务器。

我们将存储登陆成功的用户表从数据库中分离出来,放到缓存中。并利用集群建立四台服务器缓存同步更新。。。。

 

在登陆时,我们读了缓存中的Token,同时遍历IP集群中配置的服务器地址。同步四台服务器之间的Token缓存。。。。。

 

 

相应的代码:

DE层中配置文件:

 


<configuration>
    <appSettings>
        <!--集群相关开始-->
        <!--集群IP组-->
        <add key="ClusterGroupAddr" value="192.168.1.165,10.132.41.52" />
        <!--当前的Web站点名称-->
        <add key="WebSiteName" value="HttpRuntimeCacheService" />
        <!-- 集群相关截止 -->
    </appSettings>
 <system.serviceModel>
  <bindings>
   <basicHttpBinding>
    <binding name="CacheServiceSoap" closeTimeout="00:01:00" openTimeout="00:01:00"
     receiveTimeout="00:10:00" sendTimeout="00:01:00" allowCookies="false"
     bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
     maxBufferSize="65536" maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
     messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered"
     useDefaultWebProxy="true">
     <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
      maxBytesPerRead="4096" maxNameTableCharCount="16384" />
     <security mode="None">
      <transport clientCredentialType="None" proxyCredentialType="None"
       realm="" />
      <message clientCredentialType="UserName" algorithmSuite="Default" />
     </security>
    </binding>
   </basicHttpBinding>
  </bindings>
  <client>
   <endpoint address="http://localhost/HttpRuntimeCacheService/CacheService.asmx"
    binding="basicHttpBinding" bindingConfiguration="CacheServiceSoap"
    contract="CacheService.CacheServiceSoap" name="CacheServiceSoap" />
  </client>
 </system.serviceModel>
</configuration>

 

 CacheBase.cs  缓存基类

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.Serialization.Formatters.Binary;
using System.Security;
using System.Web.Caching;
using System.Web;
using System.ServiceModel;   
using System.Reflection;
using HttpRuntimeCacheDE.CacheService;

namespace HttpRuntimeCacheDE.Cache
{
    public class CacheBase
    {
        private CacheServiceSoapClient client = null;
        private CacheService.LoginStatusParam cParam = new CacheService.LoginStatusParam();
        private CacheService.CacheOperation cOperation = new CacheService.CacheOperation();
        /// <summary>
        /// 发送用于同步集群中的Cache数据
        /// </summary>
        /// <param name="param">Cache数据</param>
        public void SendCacheData(CacheParam param, CacheOperation operation)
        {

            string[] ips = CacheConfig.ClusterGroupAddr;
            foreach (string ip in ips)
            {
                try
                {
                    client = new CacheService.CacheServiceSoapClient();
                    EndpointAddress address = new EndpointAddress("http://" + ip + @"/" + CacheConfig.WebSiteName + "/CacheService.asmx");

                    client.Endpoint.Address = address;

                    RemoteParamConvert(cParam, param);

                    switch (operation)
                    {
                        case CacheOperation.Add:
                            cOperation = CacheService.CacheOperation.Add;
                            break;
                        case CacheOperation.Edit:
                            cOperation = CacheService.CacheOperation.Edit;
                            break;
                        case CacheOperation.Delete:
                            cOperation = CacheService.CacheOperation.Delete;
                            break;
                        default:
                            break;
                    }

                    client.GetCacheData(cParam, cOperation);
                }
                catch
                {
                    continue;
                }
            }

        }
        /// <summary>
        /// 用于同步集群中的Cache数据
        /// </summary>
        /// <param name="param">Cache数据</param>
        /// <param name="operation">Cache操作类型</param>
        public void SyncCacheData(CacheParam param, CacheOperation operation)
        {
            switch (operation)
            {
                case CacheOperation.Add:
                    AddCache(param);
                    break;
                case CacheOperation.Edit:
                    EditCache(param);
                    break;
                case CacheOperation.Delete:
                    DeleteCache(param);
                    break;
                default:
                    break;
            }
        }
        // 增加Cache数据
        protected virtual void AddCache(CacheParam param)
        {
            string key = BuildCacheKey(param);
            HttpRuntime.Cache.Add(key, param, null, DateTime.Now.AddHours(1), System.Web.Caching.Cache.NoSlidingExpiration, CacheItemPriority.High, null);
        }
        // 修改Cache数据
        protected virtual void EditCache(CacheParam param)
        {
            string key = BuildCacheKey(param);
            HttpRuntime.Cache.Remove(key);
            AddCache(param);
        }

        // 删除Cache数据
        protected virtual void DeleteCache(CacheParam param)
        {
            string key = BuildCacheKey(param);
            HttpRuntime.Cache.Remove(key);
        }

        // 生成在线的Cache Key
        protected virtual string BuildCacheKey(CacheParam param)
        {
            return "";
        }
        // 将本地参数转换成远程调用的参数
        private void RemoteParamConvert(object sourceObj, object targetObj)
        {
            try
            {
                PropertyInfo[] sourceInfo = sourceObj.GetType().GetProperties();
                PropertyInfo[] targetInfo = targetObj.GetType().GetProperties();

                for (int i = 0; i < sourceInfo.Length; i++)
                {
                    if (sourceInfo[i].Name == targetInfo[i].Name)
                    {
                        object targetValue = targetInfo[i].GetValue(targetObj, null);


                        if (!ParamFunc.Judgement(targetValue))
                            continue;

                        sourceInfo[i].SetValue(sourceObj, targetValue, null);
                    }
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
       
    }

    /// <summary>
    /// Cache同步操作类型
    /// </summary>
    public enum CacheOperation
    {
        Add,
        Edit,
        Delete
    }
}

 

  CacheFunc.cs 缓存操作函数


using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
using System.Web.Caching;


namespace HttpRuntimeCacheDE.Cache
{
    public class CacheFunc:CacheBase
    {
        protected override string BuildCacheKey(CacheParam param)
        {
            LoginStatusParam lsparam = param as LoginStatusParam;
            return param.GetType().Name.ToString() + "&" + lsparam.SysLoginStatusID + "&" + lsparam.LoginName;
        }
        /// <summary>
        /// 在Cache中查询在线用户
        /// </summary>
        /// <param name="param">在线用户参数</param>
        public List<LoginStatusParam> QueryLoginStatus(LoginStatusParam param)
        {
            List<LoginStatusParam> result = new List<LoginStatusParam>();

            List<LoginStatusParam> plist = ConvertCacheItem();

            var loginResult = from c in plist
                              where 1 == 1
                              && (!Judgement(param.SysLoginStatusID) ? true : c.SysLoginStatusID == param.SysLoginStatusID)
                              && (!Judgement(param.SysOrganizationID) ? true : c.SysOrganizationID == param.SysOrganizationID)
                              && (!Judgement(param.SysServiceCenterID) ? true : c.SysServiceCenterID == param.SysServiceCenterID)
                              && (!Judgement(param.LoginName) ? true : c.LoginName == param.LoginName)
                              && (!Judgement(param.LoginTime) ? true : c.LoginTime == param.LoginTime)
                              && (!Judgement(param.LastHandleTime) ? true : c.LastHandleTime == param.LastHandleTime)
                              && (!Judgement(param.FullName) ? true : c.FullName == param.FullName)
                              && (!Judgement(param.LoginToken) ? true : c.LoginToken == param.LoginToken)
                              select c;

            result = loginResult.ToList<LoginStatusParam>();

            return result;
        }

        // 将Cache中的项转换成List
        private List<LoginStatusParam> ConvertCacheItem()
        {
            List<LoginStatusParam> plist = new List<LoginStatusParam>();

            IDictionaryEnumerator CacheEnum = HttpRuntime.Cache.GetEnumerator();

            while (CacheEnum.MoveNext())
            {
                if (CacheEnum.Value is LoginStatusParam)
                    plist.Add(CacheEnum.Value as LoginStatusParam);
            }

            return plist;
        }
        public string SysUserLogin(LoginStatusParam param)
        {
            AddLoginStatus(param);
            param = QueryLoginStatus(param).First();

            return param.LoginToken;
        }

        #region AddMethod
        /// <summary>
        /// 在Cache中增加在线用户
        /// </summary>
        /// <param name="param">在线用户参数</param>
        public void AddLoginStatus(LoginStatusParam param)
        {
            Random random = new Random();
            param.SysLoginStatusID = random.Next().ToString();
            SyncCacheData(param, CacheOperation.Add);

            SendCacheData(param, CacheOperation.Add);
        }
        #endregion
        private bool Judgement(object obj)
        {
            try
            {
                if (obj != null && obj != DBNull.Value)
                {
                    return true;
                }
                else
                {
                    return false;
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
    }
}
posted @ 2012-10-11 15:33  枫-  阅读(674)  评论(0编辑  收藏  举报