diff --git a/content/posts/nginx-load-balancing.md b/content/posts/nginx-load-balancing.md new file mode 100644 index 0000000..4db236a --- /dev/null +++ b/content/posts/nginx-load-balancing.md @@ -0,0 +1,208 @@ +--- +title: Load Balancing and Static File Serving with NGINX +author: Shashank Shekhar +date: 2024-10-13 +--- + +![alt text](/nginx-load-balancing.png) + +NGINX is a popular web server often used to host Node.js applications in production. It provides features like **load balancing**, **proxying**, **reverse proxy**, and **static file serving** out of the box. + +#### Serving Web Apps with NGINX + +Today, we will perform a simple exercise using a basic JavaScript backend to demonstrate the **load balancing** capabilities of the NGINX web server. Alongside the backend server script, we’ll also host a single webpage on NGINX to showcase static file serving. + +As usual, code examples are available in my [GitHub repository](https://github.com/thatShashankGuy/code-examples/tree/master/nginx-load-balancer). Let’s get started! + +In this exercise, our web page will send a request to the backend, and the backend will respond with a joke. We will simulate load balancing among different servers by running our backend script on four separate ports. The backend script will check the `PORT` value for each request and return a **port-specific joke** to the webpage. + +--- + +### Exercise: Random Joke Generator + +Here is the code for the backend server and the web page. + +#### `index.html` + +```html + + + + + + Joke Balancing with NGINX + + +

Here are Random Jokes

+

With each request the server responds to, NGINX will serve a port-specific joke.

+
JOKE FROM PORT: waiting...
+
Fetching a joke from the server...
+ + + + +``` + +#### `server.js` + +```js +const http = require('http'); +const os = require('os'); + +const PORT = process.env.PORT || "3000"; + +http.createServer((req, res) => { + let joke = `THIS IS SERIOUS BUSINESS`; + switch (PORT) { + case "3000": + joke = `Why don't skeletons fight each other? Because they don't have the guts.`; + break; + case "8080": + joke = `What do you call fake spaghetti? An impasta!`; + break; + case "1313": + joke = `Why did the scarecrow win an award? Because he was outstanding in his field!`; + break; + case "1517": + joke = `Why don’t eggs tell jokes? Because they might crack up!`; + break; + default: + break; + } + + console.log(JSON.stringify({ port: PORT, joke })); + + res.writeHead(200, { 'Content-Type': 'application/json' }); + res.end(JSON.stringify({ port: PORT, joke })); +}).listen(PORT, () => { + console.log(`Server running at http://localhost:${PORT}/`); +}); +``` + +#### A Script to Start All Servers Together + +```bash +#!/bin/bash + +PORTS=(3000 8080 1313 1517) +SERVER_JS_PATH="./server.js" + +for PORT in "${PORTS[@]}" +do + echo "Starting server.js on port $PORT" + PORT=$PORT nohup node $SERVER_JS_PATH > logs/server_$PORT.log 2>&1 & +done + +echo "All servers started." +``` + +--- + +### Configuring NGINX for Our Web App + +Before configuring NGINX, you need to [install NGINX](https://nginx.org/en/docs/install.html) on your system. You can check if NGINX is installed by running the following command: + +```bash +nginx -v +``` + +The behavior of NGINX is determined by its configuration file, typically named `nginx.conf`. By default, this file is located in directories such as `/etc/nginx` or `/usr/local/etc/nginx`, but for this demonstration, we will keep the `nginx.conf` file in the same directory as the project files. + +You can read the configuration file with the following command: + +```bash +nginx -c /your/path/to/code-examples/nginx-load-balancer/nginx.conf +``` + +Before running the server, it’s always a good idea to test the configuration using the `-t` flag: + +```bash +nginx -t -c /your/path/to/code-examples/nginx-load-balancer/nginx.conf +``` + +#### NGINX Configuration (`nginx.conf`) + +```bash +events { + worker_connections 1024; +} + +http { + upstream backend { + server 127.0.0.1:3000; + server 127.0.0.1:8080; + server 127.0.0.1:1313; + server 127.0.0.1:1517; + } + + server { + listen 80; + server_name localhost; + + location / { + root code-examples/nginx-load-balancer; + index index.html; + } + + location /api/data { + proxy_pass http://backend; + } + } +} +``` + +--- + +### Explaining the NGINX Configuration + +**Worker Connections**: In the `events` block, we configured NGINX to handle 1024 simultaneous connections per worker. This optimizes how NGINX deals with incoming requests. + +**Upstream Block**: The `upstream` block defines a pool of backend servers, each running on a different port (3000, 8080, 1313, and 1517). NGINX will distribute the load across these servers using a **round-robin method**, sending each request to a different server in turn. + + + **Port 80**: NGINX listens on port 80, which is the default HTTP port. + + **Serving Static Files**: When a request is made to `/`, NGINX serves the static HTML file (`index.html`) located in the `code-examples/nginx-load-balancer` directory. + + **Proxying Requests**: When a request is made to `/api/data`, NGINX acts as a **proxy** and forwards the request to one of the backend servers, which will respond with a port-specific joke. + +--- + +### Testing the Web Application + +Once everything is set up, open a browser and go to `http://localhost`. Each time you refresh the page, NGINX will serve the static HTML file and fetch data from different backend servers running on different ports, showing a new joke with each request. + +Request 1 +![image not found](/nginx-req1.png) + +Request 2 +![image not found](/nginx-req2.png) + +--- + +### Conclusion + +In this article, we explored how to use NGINX to serve a Node.js application, demonstrating its **load-balancing**, **proxying**, and **static file serving** capabilities. NGINX is a popular choice in the Node.js ecosystem for production environments, thanks to its efficiency and powerful features. + +This is a basic example demonstrating some of NGINX's capabilities. In future exercises, we will explore more features such as caching, reverse proxying, and SSL/TLS configuration. + +--- + +### Further Reading +- [What is a Web Server?](https://developer.mozilla.org/en-US/docs/Learn/Common_questions/Web_mechanics/What_is_a_web_server) +- [NGINX Beginner's Guide](https://nginx.org/en/docs/beginners_guide.html) +- [Load Balancing Node.js Applications on NGINX](https://docs.nginx.com/nginx/deployment-guides/load-balance-third-party/node-js/) +- [Apache vs IIS vs NGINX: Web Server Comparison](https://www.linuxcareers.com/resources/blog/2023/07/apache-vs-iis-vs-nginx-an-in-depth-comparison-of-web-servers/) + +As always, happy coding! diff --git a/public/404.html b/public/404.html index 81965f4..8f28713 100644 --- a/public/404.html +++ b/public/404.html @@ -75,8 +75,8 @@

