惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

量子位
雷峰网
雷峰网
博客园 - 三生石上(FineUI控件)
月光博客
月光博客
有赞技术团队
有赞技术团队
阮一峰的网络日志
阮一峰的网络日志
Last Week in AI
Last Week in AI
G
Google Developers Blog
腾讯CDC
B
Blog
Microsoft Azure Blog
Microsoft Azure Blog
酷 壳 – CoolShell
酷 壳 – CoolShell
Microsoft Security Blog
Microsoft Security Blog
人人都是产品经理
人人都是产品经理
博客园_首页
T
Tailwind CSS Blog
C
Check Point Blog
博客园 - 【当耐特】
MongoDB | Blog
MongoDB | Blog
A
About on SuperTechFans
Y
Y Combinator Blog
L
LangChain Blog
Engineering at Meta
Engineering at Meta
GbyAI
GbyAI

博客园 - Yolion

[转贴]VBA语句集粹 Google奥运会logo [转载]How to test web load balance 离开Cnblogs太久了 Top 10 .NET & C# on Amazon 解析Response对象 看东亚四强赛想到的 招聘ASP.NET(C#)软件工程师(上海) 我与ASP.NET之父Scott Guthrie合影 推荐一款Xml编辑器(XML Notepad) DIV+CSS教程(来自标准之路) 收集不同浏览器下,CSS Hacks 公司尽然把cnblogs给屏蔽了,可恶!!! 大家有没有发现博客园收藏文章不成功的问题 关于用IE7.0开发ASP.NET的一个小问题 CSV文件的注意事项 ASP.NET 2.0中CSS失效的问题总结(摘自孟子E章) sql server系统表详细说明(转) HTML转义字符表
[转贴]ASP.NET Session State Partitioning using State Serv...
Yolion · 2008-02-20 · via 博客园 - Yolion

It seems like amount of posts on ASP.NET's Session State keeps growing. Here's the list:

Yesterday's post on Session State Partitioning used a round-robin method for partitioning session state over different state server machines. The solution I presented actually works, but can still lead to performance bottlenecks.

Let's say you have a web farm running multiple applications, all using the same pool of state server machines. When having multiple sessions in each application, the situation where one state server handles much more sessions than another state server could occur. For that reason, ASP.NET supports real load balancing of all session state servers.

Download example

Want an instant example? Download it here.
Want to know what's behind all this? Please, continue reading.

What we want to achieve...

Here's a scenario: We have different applications running on a web farm. These applications all share the same pool of session state servers. Whenever a session is started, we want to store it on the least-busy state server.

1. Performance counters

To fetch information on the current amount of sessions a state server is storing, we'll use the performance counters ASP.NET state server provides. Here's a code snippet:

if (PerformanceCounterCategory.CounterExists("State Server Sessions Active", "ASP.NET", "STATESERVER1")) {
    PerformanceCounter pc = new PerformanceCounter("ASP.NET", "State Server Sessions Active", "", "STATESERVER1");
    float currentLoad = pc.NextValue();
}

2. Creating a custom session id

Somehow, ASP.NET will have to know on which server a specific session is stored. To do this, let's say we make the first character of the session id the state server id from the following IList:

IList<StateServer> stateServers = new List<StateServer>();

// Id 0, example session id would be 0ywbtzez3eqxut45ukyzq3qp
stateServers.Add(new StateServer("tcpip=10.0.0.1:42424", "sessionserver1"));

// Id 1, example session id would be 1ywbtzez3eqxut45ukyzq3qp
stateServers.Add(new StateServer("tcpip=10.0.0.2:42424", "sessionserver2"));

Next thing we'll have to do is storing these list id's in the session id. For that, we will implement a custom System.Web.SessionState.SessionIDManager class. This class simply creates a regular session id, locates the least-busy state server instance and assign the session to that machine:

using System;
using System.Diagnostics;

public class SessionIdManager : System.Web.SessionState.SessionIDManager
{
    public override string CreateSessionID(System.Web.HttpContext context)
    {
        // Generate a "regular" session id
        string sessionId = base.CreateSessionID(context);

        // Find the least busy state server
        StateServer leastBusyServer = null;
        float leastBusyValue = 0;
        foreach (StateServer stateServer in StateServers.List)
        {
            // Fetch first state server
            if (leastBusyServer == null) leastBusyServer = stateServer;

            // Fetch server's performance counter
            if (PerformanceCounterCategory.CounterExists("State Server Sessions Active", "ASP.NET", stateServer.ServerName))
            {
                PerformanceCounter pc = new PerformanceCounter("ASP.NET", "State Server Sessions Active", "", stateServer.ServerName);
                if (pc.NextValue() < leastBusyValue)
                {
                    leastBusyServer = stateServer;
                    leastBusyValue = pc.NextValue();
                }
            }
        }

        // Modify session id to contain the server's id
        // We will change the first character in the string to be the server's id in the
        // state server list. Notice that this is only for demonstration purposes! (not secure!)
        sessionId = StateServers.List.IndexOf(leastBusyServer).ToString() + sessionId.Substring(1);

        // Return
        return sessionId;
    }
}

The class we created will have to be registered in web.config. Here's how:

<configuration>
  <system.web>
    <!-- ... -->
    <sessionState mode="StateServer"
                partitionResolverType="PartitionResolver"
                sessionIDManagerType="SessionIdManager" />
    <!-- ... -->
  </system.web>
</configuration>

You notice our custom SessionIdManager class is now registered to be the sessionIDManager. The PartitionResolver I blogged about is also present in a modified version.

3. Using the correct state server for a specific session id

In the previous code listing, we assigned a session to a specific server. Now for ASP.NET to read session state from the correct server, we still have to use the PartitionResolver class:

using System;

public class PartitionResolver : System.Web.IPartitionResolver
{

    #region IPartitionResolver Members

    public void Initialize()
    {
        // No need for this!
    }

    public string ResolvePartition(object key)
    {
        // Accept incoming session identifier
        // which looks similar like "2ywbtzez3eqxut45ukyzq3qp"
        string sessionId = key as string;

        // Since we defined the first character in sessionId to contain the
        // state server's list id, strip it off!
        int stateServerId = int.Parse(sessionId.Substring(0, 1));

        // Return the server's connection string
        return StateServers.List[stateServerId].ConnectionString;
    }

    #endregion
}