ASP.net session 管理1(from msdn)

Best Practices
Fast, Scalable, and Secure Session State Management for Your Web Applications
Michael Volodarsky

Parts of this article are based on a prerelease version of ASP.NET 2.0. Those sections are subject to change.
This article discusses:                                                                               
  • ASP.NET 2.0 session state architecture
  • Improving state management performance and scalability
  • Addressing session state issues in Web farms
  • Securing your state management infrastructure
This article uses the following technologies:                                                                               
ASP.NET
How Session State Works                                                  
Improving Performance                                                  
Disabling Session State                                                  
Reducing Network/Storage Overhead                                                  
Optimizing Serialization                                                  
In-Process Optimizations                                                  
Improving Scalability                                                  
ASP.NET 2.0 Session State Partitioning                                                  
Securing Session State                                                  
Configuring for Security                                                  
Conclusion                                                  
                                        
          Due to the stateless nature of the HTTP protocol, Web applications have always shouldered the burden of user state management. Fortunately, ASP.NET provides a number of ways to maintain user state, the most powerful of which is session state. This feature provides a convenient programmatic interface for associating arbitrary application state with a user session, and takes care of back-end state storage and client session management for the application. This article takes an in-depth look at designing and deploying high-performance, scalable, secure session solutions, and presents best practices for both existing and new ASP.NET session state features straight from the ASP.NET feature team.