Read more

-

Chat server with Websocket in Node JS

-
Oct 6, 2024
+

Load Balancing and Static File Serving with NGINX

+
Oct 13, 2024
@@ -84,8 +84,8 @@

Chat server with Webs
-

Build Custom Browser Extensions with Javascript

-
Sep 23, 2024
+

Chat server with Websocket in Node JS

+
Oct 6, 2024
diff --git a/public/404/page/2/index.html b/public/404/page/2/index.html index 9565ac0..5f9dc94 100644 --- a/public/404/page/2/index.html +++ b/public/404/page/2/index.html @@ -75,8 +75,8 @@

Read more

-

Building Web APIs in Go - StoreFM#2

-
Aug 25, 2024
+

Build Custom Browser Extensions with Javascript

+
Sep 23, 2024
@@ -84,8 +84,8 @@

Building Web APIs in Go - StoreFM
-

Working with Go's Standard Library - StoreFM#1

-
Aug 18, 2024
+

Building Web APIs in Go - StoreFM#2

+
Aug 25, 2024
diff --git a/public/404/page/3/index.html b/public/404/page/3/index.html index 3916210..82a1201 100644 --- a/public/404/page/3/index.html +++ b/public/404/page/3/index.html @@ -75,8 +75,8 @@

Read more

-

Garbage Collection in JavaScript

-
Aug 10, 2024
+

Working with Go's Standard Library - StoreFM#1

+
Aug 18, 2024
@@ -84,8 +84,8 @@

Garbage Collec
-

Profiling Your Node.js Production Code

-
Aug 4, 2024
+

Garbage Collection in JavaScript

+
Aug 10, 2024
diff --git a/public/404/page/4/index.html b/public/404/page/4/index.html index 99c70c5..676cb7e 100644 --- a/public/404/page/4/index.html +++ b/public/404/page/4/index.html @@ -75,8 +75,8 @@

Read more

-

Learn to Love Boring

-
Jun 11, 2024
+

Profiling Your Node.js Production Code

+
Aug 4, 2024
@@ -84,8 +84,8 @@

Learn to Love Boring
-

Database Paradigms - ACID, BASE and CAP in brief

-
Jan 8, 2024
+

Learn to Love Boring

+
Jun 11, 2024
diff --git a/public/404/page/5/index.html b/public/404/page/5/index.html index ea15aba..800d5a8 100644 --- a/public/404/page/5/index.html +++ b/public/404/page/5/index.html @@ -75,8 +75,8 @@

Read more

-

Coding My Way Out of Burnout

-
Dec 25, 2023
+

Database Paradigms - ACID, BASE and CAP in brief

+
Jan 8, 2024
@@ -84,8 +84,8 @@

Coding My Way Out of Burnout

-

Async IO programming with Node js

-
Dec 15, 2023
+

Coding My Way Out of Burnout

+
Dec 25, 2023
diff --git a/public/404/page/6/index.html b/public/404/page/6/index.html index 99862cd..a9df1a1 100644 --- a/public/404/page/6/index.html +++ b/public/404/page/6/index.html @@ -75,8 +75,8 @@

Read more

-

Reference Articles and Whitepapers

-
Nov 15, 2023
+

Async IO programming with Node js

