分布式缓存HttpRuntime.cache应用到单点登陆中_优化登陆
以前的设计方案,是我们在数据库中放一个表,用作存储验证登陆成功的用户,并且生成用
户TOKEN(令牌)
分布式缓存+集群的解决方案图:
大概就是这样设计的。。。四台服务器。
我们将存储登陆成功的用户表从数据库中分离出来,放到缓存中。并利用集群建立四台服务器缓存同步更新。。。。
在登陆时,我们读了缓存中的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
}
}
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;
}
}
}
}