这段时间在学习使用Memcached共享Session,现将其间遇到问题及解决方法记录下来,作为日后参考。
1. 准备工作(dll文件)
当前我们所使用的Memcached客户端是Memcached Providers,此项目需要自行下载且需要自行添加针对mysql的操作类,本人命名为:MemcachedProvidersForMySql,此项目由C#编写,最后生成两个动态库文件:Enyim.Caching.dll、MemcachedProviders.dll,但Memcached Providers引用了mysql.data.dll与log4net.dll两个库,所以在使用的时候也需要一并引用。
注意:有时候可能项目中已存在mysql.data.dll与log4net.dll两个库文件,需要注意此两个文件的版本与MemcachedProvidersForMySql中引用的版本需要一致,否则配置错误!
2. 数据库配置及注意事项
Memcached Providers工作机制是在Memcached服务器缓存一份数据的同时也在数据库中保存一份相同的数据作为备用(前提:dbType="MySql"而不是dbType="None"),所以需要为Memcached Providers配置一个可用的数据库,我们可命名为:memcache。Memcached Providers项目提供了此数据库需要的表与存储过程的脚本,只需要我们把脚本执行即可建立。
现在在调用存储过程时候,总是出现“"Procedure or function '`proc_LockItem`' cannot be found in database '`memcache`'."”的错误。此问题经多方验证、测试,最后确定是mysql.data.dll版本较低引起,下载高版本的mysql.data.dll(6.5.4.0)后此问题解决。
另:对于新安装的mysql数据库,需要确认当前时区设置是否正确,步骤如下:
2.1通过SHOW VARIABLES LIKE '%time_zone%'查看当前时区,如下图所示,timer_zone为UTC,则mysql的时间与北京时间差8个小时,需要进行调整。
2.2调整时区:在mysql安装目录bin目录下找到my.ini配置文件,在文件最后添加如下配置,重启后即可:
[mysqld]
default-time-zone = "+8:00"
3. 项目引用配置
a) 引用
将Enyim.Caching.dll、MemcachedProviders.dll、mysql.data.dll、log4net.dll四个文件复制到需要使用Memcached的项目的bin目录中,然后在需要使用的子项目中引用此四个文件
b) 配置
打开项目的web.config文档,按照如下配置:
<configSections>
<sectionGroupname="enyim.com">
<sectionname="memcached"type="Enyim.Caching.Configuration.MemcachedClientSection, Enyim.Caching" />
</sectionGroup>
<sectionname="cacheProvider"type="MemcachedProviders.Cache.CacheProviderSection,MemcachedProviders"
allowDefinition="MachineToApplication"restartOnExternalChanges="false" />
<sectionname="log4net"type="log4net.Config.Log4NetConfigurationSectionHandler,log4net" />
</configSections>
<connectionStrings>
<addname="MemcachedDB"connectionString="server=localhost;port=3306;uid=root;pwd=123456;DataBase=memcache;charset=utf8;allow zero datetime=true;"providerName="MySql.Data.MySqlClient"/>
</connectionStrings>
<enyim.com>
<memcached>
<servers>
<!--Memcache缓存服务器地址、端口号-->
<addaddress="192.168.1.X"port="12000" />
</servers>
<socketPoolminPoolSize="10"maxPoolSize="100"connectionTimeout="00:00:10"deadTimeout="00:02:00" />
</memcached>
</enyim.com>
<cacheProviderdefaultProvider="MemcachedCacheProvider">
<providers>
<addname="MemcachedCacheProvider"type="MemcachedProviders.Cache.MemcachedCacheProvider, MemcachedProviders"keySuffix="_prefix_"defaultExpireTime="2000" />
</providers>
</cacheProvider>
<!--timeout单位:分钟-->
<sessionStatecookieless="false"timeout="2"regenerateExpiredSessionId="false"
mode="Custom"customProvider="MemcachedSessionProvider">
<providers>
<addname="MemcachedSessionProvider"
type="MemcachedProviders.Session.SessionStateProvider,MemcachedProviders"
connectionStringName="MemcachedDB"dbType="MySql"
writeExceptionsToEventLog="false"keepKey="UserKey" />
</providers>
</sessionState>
4. 二级域共享Session的代码设置
为了能在不同的二级域名中进行Session共享,需要在Sessciont_Start中将Cookie对象的工作域指定为相同的域,代码如下:
如我们有多个二级域名sz.anjuke.com、gz.anjuke.com、
protected void Session_Start()
{
Response.Cookies["ASP.NET_SessionId"].Value = Session.SessionID;
Response.Cookies["ASP.NET_SessionId"].Domain ="anjuke.com";
}
其上,ASP.NET_SessionId为.Net将SessionID保存到Cookie中的默认名称,不可改动。
到此,可实现Memcached存储Session,并实现二级域名之间共享Session。Session的使用仍同平常一样。
5. 参考资料
1. 资料标题:ASP.NET利用Memcached的分布式Session来提升性能,
http://www.kuqin.com/dotnet/20111107/314498.html
2. 资料标题:.net的Session共享
http://www.25175.com/200609/25175/25175_html/2011-03/4377.html