Wisej.NET
Ask or search…
K

Load Balancing

The features described on this page may not be available for all Wisej.NET Server license editions. For more details, please review the license details for your edition.
Wisej applications are standard web applications and work very well with load balancers.
However, Wisej goes a step further and gives you additional features to manage the load across several servers. You can configure each server running a Wisej application to accept a a maximum number of sessions, or to be available for the load balancer only if the CPU load is below a certain percentage and/or the memory usage is below a certain level.
Wisej applications run using WebSocket connections, which may require your load balancer to be configured to route TCP rather than HTTP. More on this below.

Prepare your Wisej App

There isn't much you need to do to prepare your Wisej apps for load balancing. You may, however, want to configure the healthcheck parameters and decide how much workload can a specific server instance support before returning an error code that signals to the load balance to send the request to the next instance.
Use Add New Item and select Healthcheck from the list of templates, or simply copy and paste the configuration settings below, or download the default HealthCheck.json to override it.
Place it in the application's root folder and set the "Copy to Output Directory" property to "Copy if newer". HealthCheck.json must be in the application's /bin directory to be recognized.
/**
* Health Check
*
* You can modify the default health check configuration by
* placing a HealthCheck.json file in the /bin directory of the
* application.
*
* HealthCheck Properties:
*
* maxMemory: Maximum percentage of allocated memory. Default: 70; 0 = skip.
* maxSessions: Maximum number of active sessions: Default: 100; 0 = skip.
* maxCPU: Maximum CPU load in percentage: Default: 100; 0 = skip.
* returnCode: Http return code to signal that this server is not available. Default: 503.
* retryAfter: Value for the Retry-After header in minutes. Default: 10.
*/
{
"enabled": true,
"maxMemory": 70,
"maxSessions": 100,
"maxCPU": 100,
"returnCode": 503,
"retryAfter": 10
}
HealthCheck.json
920B
Code

Configuration

Wisej needs that the requests from client are routed always to the same server instance. This is usually achieved by configuring your load balancer to either use sticky Sessions, or another type of routing that guarantees that a specific server instance is assigned to user.
Some load balancers need to be configured in TCP mode to route WebSocket connections. Reverse Proxy servers like NGINX are designed to handle WebSocket connections and have all he required settings already available: NGINX as a WebSocket Proxy.

Session

Wisej needs the load balancer to support session affinity: the same user/session must be routed to the same server.
It's usually done using a sticky session cookie, or the client IP hash, or other settings that the load balancer uses to make sure that the same session goes to the same server instance.

Healthcheck

Load balancers check periodically that the server instances they have in their rotation list are actually turned on. To do that, they use a "healthcheck" URL. You may use a custom html (or aspx) page or use healthcheck.wx if you want to make sure that the Wisej routing component is up and running.

HealthCheck.json

Wisej applications automatically respond to the initial Default.html (or the subapplication's URL) requests either by returning the pageor by returning "503 Service Unavailable" (the return code can be configured in HealthCheck.json).
The following list explains each property in the HealthCheck.json configuration file and how to use them. They are not exclusive, wisej will use all of them, if configured, in the order they are listed below:
maxSessions
This is the maximum number of live sessions that a Wisej server will accept before refusing to take on more. It's a lot better to return "503 Service Unavailable" (or the HTML page configured in Default.json) to a new user instead of crashing an entire server under too much load.
Set this value to 0 to ignore it.
maxMemory
The maximum percentage of memory that the server can use before returning "503 Service Unavailable". Setting this value to 70 means that when the main page request arrives and the server is using 70% or more memory it will return "503 Service Unavailable".
Set this value to 0 to ignore it.
maxCPU
The maximum CPU load that the server can take before returning "503 Service Unavailable". Setting this value to 100 means that when the main page request arrives and the server is using 100% of the CPU time it will return "503 Service Unavailable".
Set this value to 0 to ignore it.
returnCode
This is the return code that the /healthcheck.wx request will receive when the server is unavailable to take new sessions. The default is 503. See Status Code Definitions.
503: The server is currently unable to handle the request due to a temporary overloading or maintenance of the server. The implication is that this is a temporary condition which will be alleviated after some delay. If known, the length of the delay MAY be indicated in a Retry-After header. If no Retry-After is given, the client SHOULD handle the response as it would for a 500 response.
retryAfter
he number of minutes to return in the Retry-After header along with the "503 Service Unavailable" response code.
Most load balancers currently ignore this return header.

HealthCheck.IsServerAvailable

You may also install a custom static method that is called by the healthcheck handler. The method returns true if the server is available to the load balancer, or false if it should return 503 (not available).
The code in the IsServerAvailable method can check all sorts of values to determine whether the server is able to accept new sessions.
static class Program {
// static constructor.
static Program() {
Wisej.Core.HealthCheck.IsServerAvailable = Program.IsServerAvailable;
}
static bool IsServerAvailable() {
// this server can be used only on Mondays...
return DateTime.Now.DayOfWeek == DayOfWeek.Monday;
}
}