DEV Community

Cover image for Basic load balancer with NGINX
Saurabh Bomble
Saurabh Bomble

Posted on • Originally published at saurabhbomble.hashnode.dev

Basic load balancer with NGINX

NGINX is an advanced web browser that can be used as a reverse proxy, load balancer, mail proxy, and caching mechanism. In this short tutorial, we scale a golang REST API service with docker-compose and distribute all the load from the client to these multiple service instances.

System diagram

The client makes an API call to http://localhost:8000/ endpoint, which hits the nginx service that internally proxies the request to one of the 3 instances of the REST servers running on the port 8000. We will be using the Round robin load-balancing technique that can help us to almost evenly distribute the load across every instance.

  1. build golang servers image with Dockerfile

    FROM golang:1.18-alpine AS builder
    
    RUN mkdir /app
    WORKDIR /app
    COPY . .
    
    RUN CGO_ENABLED=0 GOOS=linux go build -o app cmd/api/main.go
    
    FROM alpine:latest AS production
    WORKDIR /app
    COPY --from=builder /app/app .
    
    CMD [ "./app" ]
    
  2. docker-compose file - run the golang servers and nginx load balancer

    version: "3.8"
    
    services:
      rest_api:
        build:
          context: ./server
          dockerfile: Dockerfile
        environment:
          - PORT=:8000
        networks:
          - server-network
        command: /start
    
      nginx:
        image: nginx:latest
        volumes:
          - ./conf.d/nginx.conf:/etc/nginx/nginx.conf
        depends_on:
          - rest_api
        ports:
          - 8000:8000
        networks:
          - server-network
    
    networks:
      server-network:
        driver: bridge
    
  3. nginx conf file - We'll define events and set the expected maximum client concurrent connections to 1024. We can define a group of REST servers(image=rest_api) inside the upstream block. We can also mention the load balancing method inside the upstream block. NGINX server will listen on the port 8000 of the host. NGINX will proxy all the requests hitting at / route to app_servers group.

    events {
        worker_connections 1024;
    }
    
    http {
        upstream app_servers {
            # default load balancing method is Round Robin
            # other ex. least_conn, ip_hash, etc
            server rest_api:8000;
        }
    
        server {
            listen 8000;
    
            location / {
                proxy_pass http://app_servers;
                proxy_set_header Host $host;
                proxy_set_header X-Real-IP $remote_addr;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            }
        }
    }
    

Now we can start multiple instances of golang REST API servers with the following command -

$ docker-compose up --build --scale rest_api=3
Enter fullscreen mode Exit fullscreen mode

NGINX will serve the same request through different REST server instances -

Output 1

Output 2

Output 3

Top comments (0)