一,、 引發(fā) Session 丟失的幾種原因
動(dòng)過手寫代碼的人都知道,,Session 丟失是比較常見的事,。以下是本人這幾年所遇到的,,能夠引發(fā) Session 丟失的原因,,不敢說是百分百,,丟失概率還是特別高的,。錯(cuò)…,,簡(jiǎn)直可以說是“相…當(dāng)…”高哇 ^_^"
1,、 存放 Session 的電腦重啟(廢話,若這樣都不丟,,你神仙?。?/span>
2、 InProc 模式:aspnet_wp.exe或w3wp.exe 在“任務(wù)管理器”中或其它情況下導(dǎo)致其進(jìn)程被終止運(yùn)行,。
3,、 InProc 模式:修改 .cs 文件后,編譯了兩次(只編譯一次,,有時(shí)不會(huì)丟失)
4,、 InProc 模式:修改了Web.config
5、 InProc 模式,,Windows 2003 環(huán)境:應(yīng)用程序池回收,、停止后重啟
6、 InProc 模式:服務(wù)器上 bin 目錄里的 .dll 文件被更新
以上列舉的都是 InProc 模式下,容易引發(fā)解析 ASP.NET 應(yīng)用程序重置的原因,。是不是覺得很窩火,?之前我也有這種感覺,慢慢就習(xí)慣啦,,再后來就干脆不用這種模式了,。于是乎,就有了使用下列兩種模式的嘗試,,現(xiàn)寫出來與大家一起分享,。
二、 使用 StateServer 保存 Session
StateServer模式的實(shí)質(zhì)是,,把Session 存放在一個(gè)單獨(dú)的進(jìn)程里,,此進(jìn)程獨(dú)立于aspnet_wp.exe或w3wp.exe。啟用此服務(wù)后,,在“任務(wù)管理器”中可以看到一個(gè)名為aspnet_state.exe的進(jìn)程,,下面開始說明一下設(shè)置的具體步驟:
1、 修改注冊(cè)表(關(guān)鍵步驟,,如下圖)
運(yùn)行regedit→打開注冊(cè)表→找到HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Services/aspnet_state/Parameters 節(jié)點(diǎn)→將AllowRemoteConnection 的鍵值設(shè)置成“1”(1 為允許,,0 代表禁止)→設(shè)置Port (端口號(hào))
注意事項(xiàng):
a)、若ASP.NET State Service正在運(yùn)行,,修改注冊(cè)表內(nèi)容后,,則需要重新啟動(dòng)該服務(wù)
b)、注意端口號(hào)的鍵值是以十六進(jìn)制儲(chǔ)存的,,可以使用十進(jìn)制進(jìn)行修改,,42424是默認(rèn)的端口
c)、AllowRemoteConnection 的鍵值設(shè)置成“1”后,,意味著允許遠(yuǎn)程電腦的連接,,也就是說只要知道你的服務(wù)端口,就可享用你的ASP.NET State Service,,即把 Session 存放在你的電腦進(jìn)程內(nèi),,因此請(qǐng)大家慎用;鍵值為“0”時(shí),,僅有stateConnectionString為“tcpip=localhost: 42424”與“tcpip=127.0.0.1:42424”的情況,,方可使用ASP.NET State Service
2、 開啟ASP.NET State Service(如下圖)
右鍵點(diǎn)擊“我的電腦”→管理→服務(wù)與應(yīng)用程序→服務(wù)→雙擊“ASP.NET State Service”→啟動(dòng)(可設(shè)為“自動(dòng)”)
說明:只要安裝了 .Net Framework v1.0/v1.1 ,,都擁有此服務(wù),。
3、 更改Web.config
打開Web.config→找到<sessionState>節(jié)點(diǎn)內(nèi)容
<sessionState
mode="InProc"
stateConnectionString="tcpip=127.0.0.1:42424"
sqlConnectionString="data source=127.0.0.1;Trusted_Connection=yes"
cookieless="false"
timeout="20"/>
→將其改為以下內(nèi)容
<sessionStatemode="StateServer" stateConnectionString="tcpip=192.168.0.2:42424"timeout="20"/>
注意事項(xiàng):
a),、設(shè)成StateServer 后,,必須要有對(duì)應(yīng)的stateConnectionString
b),、注意 IP 地址(可以是遠(yuǎn)程計(jì)算機(jī) IP、計(jì)算機(jī)名稱,、域名)與端口號(hào),,端口號(hào)需與ASP.NET State Service的服務(wù)端口一致
三、 將 Session 放入 SQLServer 保存
SQLServer模式就是,,把Session 存放在SQL Server數(shù)據(jù)庫(kù)里(注意不是Oracle,,動(dòng)動(dòng)腳趾都能猜到原因啦),下面開始說明一下設(shè)置的具體步驟:
1,、 啟動(dòng)相關(guān)的數(shù)據(jù)庫(kù)服務(wù)(如圖)
運(yùn)行SQL Server 服務(wù)管理器→啟動(dòng)SQL Server(最好設(shè)為開機(jī)自動(dòng)運(yùn)行)→啟動(dòng)SQL Server Agent服務(wù)(最好設(shè)為開機(jī)自動(dòng)運(yùn)行)
注意事項(xiàng):
a),、注意啟動(dòng)順序,也可通過下列方式設(shè)置:右鍵點(diǎn)擊“我的電腦”→管理→服務(wù)與應(yīng)用程序→服務(wù)→找到“MSSQLSERVER”與“SQLSERVERAGENT”→啟動(dòng)并設(shè)置啟動(dòng)類型為“自動(dòng)”
b),、SQL Server Agent在此處的作用是清除數(shù)據(jù)庫(kù)中已過期的 Session
2,、 建立存放 Session 的DataBase
運(yùn)行“SQL 查詢分析器”→使用“sa”或是擁有“master”的db_owner權(quán)限的用戶登錄數(shù)據(jù)庫(kù)→打開查詢文件C:/WINNT/Microsoft.NET/Framework/v1.1.4322/InstallSqlState.sql(存放在 Windows 系統(tǒng)目錄的 .Net 安裝目錄下可找到)→直接運(yùn)行該 sql 腳本→刷新數(shù)據(jù)庫(kù)即可看到名為ASPState的 DataBase
3、 建立連接數(shù)據(jù)庫(kù)ASPState的用戶,,并為此用戶授權(quán)(此步驟可跳過)
進(jìn)行此步的原因是:一是不想在Web.config中出現(xiàn)sa的密碼,;二是tempdb在數(shù)據(jù)庫(kù)啟動(dòng)后僅保留sa 一個(gè)賬號(hào)的使用權(quán)限,其余賬號(hào)的權(quán)限統(tǒng)統(tǒng)被清除,,但保存 Session又需要用到此DataBase,;
A)、運(yùn)行 SQL Server 的企業(yè)管理器→展開數(shù)據(jù)庫(kù)的安全性→右擊“登錄”→新建“登錄”→輸入“名稱”→選擇“SQL Server 身份驗(yàn)證”→輸入“密碼”→指定“數(shù)據(jù)庫(kù)”→點(diǎn)擊“數(shù)據(jù)庫(kù)訪問”→勾選“ASPState”→選中“db_owner”角色→點(diǎn)擊“確定”→再一次輸入“密碼”→點(diǎn)擊“確定”后即可建立ASPState的用戶(此處建立名為“SessionStateUser”,,密碼為“123456”的測(cè)試用戶)
B),、運(yùn)行 SQL Server 的企業(yè)管理器→展開“管理”→展開“SQL Server 代理”→右擊“作業(yè)”→點(diǎn)擊“新建作業(yè)”→輸入“名稱”(此例為GrantSessionUser)→點(diǎn)擊標(biāo)簽“步驟”→新建→輸入“步驟名”(此例為Grant01)→選擇數(shù)據(jù)庫(kù)“tempdb”→編寫 SQL 腳本“execsp_adduser'SessionStateUser', 'SessionUser' ,'db_owner' ”→確定→點(diǎn)擊標(biāo)簽“調(diào)度”→新建→輸入“名稱”(此例為Start01)→選擇類型“SQL Server 代理啟動(dòng)時(shí)自動(dòng)啟動(dòng)”→確定→最后點(diǎn)擊“確定”新增完畢
C)、也可運(yùn)行以下腳本一次性搞定以上 A,、B 兩個(gè)步驟
/******腳本開始******/
--新建數(shù)據(jù)庫(kù)賬號(hào) SessionStateUser ,默認(rèn)登錄 ASPState
EXECsp_addlogin 'SessionStateUser', '123456', 'ASPState'
useASPState --切換 DataBase
--將 SessionStateUser 授予 db_owner 的權(quán)限
exec sp_adduser 'SessionStateUser','SessionUser','db_owner'
usemaster --切換 DataBase
BEGIN TRANSACTION
/******聲明變量******/
DECLARE@JobIDBINARY(16)
DECLARE@ReturnCodeINT
SELECT@ReturnCode= 0
-- 若沒有,,則添加作業(yè)的分類
IF(SELECTCOUNT(*)FROMmsdb.dbo.syscategories WHEREname=N'[Uncategorized (Local)]') < 1
EXECUTEmsdb.dbo.sp_add_category @name =N'[Uncategorized (Local)]'
-- 新建作業(yè)
EXECUTE@ReturnCode=msdb.dbo.sp_add_job --調(diào)用存儲(chǔ)過程 sp_add_job
@job_id=@JobID OUTPUT, --將返回的 JobID,,賦值給變量
@job_name=N'GrantSessionUser', --作業(yè)名稱
@owner_login_name= NULL, --默認(rèn)為當(dāng)前用戶所有
@description=null,
@category_name =N'[Uncategorized (Local)]', --作業(yè)分類歸屬
@enabled=1, --是否啟用
@notify_level_email=0,
@notify_level_page=0,
@notify_level_netsend=0,
@notify_level_eventlog =0,
@delete_level=0
IF(@@ERROR<>0OR@ReturnCode<>0)GOTOQuitWithRollback --出錯(cuò)則回滾
-- 新建步驟
EXECUTE@ReturnCode=msdb.dbo.sp_add_jobstep--調(diào)用存儲(chǔ)過程 sp_add_jobstep
@job_id = @JobID, --傳入剛剛新建的 JobID
@step_id=1,
@step_name=N'Grant01', --步驟名稱
@command =N'exec sp_adduser ''SessionStateUser'', ''SessionUser'' ,''db_owner''',
--需要執(zhí)行的 SQL 腳本(注意用兩個(gè)連續(xù)的單引號(hào)表示 SQL 中的單引號(hào))
@database_name =N'tempdb',--執(zhí)行上述 SQL 所用的 DataBase
@server =N'',
@database_user_name=N'',
@subsystem=N'TSQL', --執(zhí)行類型為“Transact-SQL 腳本”
@cmdexec_success_code=0,
@flags=0,
@retry_attempts =0,
@retry_interval=1,
@output_file_name=N'',
@on_success_step_id=0,
@on_success_action=1,
@on_fail_step_id =0,
@on_fail_action =2
IF(@@ERROR<>0OR@ReturnCode <>0)GOTOQuitWithRollback
-- 新建調(diào)度
EXECUTE @ReturnCode= msdb.dbo.sp_add_jobschedule
@job_id =@JobID,
@name= N'Start01', --調(diào)度名稱
@enabled=1,
@freq_type= 64 --“64”表示當(dāng) SQLServerAgent 服務(wù)啟動(dòng)時(shí)運(yùn)行
IF(@@ERROR <>0OR@ReturnCode <> 0)GOTOQuitWithRollback
-- 將新建的作業(yè)添加到本地?cái)?shù)據(jù)庫(kù)
EXECUTE@ReturnCode=msdb.dbo.sp_add_jobserver@job_id =@JobID,@server_name=N'(local)'
IF(@@ERROR<>0OR @ReturnCode<>0)GOTOQuitWithRollback
COMMITTRANSACTION
GOTO EndSave
QuitWithRollback:
IF(@@TRANCOUNT>0)ROLLBACKTRANSACTION
EndSave:
/******腳本結(jié)束******/
4、 設(shè)置Web.config內(nèi)容
打開 Web.config →找到<sessionState>節(jié)點(diǎn)內(nèi)容→修改為以下內(nèi)容即可:
<sessionStatemode="SQLServer" sqlConnectionString ="data source=192.168.0.2; user id=SessionStateUser; password=123456"timeout="20"/>
注意事項(xiàng):
a),、sqlConnectionString中不能出現(xiàn)initial catalog 選項(xiàng)
b),、SQL Server Agent在此處的作用是清除數(shù)據(jù)庫(kù)中已過期的 Session
c)、你若跳過了第三步,,則user id 需要用sa進(jìn)行登錄
d),、若sqlConnectionString為“data source=127.0.0.1;Trusted_Connection=yes”,則使用本地計(jì)算機(jī)ASPNET(Windows 2000 系統(tǒng)帳戶)或Network Service(Windows 2003 系統(tǒng)帳戶)的身份登錄數(shù)據(jù)庫(kù),。要是數(shù)據(jù)庫(kù)不允許上述用戶登錄,,則報(bào)錯(cuò);同樣,,即使上述帳戶能成功登錄,,也要分配其tempdb的權(quán)限,理由是 Session 是保存在tempdb中的,若沒有該DataBase的存取權(quán)限是行不滴,。見下圖:
|
|