Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / C#6.0

Overloaded Server: Quick Fix

4.09/5 (3 votes)
7 Dec 2015MIT2 min read 8.6K   71  
Review of an approach of increase clustered server performance. Library sample and test utility.

Introduction

Server solutions are designed for high multiuser load and fault tolerance often used scalable architecture (Web Farm for example). In such kind of solution, it is an attractive idea to build stateless server modules (without ASP.NET session for example). Thus, authorization of user/session of each request should be implemented in the server module in a custom way. This tip describes an optimized approach to resolve the issue.

Background

The approach was used to quick fix overloaded Web Service on Web Farm. Web Service receives SessionGUID and before process request makes a request to MS SQL Sessions table to check the session activity and receives User attributes. The fault was caused by unexpected increased number of users of the system and authorization was a bottleneck.

And now I got the idea to rewrite it well, build a performance test and discuss. Perhaps it makes sense to use this approach not only as a hotfix. Maybe this approach can be useful to solve and some other issues of overloaded clusters.

Algorithms

The Task

  • Verify the existence of a session
  • Get corresponding user data with roles of the user
  • Update session activity timestamp (no frequently than is necessary)

The Basic Algorithm

  • At Login: User authentication
  • SessionGUID generation and add Session table record
  • At Request: Check whether there is a record with the SessionGUID
  • Load User with Roles and update Activity timestamp (if needed)
  • At Logoff: Delete Session record with the SessionGUID

Assumptions for Optimization

  • The code is very often executed from parallel threads
  • It does not matter that servers cannot determine instantaneous closing of the session (only during a predetermined period)
  • It does not matter that servers cannot receive user attributes updates instantly (only during a predetermined period)

The Optimization

  • The Session records in-memory cache
  • Use a permanent background thread to refresh the Session records with defined time period
  • When the Cache Manager does not find an entry in the Session cache, it tries to load it from database (because an actual result of the operation should be received immediately and cannot be postponed up to cache refresh)

Using the Code

I used the following test database:

Image 1

Sessions handling implemented in two modes:

C#
// Sessions handling interface
public interface ISessionManager { ... }
// Non cached (RAW) Session Manager
public class SessionManager : ISessionManager { ... }
// Cached Sessions Manager
public class SessionCacheManager : ISessionManager { ... }

Cache controller is implemented in a separate class: SessionCache.

The solution includes a test command line application.

SessionCacheManager uses static fields. In ASP.NET, it may by useful to replace it to an in-process cache storage.

Testing

Execution time of 500 authorization operations, depending on the number of concurrent threads of execution:

Image 2

  • BLUE (basic algorithm) - unexpected deviation at start
  • RED (optimized algorithm) - is stable and expectedly fast

Points of Interest

May be interesting as a sample of usage effective thread lockers: ReaderWriterLockSlim and Interlocked

History

  • December-2015: v1.0.0.1 Initial release

License

This article, along with any associated source code and files, is licensed under The MIT License