How Session State Works
ASP.NET session state lets you associate a server-side string or object dictionary containing state data with a particular HTTP client session. A session is defined as a series of requests issued by the same client within a certain period of time, and is managed by associating a session ID with each unique client. The ID is supplied by the client on each request, either in a cookie or as a special fragment of the request URL. The session data is stored on the server side in one of the supported session state stores, which include in-process memory, SQL Server database, and the ASP.NET State Server service. The latter two modes enable session state to be shared among multiple Web servers on a Web farm and do not require server affinity (that is, they don't require the session to be tied to one specific Web server).
Session state runtime operation is implemented by the SessionStateModule class which plugs into the request processing pipeline in the application as an IHttpModule. SessionStateModule executes once before handler execution in the AcquireRequestState pipeline stage, and once after handler execution in the ReleaseRequestState pipeline stage (see Figure 1). In the AcquireRequestState stage, SessionStateModule attempts to extract the session ID from the request and retrieve the session data for that session ID from the session state store provider. If the session ID is present and the state is retrieved successfully, the module builds the session state dictionary that can be used by the handler to inspect and change the session state.
                                                  
Figure 1  Maintaining Session State 
In ASP.NET 2.0, session extraction is encapsulated in the session ID manager component, which can be replaced by a custom implementation in order to support custom session ID management schemes (for example, storing the session ID in a query string or in form fields). The default session ID manager supports both cookie-based and URL-based session IDs. The default ASP.NET 2.0 session ID manager also provides support for automatically detecting which session ID mode should be used per request based on device profile or runtime negotiation with the client.
If no session ID is present in the request, and the handler makes some changes to the session, a new session ID will be created in the ReleaseRequestState stage, and the new ID will be issued to the client by the session ID manager implementation. In this case, and also if changes were made to an existing session, SessionStateModule will use the state store provider to persist the changes made to session data for that session.
In ASP.NET 2.0, the session state store functionality is encapsulated in the session store provider component, which can be one of the built-in InProc, SQLServer, or StateServer providers, or a custom provider that implements the fetching of session data, the creation of sessions, and the saving of changes to existing sessions.

Improving Performance
Using session state in an ASP.NET application can add noticeable overhead to the application performance. This should be expected as you are executing more code during the processing of every request in the application and possibly making network requests to retrieve stored state. However, there are several techniques your application can take advantage of to reduce the performance impact of session state use while still maintaining the desired state management functionality.
The bulk of the session state processing that occurs on every request resides in SessionStateModule. This module executes once before the ASP.NET request handler to fetch the state for the session identified by the request information, and once after the request handler to create a new session or to save the changes made to the existing session during handler execution.
The InProc session state mode is the fastest of the built-in state storage modes. Its overhead is limited to extracting the session ID from the request, performing a cache lookup for the state dictionary stored in the application's memory space, and marking the session as accessed to prevent its expiration. Updates to the data contained in the session are made directly to objects in memory and do not require any additional work to be persisted for the next request. However, because the InProc mode lacks the application restart tolerance and does not work in Web farm scenarios, the application frequently has no choice but to use one of the other two out-of-process modes.
In the default out-of-process modes, SQLServer and StateServer, session state must be fetched from an external store and deserialized from its binary blob representation to the in-memory state dictionary form in the AcquireRequestState stage. In the ReleaseRequestState stage, the state dictionary needs to be serialized again and transferred to external storage. In addition, the session entry in the store must be updated to indicate the last access time to prevent its expiration. In these modes, serialization and deserialization of the state data, and its out-of-process transfer, are by far the most expensive operations introduced by session state to the request path.
SessionStateModule will perform a number of optimizations by default to avoid overhead wherever possible. These optimizations fall into four categories.
First, for handlers or pages that are not marked as requiring session state, no session state work will be performed except for marking the session as accessed in the store. For pages marked as requiring read-only session state access, only the last-accessed marking and initial data fetching will be done.
Second, until any data is actually saved into the session dictionary, no session will be started for requests that do not already specify a session ID.
Third, on requests where no session state accesses are made or where only read accesses are made to session variables that contain immutable primitive types, no state changes will be persisted to the provider at the end of the request. On requests where mutable session data was accessed or where the session was modified, only the accessed variables will be serialized and the rest will just be copied from their binary blob representations.
And fourth, primitive types are serialized directly, but object types are serialized using the relatively slower BinaryFormatter serialization method.
By taking advantage of these optimizations using the best practices illustrated in this article, you can reduce the performance impact of session state management. The strategies discussed here focus on the three most promising approaches to improving application performance when using session state, taking advantage of the session state performance optimizations:
  • Disabling session state when possible in order to avoid the overhead entirely.
  • Reducing the overhead of the serialization and deserialization of state data.
  • Reducing the overhead of out-of-process transfer of session state to and from the state store.

Disabling Session State
Not all pages in your application will need access to session state. For those pages that do not, you can indicate that session state is not needed and prevent session data from being fetched from the store in requests to these pages.
For pages that do not update session state, you can indicate that read-only access is required. This does not prevent the state data from being fetched, but it results in a read lock being taken on the database, which enables multiple read-only requests to access the session simultaneously and prevents lock contention when multiple requests are made to the server with the same session ID. More importantly, it always prevents the session state module from connecting to the store at the end of the request to update the state (there are other ways to avoid this also, which I'll describe later).
Here's how you disable session state:
                Copy Code                      
<%@ Page EnableSessionState="False" %>
Similarly, this is how you indicate read-only session state:
                Copy Code                      
<%@ Page EnableSessionState="ReadOnly" %>
In fact, most typical pages such as shopping carts will only update the state if the user performs a postback action, like adding or removing an item from the cart, but not when she simply views the shopping cart. You can tweak application performance in this case by separating the viewing of the cart into its own page with read-only session state that does not perform an update. Updating the shopping cart can be separated into another page to which the viewing page posts when an action is requested (cross posting is supported in ASP.NET 2.0).
You can also make the default behavior of the application be read-only or you can turn off session state by default by using the <pages> configuration element in your Web.config file. Then you can explicitly enable session state or enable write access in only the pages that need it by setting the page EnableSessionState attribute appropriately, as shown here:
                Copy Code                      
<!--No session state by default-->
<configuration>
    <system.web>
        <pages enableSessionState="false" />
    </system.web>
</configuration>

<!--Read-only session state by default-->
<configuration>
    <system.web>
        <pages enableSessionState="ReadOnly" />
    </system.web>
</configuration>
Similarly, when you are building custom handlers for processing requests in your application, you can disable session state by default by not implementing the marker interface System.Web.State.IRequiresSessionState in your handler class. You can enable read-only mode by implementing the System.Web.State.IRequiresReadOnlySessionState marker interface instead of System.Web.State.IRequiresSessionState.
Note that if you turn off session state in your application, the HttpContext.Session property will throw an exception if the page or handler tries to access it. If you mark the page as read-only, updates to the session in the out-of-process modes will not be preserved across requests. In InProc mode, however, updates will be preserved because they are made to the live objects that stay memory-resident across requests.
Unfortunately, even when you turn off session state for a particular page or handler, SessionStateModule will still mark the session as accessed in the store, so an out-of-process connection to the store will still be made when not using InProc mode. This is normally desired to prevent session expiration as long as the user is actively making requests to the application, regardless of whether the requests are to resources that require session state. But you may want to disable this behavior for some requests for performance reasons, especially if you are using ASP.NET to serve images and page resources that are contained within a parent ASP.NET page that already has marked the session as active.
To optimize this behavior, you can take advantage of the ASP.NET 2.0 custom session ID generation features to hide the session ID for a request, thereby preventing any session state work for that request. You can do this by implementing a custom type that derives from System.Web.SessionState.SessionIDManager, and then implementing the GetSessionID method to return a null session ID for requests that do not require session state (see Figure 2). For all other requests, you can delegate to the default GetSessionID implementation of the SessionIDManager class, which provides the default cookie and cookieless session ID support in ASP.NET.
                Copy Code                      
public class SessionDisablementIDManager : SessionIDManager
{
    // override the ID management behavior of the session ID manager
    public override String GetSessionID(HttpContext context)
    {
        // do not return the session ID if no session state is 
        // desired for this request
        if (ShouldSkipSessionState(context))
            return null;
        
        // otherwise just delegate to the built-in session
        // ID manager to get the session ID from the request
        else 
            return base.GetSessionID(context);
    }
    
    protected virtual bool ShouldSkipSessionState(HttpContext context) 
    {
        // determine if session state should be skipped for this request
    }
}
                                        
                                        
There are some interesting ways to implement ShouldSkipSessionState that avoid tracking session state. For example, you could skip session state when the request is for one of the extensions specified in your custom configuration section. You could also ignore session state when the current request handler instance (available as HttpContext.Current.CurrentHandler) implements your own ISkipSessionState interface. You can make pages implement this interface by specifying your own page base class.
Another scenario is when the current request handler instance does not implement IRequiresSessionState and there was another recent request with this session ID on which the session was marked as accessed. (You can keep track of this by writing your own custom cookie, or by storing session ID/timestamp pairs in the ASP.NET cache.) For example, if the last request that marked the session as active was less then 30 seconds ago, do not mark it as active now. This achieves the objective and also does not seriously reduce the session activity window.
You can deploy the custom session ID manager code in the App_Code application directory, or you can compile it into an assembly and deploy it to the \Bin application directory or install it into the Global Assembly Cache (GAC). Then, to enable it, register it with session state configuration as follows:
                Copy Code                      
<configuration>
    <system.web>
        <sessionState 
             sessionIDManagerType="IndustryStrengthSessionState. 
                 SessionDisablementIDManager"/>
    </system.web>
</configuration> 
Note that if you employ this technique when using cookieless session IDs, some ASP.NET functionality that generates links or performs redirects that preserve the cookieless session ID will not work for the requests where you return a null ID.

 
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值