1

I'm using NGINX inside docker-compose with 2 node services.

The load balancing is working. Not sure if this is how it should be, but my page load goes to ping1, then the CSS file loads from service ping2, then the next file from ping1, and... Where I thought it'd mostly be one full page load from ping1 and the next one from ping2.

Which one is more standard?

Here's docker-compose.yml

version: "2"

services:
  ping1:
    ports:
      - "80"
    build:
      context: ./1
      dockerfile: Dockerfile
    networks:
      - front-tier

  ping2:
    build:
      context: ./1
      dockerfile: Dockerfile
    networks:
      - front-tier

  nginx:
    build: ./nginx
    ports:
        - "80:80"
    networks:
      - front-tier

networks:
  front-tier:
    driver: bridge

As my second question, I'm trying to imagine how I could use Jenkins to take down ping2, update it, then bring it up and do the same thing to ping1.

Now I'm just testing manually, and using

docker-compose stop ping2

The service goes down, but nginx takes a while to realize that, and route through ping1.

I load port 80 on chrome, first request is the page load which goes through ping1, and the second is the CSS file, which would've been ping2, and it takes anywhere between 18-90 seconds to load from ping1, and just says "Pending" the whole time.

NGINX Error

How would I fix this where I'd check before routing to an upstream, if it is "healthy", maybe through a manually setup endpoint by me?

Here's nginx.conf

events {
    worker_connections 20000;
    use epoll;
    multi_accept on;
}

http {
  upstream ping {
    server ping1:80 max_fails=1 fail_timeout=1s;
    server ping2:80 max_fails=1 fail_timeout=1s;
  }

  limit_req_zone $binary_remote_addr zone=one:10m rate=18000r/m;
  limit_conn_zone $binary_remote_addr zone=addr:10m;

  keepalive_timeout 65;
  keepalive_requests 100000;
  sendfile on;
  tcp_nopush on;
  tcp_nodelay on;

  client_body_buffer_size      128k;
  client_max_body_size         10m;
  client_header_buffer_size    1k;
  large_client_header_buffers  4 4k;
  output_buffers               1 32k;
  postpone_output              1460;

  client_header_timeout  3m;
  client_body_timeout    3m;
  send_timeout           3m;

  open_file_cache max=1000 inactive=20s;
  open_file_cache_valid 30s;
  open_file_cache_min_uses 5;
  open_file_cache_errors off;

  server {
      listen 80;

      server_tokens   off;

      gzip on;
      gzip_disable "MSIE [1-6]\.";
      gzip_comp_level 5;
      gzip_vary on;
      gzip_min_length 1000;
      gzip_proxied any;
      gzip_types text/html application/x-javascript text/css application/javascript text/javascript text/plain text/xml application/json application/vnd.ms-fontobject application/x-font-opentype application/x-font-truetype application/x-font-ttf application/xml font/eot font/opentype font/otf image/svg+xml image/vnd.microsoft.icon;
      gzip_buffers 16 8k;

      location / {
          limit_req zone=one;
          limit_conn addr 10;

          proxy_pass http://ping/;
          proxy_http_version 1.1;
          proxy_set_header   Upgrade $http_upgrade;
          proxy_set_header   X-Real-IP            $remote_addr;
          proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;
          proxy_set_header   X-Forwarded-Proto $scheme;
          proxy_set_header   Host                   $http_host;
          proxy_set_header   X-NginX-Proxy    true;
          proxy_set_header   Connection "";

          proxy_connect_timeout      90;
          proxy_buffer_size          4k;
          proxy_buffers              4 32k;
          proxy_busy_buffers_size    64k;
          proxy_temp_file_write_size 64k;
          proxy_temp_path            /etc/nginx/proxy_temp;

          proxy_send_timeout 600;
          proxy_read_timeout 600;
      }

      location /stats {
        stub_status on;

        allow all;
      }
  }
}
Illinois47
  • 13
  • 2

1 Answers1

0

my page load goes to ping1, then the CSS file loads from service ping2, then the next file from ping1, and... Where I thought it'd mostly be one full page load from ping1 and the next one from ping2.

That's because the default method is round-robin.

See http://nginx.org/en/docs/http/load_balancing.html. In particular:

The following load balancing mechanisms (or methods) are supported in nginx:

  • round-robin — requests to the application servers are distributed in a round-robin fashion,
  • least-connected — next request is assigned to the server with the least number of active connections,
  • ip-hash — a hash-function is used to determine what server should be selected for the next request (based on the client’s IP address).

[...]

When the load balancing method is not specifically configured, it defaults to round-robin.

[...]

To configure ip-hash load balancing, just add the ip_hash directive to the server (upstream) group configuration:

upstream myapp1 {
    ip_hash;
    server srv1.example.com;
    server srv2.example.com;
    server srv3.example.com;
}

As my second question, I'm trying to imagine how I could use Jenkins to take down ping2, update it, then bring it up and do the same thing to ping1.

No need to do it in that order. All you need is one command:

docker-compose up --build -d ping2

(and then repeat for ping1)

I believe that won't stop the container until after the image is built, at which point it will stop it and immediately recreate it.

I don't know why nginx is hanging for so long, but using ip_hash should avoid that happening mid-page, and using the above docker-compose command should make the downtime extremely miniscule.

nafg
  • 116
  • 1