+
Dec 15, 2023
@@ -84,7 +84,7 @@

Reference Articles and Whitepapers
-

The Typescript Programming Guide

+

Reference Articles and Whitepapers

Nov 15, 2023
diff --git a/public/404/page/7/index.html b/public/404/page/7/index.html index 664a1b3..adf7503 100644 --- a/public/404/page/7/index.html +++ b/public/404/page/7/index.html @@ -75,8 +75,8 @@

Read more

-

Go Basics - Error as values

-
Oct 29, 2023
+

The Typescript Programming Guide

+
Nov 15, 2023
@@ -84,8 +84,8 @@

Go Basics - Error as values
-

Go Basics - Map and Structs

-
Oct 9, 2023
+

Go Basics - Error as values

+
Oct 29, 2023
diff --git a/public/404/page/8/index.html b/public/404/page/8/index.html index c49e7dc..0ae6733 100644 --- a/public/404/page/8/index.html +++ b/public/404/page/8/index.html @@ -75,8 +75,8 @@

Read more

-

Go Basics - Arrays vs Slices

-
Aug 11, 2023
+

Go Basics - Map and Structs

+
Oct 9, 2023
@@ -84,8 +84,8 @@

Go Basics - Arrays vs Slices
-

Go Basics - Pointers

-
Jul 20, 2023
+

Go Basics - Arrays vs Slices

+
Aug 11, 2023
diff --git a/public/404/page/9/index.html b/public/404/page/9/index.html new file mode 100644 index 0000000..7cf1159 --- /dev/null +++ b/public/404/page/9/index.html @@ -0,0 +1,160 @@ + + + + PrintF/ScanF + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+
+ +

404 - Page Not Found

+ + + +
The content you're looking for doesn't seem to exist.
+ +
+ + +

Read more

+ + + + + + + + + + +
+
+

Go Basics - Pointers

+
Jul 20, 2023
+
+
+ +
+ +
+ + + + + + + diff --git a/public/index.html b/public/index.html index a5dde3a..071cda4 100644 --- a/public/index.html +++ b/public/index.html @@ -72,15 +72,15 @@

PrintF/ScanF

-

Chat server with Websocket in Node JS

+

Load Balancing and Static File Serving with NGINX

- +
-
WebSockets are powerful tools for real-time communication, allowing clients and servers to maintain an open connection and exchange data freely. This makes them ideal for building interactive applications like chat systems, real-time collaboration tools, and multiplayer games. -In this blog post, we’ll walk through creating a WebSocket server in Node.js using the ws library. We’ll maintain a queue of connected clients, notify users when new clients join or leave, and ensure every client stays up-to-date with the current lobby status.
+
NGINX is a popular web server often used to host Node.js applications in production. It provides features like load balancing, proxying, reverse proxy, and static file serving out of the box. +Serving Web Apps with NGINX 🔗Today, we will perform a simple exercise using a basic JavaScript backend to demonstrate the load balancing capabilities of the NGINX web server. Alongside the backend server script, we’ll also host a single webpage on NGINX to showcase static file serving.
@@ -89,16 +89,15 @@

Chat server with Webs
-

Build Custom Browser Extensions with Javascript

+

Chat server with Websocket in Node JS

- +
-
In this quick article, we will learn how to build a browser extension to manipulate some website behavior for your personal use. -What is a Browser Extension? 🔗A browser extension is essentially a small software program that adds custom functionality to your web browser. Extensions can help you take notes, manage passwords, block ads, and more. -They can be installed in most modern browsers like Chrome, Firefox, Edge, etc. Often, an extension can be downloaded and installed from a web store, like the Chrome Web Store.
+
WebSockets are powerful tools for real-time communication, allowing clients and servers to maintain an open connection and exchange data freely. This makes them ideal for building interactive applications like chat systems, real-time collaboration tools, and multiplayer games. +In this blog post, we’ll walk through creating a WebSocket server in Node.js using the ws library. We’ll maintain a queue of connected clients, notify users when new clients join or leave, and ensure every client stays up-to-date with the current lobby status.
diff --git a/public/index.xml b/public/index.xml index 0e8879e..6248231 100644 --- a/public/index.xml +++ b/public/index.xml @@ -6,8 +6,15 @@ Recent content on PrintF/ScanF Hugo en-us - Sun, 06 Oct 2024 00:00:00 +0000 + Sun, 13 Oct 2024 00:00:00 +0000 + + Load Balancing and Static File Serving with NGINX + https://printf-scanf.pages.dev/posts/nginx-load-balancing/ + Sun, 13 Oct 2024 00:00:00 +0000 + https://printf-scanf.pages.dev/posts/nginx-load-balancing/ + NGINX is a popular web server often used to host Node.js applications in production. It provides features like load balancing, proxying, reverse proxy, and static file serving out of the box. Serving Web Apps with NGINX 🔗Today, we will perform a simple exercise using a basic JavaScript backend to demonstrate the load balancing capabilities of the NGINX web server. Alongside the backend server script, we’ll also host a single webpage on NGINX to showcase static file serving. + Chat server with Websocket in Node JS https://printf-scanf.pages.dev/posts/web-socket-chat-server/ diff --git a/public/nginx-load-balancing.png b/public/nginx-load-balancing.png new file mode 100644 index 0000000..af21bb8 Binary files /dev/null and b/public/nginx-load-balancing.png differ diff --git a/public/nginx-req1.png b/public/nginx-req1.png new file mode 100644 index 0000000..956cac3 Binary files /dev/null and b/public/nginx-req1.png differ diff --git a/public/nginx-req2.png b/public/nginx-req2.png new file mode 100644 index 0000000..9e7688d Binary files /dev/null and b/public/nginx-req2.png differ diff --git a/public/page/2/index.html b/public/page/2/index.html index be257ce..6dd1dfb 100644 --- a/public/page/2/index.html +++ b/public/page/2/index.html @@ -72,16 +72,16 @@

