net中默认的会话状态是存储在内存中的,当一个网站的用户数量少或者说 同时访问的人数不多的时候可能还没什么,但是一旦用户在线人数过多的时候则会出现瓶颈了,于是本文采用SQlite数据库来实现这个提供程序
/// <summary>
/// Juice网站会话状态数据存储提供类
/// </summary>
public sealed class SQLiteStoreProvider : SessionStateStoreProviderBase
{}
只要类继承SessionStateStoreProviderBase 并重写其中的抽象方法即可,由于msdn里边有,所以这里不再赘述
最后再web.config中配置为
<system.web>
<sessionState mode="Custom" cookieless="UseDeviceProfile" customProvider="JuiceSSExpress">
<providers>
<add name="JuiceSSExpress" type="Juice.Core.SessionState.SQLiteStoreProvider"/>
</providers>
</sessionState>
我采用的是将session数据串行化为二进制然后保存在数据库中,在提取的Session数据的时候用反串行二进制的方法,但是这样用起来却比我以前直接将会话状态数据保存在内存中慢了很多
以前只需要0.0003秒而现在却需要0.2786183s
当然这是因为我这两种情况只有我一个人访问所以还无法对比出来
所以正在用Web压力测试工具测试 等会把结果弄出来
同时正在考虑横向改变数据库提供方式比如用SqlServer和Access数据库再测试下
也正在考虑把纵向改变串行化的方式,看能不用用其他的串行化的方式来提高下性能
当然之所以做这么多的探讨,目的只是为了我的系统能适合更多的用户
因为有的站长没有sqlserver 所以是不能用sqlserver来提供会话状态存储数据的
有的站长只能用Access和Sqlite这种轻量级的但相对来说是免费的数据库,如果他们的用户多的话,所有数据保存在内存中估计会慢,所以正在探讨一种 数据库与SessionState提供程序的折中优化方式....
源码稍后公布
这里是自己前段时间学习,以及通过达达的指教总结得出来的一点点经验,大家可以参考下
Discuz为了支持多种数据库,所以采取了反射的方法,但是大家知道反射的性能损失非常大的
private static void GetProvider()
{
try
{
_instance = (IDataProvider)Activator.CreateInstance(Type.GetType(string.Format("Discuz.Data.{0}.DataProvider, Discuz.Data.{0}", BaseConfigs.GetDbType), false, true));
}
catch
{
throw new Exception("请检查DNT.config中Dbtype节点数据库类型是否正确,例如:SqlServer、Access、MySql");
}
}
前段时间bbsmax http://www.bbsmax.com/ (非常不错的一个.net论坛程序)的达达提供了另外一种方法
private static CreateInstance<T> CreateInstanceHandler()
{
Type baseType = typeof(T);
Type newType = CreateType();
if (newType != null)
{
DynamicMethod method = new DynamicMethod(string.Empty, baseType, null, baseType.Module);
ILGenerator iLGenerator = method.GetILGenerator();
iLGenerator.DeclareLocal(baseType, true);
iLGenerator.Emit(OpCodes.Newobj, newType.GetConstructor(new Type[0]));
iLGenerator.Emit(OpCodes.Stloc_0);
iLGenerator.Emit(OpCodes.Ldloc_0);
iLGenerator.Emit(OpCodes.Ret);
return (CreateInstance<T>)method.CreateDelegate(typeof(CreateInstance<T>));
}
return null;
}
internal delegate T CreateInstance<T>(); 这是委托的声明
即采用 DynamicMethod的方法 这种方法确实性能会有很大的提高
前段时间在国外的一个博客上也看到了关于直接引用 反射 DynamicMethod的性能比较,把它的实例下载下来了 测试结果如下
------ Object Creation ------
direct - object creation: 39ms
dynamic method - object creation: 51ms
reflection - object creation: 306ms
------ Property Get ------
direct - property get: 20ms
dynamic method - property get: 45ms
reflection - property get: 1800ms
------ Property Set ------
direct - property set: 26ms
dynamic method - property set: 52ms
reflection - property set: 2366ms
------ Instance Method Call ------
direct - instance method call: 50ms
dynamic method - instance method call: 123ms
reflection - instance method call: 3069ms
------ Static Method Call ------
direct - static method call: 24ms
dynamic method - static method call: 121ms
reflection - static method call: 2931ms
上面的结果中每一项中的 direct是指直接引用
dynamic method则是采用动态方法
reflection 即是采用反射的方法即discuz的Activator.CreateInstance
通过上面的数据大家可以清晰的看到,虽然动态方法的性能比直接引用 direct invoke要慢但是比反射方法 性能却提高了几十倍