本帖最后由 Star 于 2011-3-4 17:10 编辑 0 P4 y M4 ?/ e. x
2 x* U6 s# y/ f关于Session持久化这方面的话题,有很多人已经写过了,但是,毕竟这是我的项目经验,更加真实,可用。
" L- C6 \% P! b) k" j$ e 进入主题。, ~$ Z9 a, F9 K% d% I
9 a- a# | X3 T# D
情景一,Session ID在客户端的状态' z) `- H3 T' ?& j m
情景一中,saved in cookies情况) k: r. @0 Q# O/ B5 _: c+ _6 k* a
ID保存在client端的Cookies集合中8 \0 P" a# U ], Y% I$ [4 Y
缺点是,如果client端的cookie被禁用,那么ID无法保存& S8 ^6 N9 _& o: z' G2 Q( Q1 x$ _5 s: ]
设置cookieless="false"0 _ V# u+ z% F: C- `4 t+ d0 e
h3 i' m/ X( j( W; u5 U<sessionState
8 o2 C1 @5 M8 r) W( C4 P, @% lmode="InProc"
! W8 u E2 D0 `8 z$ N9 E/ O1 I1 CstateConnectionString="tcpip=127.0.0.1:42424"1 t' o& J9 u8 k. n$ o( f. |2 k4 v
sqlConnectionString="datasource=127.0.0.1;userid=sa;password="
5 r0 H9 t# }9 y v1 @% L/ icookieless="false"* }) X7 F, o; |% v8 Y, Q" v1 J# L
timeout="20"/># F9 i3 V) X7 |1 {& n& D: L" e; i- Q
, } L/ g4 ~) u, Z3 O
情景一中,saved in url情况
9 N3 h' e9 g$ B. } MS为了解决cookie被禁时,也能正常保存ID,在.net2.0中可以把ID保存在URL中.
& O) Y( f1 t. w# G9 J 设置cookieless="true"
. H) [0 ^/ u) `6 K' L/ }9 R- j
( j9 ?! ~& V8 s2 c& n: T<sessionState
! R" Z6 { `* Q& t. V5 L3 s mode="InProc"
1 R1 L% E' k: f0 Y stateConnectionString="tcpip=127.0.0.1:42424"
2 v- T% G! A( k3 d& j1 ? sqlConnectionString="datasource=127.0.0.1;userid=sa;password="
2 k% ?! H4 ?& c/ Q cookieless="true"
2 |( I/ }; t G0 K: x' ^4 S/ Q1 n timeout="20"/>
/ b+ e$ q9 a# t2 P! k8 Y3 X+ U! J; V5 Z6 w$ }- h K! y7 L- |
情景二,Session状态在服务器中的三中模式,进程内、进程外、数据库。5 o6 S; i D) Q9 z
情景二中,saved in 进程内# _8 j7 m/ I) S5 ~" w+ ?3 P" Q7 h9 W
设置mode="InProc"
4 {) ~1 @9 I$ {- G# v 优点;保存在本机内存中,无需跨网络,访问内存速度快
, L: s, d k6 X9 c 缺点;如果IIS进程发生异常或者WebSite有文件变更,都被asp.netRuntime监视,然后重新设置Session状态
; T R% G6 g, E) e8 a! C% Q; X9 L" g- }2 P( U
<sessionState
) K7 `8 G1 U H/ b mode="InProc"
- Q9 B! \( d; ~! ^' D, z9 A stateConnectionString="tcpip=127.0.0.1:42424"
& l2 p" V4 I8 }7 T sqlConnectionString="datasource=127.0.0.1;userid=sa;password="' @9 Z5 v3 i7 i4 g. t
cookieless="false"7 l0 k* ?! M( `% P) u6 k
timeout="20"/>
) u1 l' I( o4 K. z
; Q" c" Q7 W7 k* u, p 情景二中,saved in 进程外' z, X- T# R1 G8 ]
设置mode="StateServer",启动asp.net状态服务
( @3 b; o& Z) J 定位注册表
( C6 S2 @% L7 T& k5 Y& H: C Y0 c7 E- G “HKEY_LOCAL_MACHINE/SYSTEM/ControlSett001/Services/aspnet_state/Parameters“修改AllowRemoteConnection=1,Port=42424
$ {6 R1 o9 G1 M4 | 注意这些参数都是十进制类型,且这些设置是在访问远程asp.net状态服务的必要设置。0 X( s. B( U" U& C" L* ~* ]
优点;稳定,即使关闭WWW服务,只要启动asp.net状态服务,Session状态依然存在,不信你试试。
; r$ O" f; A3 g$ D' p6 V' E% o 如果把状态保存在非本机上只需修改上面的注册表,修改stateConnectionString="tcpip=RemoteIP:Remoteport",3 J7 b% {/ _# M& J) U' y) G
如果状态保存在远程机上的asp.net状态服务中,那么当页面关闭的时候,Session状态马上失效,* P% U' }. A" _, T; s- Z
不管你的状态保存时间设置时间有多长,一律失效,/ S2 q: ~& z% c( E0 n# l
不信可以考试试,^-^。# y5 ? ^, N; C. h: l
, J \/ R* n& h' i9 d
<sessionState
( L0 v' o6 x, N v4 P$ ?! M: w mode="StateServer"6 R$ Y- A# b; q9 i' L7 x
stateConnectionString="tcpip=127.0.0.1:42424"
) P% Z* O% U' m7 j1 i4 j sqlConnectionString="datasource=127.0.0.1;userid=sa;password="7 c/ n- y# [' z$ \7 `6 o0 y
cookieless="false". X0 o1 } p1 c# D, X
timeout="20"/>
& Q! \0 m* ~% g" m
0 ~! h" b; m6 L/ w 情景二中,saved in 数据库
7 P" ]! P& ]- Q* I" O 设置, q3 z, _& G* C8 L7 l* E6 x
mode="SQLServer"。
/ U! p' P5 R; [4 o, v1 p sqlConnectionString="datasource=127.0.0.1;userid=sa;password="。
5 N" h6 Z; W4 z, o1 ~6 [2 | 启动SqlServer和SqlServerAgent。: a! W1 N, P6 Z* i: {6 Z( R
定位到[systemdrive]\winnt\Microsoft.NET\Framework\[version]\。
* O0 x; Z$ D. N s2 w 执行InstallSqlState.sql。) O, S* ]# _! t9 P: }
然后我们看tempdb数据库中多了两个用户表,而且多了一个ASPstate的空库,ASPStateTempApplications和ASPStateTempApplications表中
, o9 }. t$ }7 k, ^! _ 存储的是应用程序信息,每个应用程序在启动的时候在这里会注册一条记录,包括应用程序的ID(通过哈希算法生成的)和应用程序名称,! O! W+ |+ F/ U! ^! ?8 J7 H2 |
实际上Session信息是存储在了tempdb数据库的ASPStateTempSessions表中,另外查看管理->SQLServer代理->作业,
& ~2 A4 S' R* G( p 发现也多了一个叫做ASPState_Job_DeleteExpiredSessions的作业,这个作业实际上就是每分钟去ASPStateTempSessions表中删除过期的Session信息。
" k6 f3 ]( k/ g! i( h% N2 S" O9 E0 X X: [* z
新建一个Asp.netWebSite,按F5,一切OK。3 G3 @( }9 c" P# ]
效果图形 ) C! |7 `7 ?5 f; h
两张表
# w# M# L5 D+ W. L$ @* n3 h! B
% e7 Z x# ], xASPStateTempApplications表的数据
: ]) q/ \7 e' X8 _. i& v
+ b: V2 C2 O" b: c, Q) PASPStateTempSessions表的数据
* R# j |, u S2 v8 g
$ u, p2 L' P. g0 h$ c. h xASPState_Job_DeleteExpiredSessions作业9 h8 w* F/ r6 E/ _5 h& B; {
$ q3 s; d& S3 w
! p/ |# F) m( b9 P$ J S8 A4 Q需要注意的地方;6 y9 N' @5 e& ?% F9 i2 ]+ F5 {& g
y' y) m( U- W8 Y: A5 f4 w* a一,ASPStateTempApplications和ASPStateTempSessions表的权限用户是sa,既管理员。 O" r8 r9 u$ D
二,启动MsSqlSeverAgent,用来执行清除过期Session的作业ASPState_Job_DeleteExpiredSessions。1 I. E6 q' W' ^/ k V) N: W" }
三,如果MsSqlServer与WebSite不在同一台机器上,那么设置sqlConnectionString="datasource=RemoteIP;userid=userName;password=userpwd"% f% |. a3 p6 h' K7 `0 Z( o% W$ W0 H
( S- S& _1 D' a. S9 k! D
结束) t& F2 l) w1 B
写得不妥之处,请多多指教! |