PrintF/ScanF

-

Building Web APIs in Go - StoreFM#2

+

Build Custom Browser Extensions with Javascript

- +
-
This is a continuation of the Store FM series, where we discuss web application development with Go and analyze the Go standard library. In the previous article, we set up our project with a Go backend and an HTML+HTMX frontend. -Today, we will be analyzing how to work with various API endpoints through which our frontend interacts with the server. -We will focus on three packages from the standard library in this article:
+
In this quick article, we will learn how to build a browser extension to manipulate some website behavior for your personal use. +What is a Browser Extension? 🔗A browser extension is essentially a small software program that adds custom functionality to your web browser. Extensions can help you take notes, manage passwords, block ads, and more. +They can be installed in most modern browsers like Chrome, Firefox, Edge, etc. Often, an extension can be downloaded and installed from a web store, like the Chrome Web Store.
@@ -90,15 +90,16 @@

Building Web APIs in Go - StoreFM
-
Introduction 🔗In my previous posts, we discussed Go’s syntax and how it allows developers to write C-like code for modern development. While we will continue to explore the language specifications in detail, another aspect of Go that stands out is its modern standard library. -The Go standard library is simply one of the best—if not the best—I have ever used. Many quality-of-life libraries and tools that might require third-party dependencies in other languages are available out of the box in Go’s standard library.
+
This is a continuation of the Store FM series, where we discuss web application development with Go and analyze the Go standard library. In the previous article, we set up our project with a Go backend and an HTML+HTMX frontend. +Today, we will be analyzing how to work with various API endpoints through which our frontend interacts with the server. +We will focus on three packages from the standard library in this article:
diff --git a/public/page/3/index.html b/public/page/3/index.html index 037b191..4ec91d4 100644 --- a/public/page/3/index.html +++ b/public/page/3/index.html @@ -72,16 +72,15 @@

PrintF/ScanF

-

Garbage Collection in JavaScript

+

Working with Go's Standard Library - StoreFM#1

- +
-
What is Garbage Collection? 🔗Unlike low-level languages like C, where memory management (allocation and freeing of memory) is handled by developers, high-level languages like JavaScript manage memory automatically. JavaScript abstracts the key concepts of allocating and freeing memory by implementing various algorithms. -The process of identifying memory that has been allocated but is no longer required by the program, referred to as garbage, is known as garbage collection. -Garbage Collection Algorithms 🔗There are many garbage collection algorithms, such as Mark and Sweep, Reference Counting, Generational Garbage Collection, and Mark-Compact, among others.
+
Introduction 🔗In my previous posts, we discussed Go’s syntax and how it allows developers to write C-like code for modern development. While we will continue to explore the language specifications in detail, another aspect of Go that stands out is its modern standard library. +The Go standard library is simply one of the best—if not the best—I have ever used. Many quality-of-life libraries and tools that might require third-party dependencies in other languages are available out of the box in Go’s standard library.
@@ -90,14 +89,16 @@

Garbage Collec
-
Introduction 🔗When building and running code on a production server, it’s crucial to be aware of memory usage, CPU cycles, and other key performance indicators (KPIs) like the time complexity and duration of function calls. Software engineers often obtain and analyze these KPIs to optimize running programs and debug issues, such as memory leaks and CPU utilization, which are difficult to catch in a development environment. This activity is called profiling.
+
What is Garbage Collection? 🔗Unlike low-level languages like C, where memory management (allocation and freeing of memory) is handled by developers, high-level languages like JavaScript manage memory automatically. JavaScript abstracts the key concepts of allocating and freeing memory by implementing various algorithms. +The process of identifying memory that has been allocated but is no longer required by the program, referred to as garbage, is known as garbage collection. +Garbage Collection Algorithms 🔗There are many garbage collection algorithms, such as Mark and Sweep, Reference Counting, Generational Garbage Collection, and Mark-Compact, among others.
diff --git a/public/page/4/index.html b/public/page/4/index.html index c893cc2..56d451b 100644 --- a/public/page/4/index.html +++ b/public/page/4/index.html @@ -72,17 +72,14 @@

