-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathappLB.js
103 lines (93 loc) · 6.7 KB
/
appLB.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
/* **************************************************************************************************************************************
# * app.js *
# **************************************************************************************************************************************
# * *
# * @License Starts *
# * *
# * Copyright © 2023. MongoExpUser. All Rights Reserved. *
# * *
# * License: MIT - https://github.com/Nodejs-Load-Balancer-On-EC2/blob/main/LICENSE *
# * *
# * @License Ends *
# **************************************************************************************************************************************
# * *
# * Project: NodeJS Load Balancer *
# * *
# * This module deploys a Vanilla NodeJS HTTP or HTTPS Load Balancer Server that: *
# * *
# * 1) Depends on no external framework. *
# * 2) Sits in front of Web Servers or Application Servers and distributes requests. *
# * 3) Uses only native NodeJS modules (https, http, fetch, os, util, path, cluster, fs, and events). *
# * * *
# * Note: *
# * 1) Node.js version: 19+ *
# * 2) Invoke as:sudo node --inspect=$((9233 + $RANDOM % 100)) --trace-warnings --trace-deprecation --watch appLB.js *
# * *
# **************************************************************************************************************************************/
class LoadBalancer
{
constructor()
{
// import modules
const events = require("events");
events.EventEmitter.defaultMaxListeners = 0;
const fs = require("fs");
const os = require("os");
const util = require("util");
const https = require("https");
const http = require("http");
const path = require("path");
const cluster = require("cluster");
const scriptPath = path.resolve(__dirname, "common.js");
let createdMiddlewares = require(`${scriptPath}`);
const LoggerMiddleware = new createdMiddlewares.LoggerMiddleware();
// define local variables
const config = JSON.parse(fs.readFileSync("config.json"));
const port = config.port;
const tlsPort = config.tlsPort;
const host = config.host;
let objs = require(`${scriptPath}`);
const lblServers = config.lblServers;
const lblServersLength = lblServers.length;
let count = 0;
(function createServer()
{
if(cluster.isPrimary)
{
objs.commonClusterStartPrimary(cluster, os, util);
}
else
{
function handleNonTLSRequests(request, response)
{
objs.commonEnforceTLS(request, response);
}
function handleTLSRequests(request, response)
{
// 1. logger middleware: logs and save all load balancer requests
LoggerMiddleware(request, response);
// 2. lbl middleware
const requestUrl = request.url;
const selectServer = lblServers[count];
const lblUrl = `${selectServer}${requestUrl}`;
count === (lblServersLength-1)? count = 0 : count++ // update server count for next request
(async function lblMiddlewareResponse()
{
response.write("");
const method = (request.method).toUpperCase();
const options = { method: method };
const lbResponse = await fetch(lblUrl, options);
const html = await lbResponse.text();
response.end(html);
}());
}
const server = http.createServer(handleNonTLSRequests);
const tlsServer = https.createServer(objs.commonOptionsTLS(), handleTLSRequests);
server.listen(port, function listenOnServer() { console.log(`Non-TLS redirect server is listening on http://${host}:${port}/ ...`) }).setMaxListeners(0);
tlsServer.listen(tlsPort, function listenOnServer() { console.log(`TLS server is listening on https://${host}:${tlsPort}/ ...`) }).setMaxListeners(0);
}
}());
}
}
new LoadBalancer();
module.exports = { LoadBalancer };