Tornado 🌪️ and Load Balancing Tutorial
Published: 2023-08-18 23:36:23

This tutorial will guide you through setting up the Tornado web framework, creating a simple "Hello, world" application, and implementing load balancing using NGINX. 🌪️

## Tornado Web Framework

Tornado is a Python web framework and asynchronous networking library originally developed by FriendFeed. It leverages non-blocking network I/O, allowing it to scale to handle numerous open connections. This makes it ideal for tasks such as long polling, WebSockets, and applications requiring persistent connections for each user. You can find more information in the official [documentation](https://www.tornadoweb.org/en/stable/).

### Installation

Installing Tornado is straightforward using `pip3`:

`pip3 install tornado`

## Hello World Application

Let's start by creating a basic "Hello, world" application using Tornado.

1. Create a file named `HelloWorld.py` and add the following code:
```python
import tornado.ioloop
import tornado.web

class MainHandler(tornado.web.RequestHandler):
    def get(self):
        self.write("Hello, world")

def make_app():
    return tornado.web.Application([
        (r"/", MainHandler),
    ])

if __name__ == "__main__":
    app = make_app()
    app.listen(8888)
    tornado.ioloop.IOLoop.current().start()
```

2. Run the application in your terminal:

`python3 HelloWorld.py`

3. Access the application in your browser at `http://localhost:8888`.

## Load Balancing with Tornado and NGINX

### Understanding Load Balancing

Load balancing is a technique used in computer networking to distribute incoming network traffic across multiple servers. The primary goal of load balancing is to ensure optimal utilization of resources, enhance performance, and maintain high availability for web applications.

By distributing traffic across multiple servers, load balancing prevents any single server from becoming overwhelmed by a large number of requests, leading to improved response times and reduced downtime.

### Balancing Multiple Servers

Now, let's delve into load balancing by creating multiple instances of the server using Tornado.

1. Create a file named `index.py` and add the following code:

```python
import tornado.ioloop
import tornado.web
import sys
import os

class basicRequestHandler(tornado.web.RequestHandler):
    def get(self):
        self.write(f"Served from {os.getpid()}")

if __name__ == "__main__":
    app = tornado.web.Application([
        (r"/basic", basicRequestHandler)
    ])

    port = 8882
    if (sys.argv.__len__() > 1):
        port = sys.argv[1]

    app.listen(port)
    print(f"Application is ready and listening on port {port}")
    tornado.ioloop.IOLoop.current().start()
```

2. Run the application in your terminal:

`python3 index.py`

3. Access the application in your browser at `http://localhost:8882/basic`.
    
4. To explore load balancing, run the application on different ports:
    
`python3 index.py 1111 python3 index.py 2222 python3 index.py 3333`

You'll notice that the server number changes as you access the URL in different browsers.

### Using NGINX for Load Balancing

To automate the process of load balancing, we will utilize NGINX.

#### Installation

Install NGINX based on your operating system. Detailed instructions can be found in the official [documentation](https://www.nginx.com/resources/wiki/start/topics/tutorials/install/).

After installation, start NGINX using:

`sudo nginx`

#### Writing the Configuration File

Create a new file named `python.conf` and define the servers, ports, and URLs for NGINX to balance:

```conf
upstream pythonweb{
    
    server localhost:1111;
    server localhost:2222;
    server localhost:3333;
}

server{
    listen 80;

    location /basic{
        proxy_pass "http://pythonweb/basic";
    }
}
```

>Explanation of `upstream`: An `upstream` defines a "cluster" to which you can send proxy requests. It's commonly used to define a cluster of web servers for load balancing or a cluster of application servers for routing/balancing.

#### Configuring NGINX

Navigate to the NGINX configuration files:

bashCopy code

`cd /usr/local/etc/nginx/`

Open the file `nginx.conf.default`. Add the line `include /path/to/folder/with/python.conf` below the line `include servers/*;`.

**Note:** Be careful not to modify other parts of the NGINX configuration.

After making the configuration changes, reload NGINX settings:

`sudo nginx -s reload`

#### Load Balancer Ready

Your load balancer is now ready. Run the Tornado application using:

`python3 index.py`

Access the application in your browser at `http://localhost:8882/basic`. You will observe different server numbers, indicating successful load balancing.

By following these steps, you've set up a basic Tornado web application and implemented load balancing using NGINX. This tutorial provides a starting point for exploring more advanced features and configurations of both Tornado and NGINX.