PrintF/ScanF

-

Learn to Love Boring

+

Profiling Your Node.js Production Code

- +
-
This is not my usual technical/CSE adjacent post. My articles are mostly tech-related, but I wanted to discuss something different today. -For the past few months, precisely six, I have not been writing anything. I re-did my Svelte SPA site and turned it into this Hugo based SSG, removing the clutter to focus on writing. -But as you see, I have not written anything since last year. Why? -Firstly, in the past quarter, I switched jobs, and the transitional period comes with a lot of uncertainty in routine.
+
Introduction 🔗When building and running code on a production server, it’s crucial to be aware of memory usage, CPU cycles, and other key performance indicators (KPIs) like the time complexity and duration of function calls. Software engineers often obtain and analyze these KPIs to optimize running programs and debug issues, such as memory leaks and CPU utilization, which are difficult to catch in a development environment. This activity is called profiling.
@@ -91,16 +88,17 @@

Learn to Love Boring
-

Database Paradigms - ACID, BASE and CAP in brief

+

Learn to Love Boring

- +
-
When starting a project, one of the earliest design decisions you need to make is selecting a database. There are various databases available in the market. -Initially, most databases were of SQL flavors, grouped as Relational Databases, and they used the de facto method of saving data into tables and establishing relationships between these tables. You can read more about History of SQL. -However, with the advent of NoSQL databases, this paradigm was challenged, opting for a more relaxed and schema-less approach, saving data as objects rather than in rigid tables with relationships.
+
This is not my usual technical/CSE adjacent post. My articles are mostly tech-related, but I wanted to discuss something different today. +For the past few months, precisely six, I have not been writing anything. I re-did my Svelte SPA site and turned it into this Hugo based SSG, removing the clutter to focus on writing. +But as you see, I have not written anything since last year. Why? +Firstly, in the past quarter, I switched jobs, and the transitional period comes with a lot of uncertainty in routine.
diff --git a/public/page/5/index.html b/public/page/5/index.html index f9706bb..91e3df7 100644 --- a/public/page/5/index.html +++ b/public/page/5/index.html @@ -72,16 +72,16 @@

PrintF/ScanF

-

Coding My Way Out of Burnout

+

Database Paradigms - ACID, BASE and CAP in brief

- +
-
About three months ago, I felt intense pressure in my career. I did not feel like learning anything, and doing my job was a struggle. At that point in time, I didn’t understand what was going on, but now I know I was going through a phase of burnout. -Burnouts are quite common in the workforce, and you will find hundreds of people sharing their stories of burnout. -One thing you will come across quite often when you search for ‘how to deal with burnouts in tech’ is to just take a break.
+
When starting a project, one of the earliest design decisions you need to make is selecting a database. There are various databases available in the market. +Initially, most databases were of SQL flavors, grouped as Relational Databases, and they used the de facto method of saving data into tables and establishing relationships between these tables. You can read more about History of SQL. +However, with the advent of NoSQL databases, this paradigm was challenged, opting for a more relaxed and schema-less approach, saving data as objects rather than in rigid tables with relationships.
@@ -90,15 +90,16 @@

Coding My Way Out of Burnout

-

Async IO programming with Node js

+

Coding My Way Out of Burnout

- +
-
Introduction 🔗Asynchronous programming is a technique that enables your program to start a potentially long-running task and still be able to be responsive to other events while that task runs, rather than having to wait until that task has finished. -Consider Node/ Browser Architecture , When program starts it start a main thread on which wil run your javascript program . While one set of instructions ( code ) is running on this thread the thread is busy
+
About three months ago, I felt intense pressure in my career. I did not feel like learning anything, and doing my job was a struggle. At that point in time, I didn’t understand what was going on, but now I know I was going through a phase of burnout. +Burnouts are quite common in the workforce, and you will find hundreds of people sharing their stories of burnout. +One thing you will come across quite often when you search for ‘how to deal with burnouts in tech’ is to just take a break.
diff --git a/public/page/6/index.html b/public/page/6/index.html index b82df5f..bc54cda 100644 --- a/public/page/6/index.html +++ b/public/page/6/index.html @@ -72,17 +72,15 @@

PrintF/ScanF

-

Reference Articles and Whitepapers

+

Async IO programming with Node js

- +
-
How the clipboard works -Intelligent Scaling in Amazon RedShift -Pycoder Weekly -Javascript Hidden Classes
+
Introduction 🔗Asynchronous programming is a technique that enables your program to start a potentially long-running task and still be able to be responsive to other events while that task runs, rather than having to wait until that task has finished. +Consider Node/ Browser Architecture , When program starts it start a main thread on which wil run your javascript program . While one set of instructions ( code ) is running on this thread the thread is busy
@@ -91,14 +89,17 @@

Reference Articles and Whitepapers
-

The Typescript Programming Guide

+

Reference Articles and Whitepapers

-
Introduction 🔗By now, TypeScript has emerged as a fully-fledged de facto standard for writing secure, enterprise-grade Node apps. I am building this guide from my experience and the TypeScript handbook to offer a brief introduction for those transitioning from JavaScript but please beware I am no SME on typescript. Readers should have some familiarity with JavaScript and Object-Oriented Programming (OOP). As we all are busy people I have kept the guide as concise as possible while being as clear as I can.
+
How the clipboard works +Intelligent Scaling in Amazon RedShift +Pycoder Weekly +Javascript Hidden Classes
diff --git a/public/page/7/index.html b/public/page/7/index.html index c3bde35..3d60c42 100644 --- a/public/page/7/index.html +++ b/public/page/7/index.html @@ -72,16 +72,14 @@

PrintF/ScanF

-

Go Basics - Error as values

+

The Typescript Programming Guide

- +
-
Error Handling in Go is bit different than traditional way you must have seen in programming in languages like JavaScript . Instead of traditional “Try/Catch” Go use something called error as values. -Go, like most statically-typed languages, mandates that you define the return type of your functions. In order to understand Error handling we must first understand return types . -Let’s dive in by creating a basic function, demoFunc, that accepts a string argument and returns it in all lowercase letters.
+
Introduction 🔗By now, TypeScript has emerged as a fully-fledged de facto standard for writing secure, enterprise-grade Node apps. I am building this guide from my experience and the TypeScript handbook to offer a brief introduction for those transitioning from JavaScript but please beware I am no SME on typescript. Readers should have some familiarity with JavaScript and Object-Oriented Programming (OOP). As we all are busy people I have kept the guide as concise as possible while being as clear as I can.
@@ -90,15 +88,16 @@

Go Basics - Error as values
-
While arrays and slices form the core of sequential data structures, maps, interfaces, and structs offer unique capabilities, especially when transitioning from a language like TypeScript. Lets talk about them today. -Maps: Go’s Key-Value Store: 🔗A map in Go is a composite type that represents a hash table or a dictionary or object/map in typescript’s case. It associates keys and values where each key maps to a unique value. The key can be of any type for which the equality operation is defined, such as integers, floats, strings, etc.
+
Error Handling in Go is bit different than traditional way you must have seen in programming in languages like JavaScript . Instead of traditional “Try/Catch” Go use something called error as values. +Go, like most statically-typed languages, mandates that you define the return type of your functions. In order to understand Error handling we must first understand return types . +Let’s dive in by creating a basic function, demoFunc, that accepts a string argument and returns it in all lowercase letters.
diff --git a/public/page/8/index.html b/public/page/8/index.html index 3a7faf6..4dbee2b 100644 --- a/public/page/8/index.html +++ b/public/page/8/index.html @@ -72,16 +72,15 @@

PrintF/ScanF

-

Go Basics - Arrays vs Slices

+

Go Basics - Map and Structs

- +
-
With this article I have tried giving a brief overview of two fundamental data structures in the Go programming language: arrays and slices. This may help anyone coming from a dynamic language to Go and understand the basics of couple of most used data structures in all programs . -Arrays -Arrays are fundamental data structures in the Go programming language that allow you to store and manage collections of elements of the same type.
+
While arrays and slices form the core of sequential data structures, maps, interfaces, and structs offer unique capabilities, especially when transitioning from a language like TypeScript. Lets talk about them today. +Maps: Go’s Key-Value Store: 🔗A map in Go is a composite type that represents a hash table or a dictionary or object/map in typescript’s case. It associates keys and values where each key maps to a unique value. The key can be of any type for which the equality operation is defined, such as integers, floats, strings, etc.
@@ -90,15 +89,16 @@

Go Basics - Arrays vs Slices
-

Go Basics - Pointers

+

Go Basics - Arrays vs Slices

- +
-
In Go, a pointer is a variable that stores the memory address of another variable. We use the ampersand (&) operator to get the memory address of a variable, and the asterisk (*) operator to declare a pointer variable or to access the value pointed to by a pointer. -In the example code provided, p is a pointer to the variable x. We can use the * operator to access the value stored in the memory location pointed to by p.
+
With this article I have tried giving a brief overview of two fundamental data structures in the Go programming language: arrays and slices. This may help anyone coming from a dynamic language to Go and understand the basics of couple of most used data structures in all programs . +Arrays +Arrays are fundamental data structures in the Go programming language that allow you to store and manage collections of elements of the same type.
@@ -115,6 +115,12 @@

Go Basics - Pointers

+ + + Older posts + + + diff --git a/public/page/9/index.html b/public/page/9/index.html new file mode 100644 index 0000000..040c679 --- /dev/null +++ b/public/page/9/index.html @@ -0,0 +1,181 @@ + + + + PrintF/ScanF + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + avatar + + +

PrintF/ScanF

+ + +
+ +
+ + + + + +
+
+

Go Basics - Pointers

+
+ +
+
+ + +
In Go, a pointer is a variable that stores the memory address of another variable. We use the ampersand (&) operator to get the memory address of a variable, and the asterisk (*) operator to declare a pointer variable or to access the value pointed to by a pointer. +In the example code provided, p is a pointer to the variable x. We can use the * operator to access the value stored in the memory location pointed to by p.
+ + +
+ + + + + + + +
+ +
+ + + + + + + diff --git a/public/posts/index.html b/public/posts/index.html index fa6e7fe..246a436 100644 --- a/public/posts/index.html +++ b/public/posts/index.html @@ -74,6 +74,19 @@

+ +
diff --git a/public/posts/index.xml b/public/posts/index.xml index 2a29712..20de0ac 100644 --- a/public/posts/index.xml +++ b/public/posts/index.xml @@ -6,8 +6,15 @@ Recent content in Posts on PrintF/ScanF Hugo en-us - Sun, 06 Oct 2024 00:00:00 +0000 + Sun, 13 Oct 2024 00:00:00 +0000 + + Load Balancing and Static File Serving with NGINX + https://printf-scanf.pages.dev/posts/nginx-load-balancing/ + Sun, 13 Oct 2024 00:00:00 +0000 + https://printf-scanf.pages.dev/posts/nginx-load-balancing/ + NGINX is a popular web server often used to host Node.js applications in production. It provides features like load balancing, proxying, reverse proxy, and static file serving out of the box. Serving Web Apps with NGINX 🔗Today, we will perform a simple exercise using a basic JavaScript backend to demonstrate the load balancing capabilities of the NGINX web server. Alongside the backend server script, we’ll also host a single webpage on NGINX to showcase static file serving. + Chat server with Websocket in Node JS https://printf-scanf.pages.dev/posts/web-socket-chat-server/ diff --git a/public/posts/nginx-load-balancing/index.html b/public/posts/nginx-load-balancing/index.html new file mode 100644 index 0000000..f3e6ba3 --- /dev/null +++ b/public/posts/nginx-load-balancing/index.html @@ -0,0 +1,303 @@ + + + + Load Balancing and Static File Serving with NGINX | PrintF/ScanF + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+

Load Balancing and Static File Serving with NGINX

+ +
+ + + · + + + 835 words + + + · + + + 4 minute read + +
+ + + + + +
+

+ alt text +

+

NGINX is a popular web server often used to host Node.js applications in production. It provides features like load balancing, proxying, reverse proxy, and static file serving out of the box.

+

Serving Web Apps with NGINX 🔗

Today, we will perform a simple exercise using a basic JavaScript backend to demonstrate the load balancing capabilities of the NGINX web server. Alongside the backend server script, we’ll also host a single webpage on NGINX to showcase static file serving.

+

As usual, code examples are available in my GitHub repository. Let’s get started!

+

In this exercise, our web page will send a request to the backend, and the backend will respond with a joke. We will simulate load balancing among different servers by running our backend script on four separate ports. The backend script will check the PORT value for each request and return a port-specific joke to the webpage.

+
+

Exercise: Random Joke Generator 🔗

Here is the code for the backend server and the web page.

+

index.html 🔗

<!DOCTYPE html>
+<html lang="en">
+<head>
+    <meta charset="UTF-8">
+    <meta name="viewport" content="width=device-width, initial-scale=1.0">
+    <title>Joke Balancing with NGINX</title>
+</head>
+<body>
+    <h1>Here are Random Jokes</h1>
+    <p>With each request the server responds to, NGINX will serve a port-specific joke.</p>
+    <div>JOKE FROM PORT: <b><i id="server-port">waiting...</i></b></div>
+    <div id="server-response">Fetching a joke from the server...</div>
+
+    <script>
+        fetch('/api/data')
+            .then(response => response.json())
+            .then(data => {
+                document.getElementById('server-response').innerText = data.joke;
+                document.getElementById('server-port').innerText = data.port;
+            })
+            .catch(error => {
+                document.getElementById('server-response').innerText = 'Error fetching data';
+                console.error('Error:', error);
+            });
+    </script>
+</body>
+</html>
+

server.js 🔗

const http = require('http');
+const os = require('os');
+
+const PORT = process.env.PORT || "3000";
+
+http.createServer((req, res) => {
+    let joke = `THIS IS SERIOUS BUSINESS`;
+    switch (PORT) {
+        case "3000":
+            joke = `Why don't skeletons fight each other? Because they don't have the guts.`;
+            break;
+        case "8080":
+            joke = `What do you call fake spaghetti? An impasta!`;
+            break;
+        case "1313":
+            joke = `Why did the scarecrow win an award? Because he was outstanding in his field!`;
+            break;
+        case "1517":
+            joke = `Why don’t eggs tell jokes? Because they might crack up!`;
+            break;
+        default:
+            break;
+    }    
+
+    console.log(JSON.stringify({ port: PORT, joke }));
+
+    res.writeHead(200, { 'Content-Type': 'application/json' });
+    res.end(JSON.stringify({ port: PORT, joke }));
+}).listen(PORT, () => {
+    console.log(`Server running at http://localhost:${PORT}/`);
+});
+

A Script to Start All Servers Together 🔗

#!/bin/bash
+
+PORTS=(3000 8080 1313 1517)
+SERVER_JS_PATH="./server.js"
+
+for PORT in "${PORTS[@]}"
+do
+    echo "Starting server.js on port $PORT"
+    PORT=$PORT nohup node $SERVER_JS_PATH > logs/server_$PORT.log 2>&1 &
+done
+
+echo "All servers started."
+

+

Configuring NGINX for Our Web App 🔗

Before configuring NGINX, you need to install NGINX on your system. You can check if NGINX is installed by running the following command:

+
nginx -v
+

The behavior of NGINX is determined by its configuration file, typically named nginx.conf. By default, this file is located in directories such as /etc/nginx or /usr/local/etc/nginx, but for this demonstration, we will keep the nginx.conf file in the same directory as the project files.

+

You can read the configuration file with the following command:

+
nginx -c /your/path/to/code-examples/nginx-load-balancer/nginx.conf
+

Before running the server, it’s always a good idea to test the configuration using the -t flag:

+
nginx -t -c /your/path/to/code-examples/nginx-load-balancer/nginx.conf
+

NGINX Configuration (nginx.conf) 🔗

events {
+    worker_connections 1024;
+}
+
+http {
+    upstream backend {
+        server 127.0.0.1:3000;
+        server 127.0.0.1:8080;
+        server 127.0.0.1:1313;
+        server 127.0.0.1:1517;
+    }
+
+    server {
+        listen 80;
+        server_name localhost;
+
+        location / {
+            root code-examples/nginx-load-balancer;
+            index index.html;
+        }
+
+        location /api/data {
+            proxy_pass http://backend;
+        }
+    }
+}
+

+

Explaining the NGINX Configuration 🔗

Worker Connections: In the events block, we configured NGINX to handle 1024 simultaneous connections per worker. This optimizes how NGINX deals with incoming requests.

+

Upstream Block: The upstream block defines a pool of backend servers, each running on a different port (3000, 8080, 1313, and 1517). NGINX will distribute the load across these servers using a round-robin method, sending each request to a different server in turn.

+

Port 80: NGINX listens on port 80, which is the default HTTP port.

+

Serving Static Files: When a request is made to /, NGINX serves the static HTML file (index.html) located in the code-examples/nginx-load-balancer directory.

+

Proxying Requests: When a request is made to /api/data, NGINX acts as a proxy and forwards the request to one of the backend servers, which will respond with a port-specific joke.

+
+

Testing the Web Application 🔗

Once everything is set up, open a browser and go to http://localhost. Each time you refresh the page, NGINX will serve the static HTML file and fetch data from different backend servers running on different ports, showing a new joke with each request.

+

Request 1 +

+ image not found +

+

Request 2 +

+ image not found +

+
+

Conclusion 🔗

In this article, we explored how to use NGINX to serve a Node.js application, demonstrating its load-balancing, proxying, and static file serving capabilities. NGINX is a popular choice in the Node.js ecosystem for production environments, thanks to its efficiency and powerful features.

+

This is a basic example demonstrating some of NGINX’s capabilities. In future exercises, we will explore more features such as caching, reverse proxying, and SSL/TLS configuration.

+
+

Further Reading 🔗

+

As always, happy coding!

+ +
+ + + + + +
+ + +
+ + + + + + + diff --git a/public/sitemap.xml b/public/sitemap.xml index 0fbb1e4..969a8a1 100644 --- a/public/sitemap.xml +++ b/public/sitemap.xml @@ -2,13 +2,16 @@ - https://printf-scanf.pages.dev/posts/web-socket-chat-server/ - 2024-10-06T00:00:00+00:00 + https://printf-scanf.pages.dev/posts/nginx-load-balancing/ + 2024-10-13T00:00:00+00:00 https://printf-scanf.pages.dev/posts/ - 2024-10-06T00:00:00+00:00 + 2024-10-13T00:00:00+00:00 https://printf-scanf.pages.dev/ + 2024-10-13T00:00:00+00:00 + + https://printf-scanf.pages.dev/posts/web-socket-chat-server/ 2024-10-06T00:00:00+00:00 https://printf-scanf.pages.dev/posts/browser-extension/ diff --git a/static/nginx-load-balancing.png b/static/nginx-load-balancing.png new file mode 100644 index 0000000..af21bb8 Binary files /dev/null and b/static/nginx-load-balancing.png differ diff --git a/static/nginx-req1.png b/static/nginx-req1.png new file mode 100644 index 0000000..956cac3 Binary files /dev/null and b/static/nginx-req1.png differ diff --git a/static/nginx-req2.png b/static/nginx-req2.png new file mode 100644 index 0000000..9e7688d Binary files /dev/null and b/static/nginx-req2.png differ