Passa ai contenuti principali

Soluzione multi-nodo per applicazioni web

Soluzione multi-nodo per applicazioni web


Introduzione

Un servizio online se invocato da un numero molto alto di richieste sull'unità di tempo può "andare in sofferenza" e dare tempi di risposta troppo alti. In questo caso si può intervenire a livello sistemistico per ottimizzare le risorse coinvolte o aumentarle. Se ciò non dovesse bastare si possono accendere più istanze del servizio in modo che il carico di lavoro venga ripartito su queste e non su una singola istanza. Ogni istanza viene detta "nodo".


Architettura

Lo scenario con una singola istanza di una classica applicazione web composta da Gateway (GW - front-end), Servizio (SR - back-end) e Database (Db):






Lo scenario con un Servizio (SR) replicato in più nodi ma con il Database (DB) ed il Gateway (GW) in comune, quello che punto a costruire:




Implementazione

Per l'implementazione prevediamo che le componenti del sistema siano tutte dockerizzate e supponiamo che siano le seguenti:
- Gateway = Nginx
- Servizio = Pspdfkit
- Database = Postgres

Il docker-compose di questo stack sarebbe questo:

version: "3"

services:
db:
image: postgres:latest
environment:
POSTGRES_USER: pspdfkit
POSTGRES_PASSWORD: password
# ... other environment variables
pspdfkit:
image: "pspdfkit/pspdfkit:latest"

environment:
PGUSER: pspdfkit
PGPASSWORD: password
# ... other environment variables
depends_on:
- db
ports:
- "5000:5000"

Se provassimo a lanciarlo avremmo la porta 5000 che espone il servizio fornito da PdfDfKit.

Se questo servizio è utilizzato da tantissime applicazioni per unità di tempo e va in sofferenza potremmo usare l'opzione "--scale" di docker che consente di creare più istanze di un servizio "scalandolo". "Scale" prevede, a livello di sintassi il nome del servizio che si intende scalare e il numero di istanze che si intende ottenere:

$ docker-compose up --scale pspdfkit=3

Lanciando questo comando otterremmo lo start del primo nodo e poi un errore per conflitto di porta già occupata dagli altri due nodi che non partirebbero (trovando la 5000 occupata dal primo nodo).
La soluzione prevede una modifica al docker-compose con la quale dichiamo di esporre la porta 5000 interna su una porta a caso dell'host, con l'opzione "ports: - 5000":

version: "3"

services:
db:
image: postgres:latest
environment:
POSTGRES_USER: pspdfkit
POSTGRES_PASSWORD: password
# ... other environment variables
pspdfkit:
image: "pspdfkit/pspdfkit:latest"

environment:
PGUSER: pspdfkit
PGPASSWORD: password
# ... other environment variables
depends_on:
- db
ports:
- "5000"

Lanciando ora:

$ docker-compose up --scale pspdfkit=3

Si otterrà la partenza dei tre nodi. Per capire su quale porta stanno girando i servizi basterà chiederlo a docker:

$ docker ps 

Capite bene che così il servizio è difficilmente utilizzabile e quindi chiediamo aiuto al proxy-pass costituito da Nginx. Basterà creare un file "nginx.conf" , nella stessa directory del docker-compose.yml, con il quale diciamo a Nginx di dirottare tutte le richieste che arrivano alla porta 4000 verso il servizio pspdfkit sulla porta 5000:

user nginx;

events {
worker_connections 1000;
}
http {
server {
listen 4000;
location / {
proxy_pass http://pspdfkit:5000;
}
}
}


e poi chiederemo a docker di esporre la porta 4000:

version: "3"

services:
db:
image: postgres:latest
environment:
POSTGRES_USER: pspdfkit
POSTGRES_PASSWORD: password
# ... other environment variables
pspdfkit:
image: "pspdfkit/pspdfkit:latest"

environment:
PGUSER: pspdfkit
PGPASSWORD: password
# ... other environment variables
depends_on:
- db
expose:
- "5000"
nginx:
image: nginx:latest
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf:ro
depends_on:
- pspdfkit
ports:
- "4000:4000"


Nginx gestirà le richieste che arriveranno sulla porta 4000 dirottandole alle istanze di pspdfkit disponibili con una logica "round robin" e quindi potremo lanciare:

$ docker-compose up --scale pspdfkit=3

Fonti:






Commenti

Post popolari in questo blog

Telecamere Ip con accesso "nascosto"

Telecamere Ip con accesso "nascosto" Storia triste di un auto-hacking obbligato che mi ha fatto scoprire come la nostra privacy è realmente messa a rischi. Storia Ho acquistato dal mercatino/fiera del Radioamatore di Fasano quattro telecamere IP. La scatola riporta "Smart Camera" LF4810. Ne ho montata una e testata in tutte le sue funzionalità per oltre un mese. Chiaramente la manualistica scarsissima, come da tradizione in questi prodotti cinesi di costo molto concorrenziale, consiste in un "pieghevole" di 4 facciate. Chiaramente non erano documentate le impostazioni necessarie per attivare i protocolli ONVIF e RTSP che mi sono indispensabili per l'uso che ne devo fare. Nonostante questa scarsa documentazione dopo l'installazione base fatta con l'apposita app: tutto sembrava corretto. Chiaramente la prima azione che ho compiuto è stata quella di cambiare la password che di default è "123". Subito dopo h...

Dynamic DNS con Duckdns.org in HTTPS

Obiettivo Avere un dominio https con certificato valido da usare come endpoint pubblico per Homeassistant e per un WebHook per i bot telegram. Fase 1 Registrazione del dominio in un servizio di dynamic DNS come https://www.duckdns.org/   : Scegliere per quale sistema operativo installare il client che si occuperà dell'aggiornamento dell'ip: Seguire la semplice guida per la configurazione del processo cron: Fase 2 Creazione del certificato e installazione sul server. Di tutto questo si occuperà una applicazione che si chiama certbot. $ sudo add-apt-repository ppa:certbot/certbot $ sudo apt install python-certbot-apache $ sudo certbot --apache -d ol3.duckdns.org -d www.ol3.duckdns.org Fase 3 Esporre il servizio https sulla rete pubblica. Aprire o reindirizzare la porta 443 verso l'host sul quale si è fatta la configurazione di certbot dal proprio router. Il certificato di certbot è valido per novanta giorn...

JHipster - Uso base

Cosa è JHipster è un "generatore di applicazioni" che fornisce tutto lo stack necessario ad implementare una applicazione web e/o a microservizi basata su Spring Boot e AngularJs. E' dotato di un marketplace di componenti già pronte: https://www.jhipster.tech/#modules E' dotato di uno strumento web per la modellazione dello schema E-R: https://start.jhipster.tech/jdl-studio/ Prerequisiti - Java 8  - Node.js (usare la versione LTS 64-bit) - NPM viene installato con Node.js ma va aggiornato      $ npm install -g npm - Per usare il JHipster Marketplace, installare Yeoman:       $ npm install -g yo Uso base Gli step, presi dal sito ufficiale sono questi: 1. Installare JHipster:       $ npm install -g generator-jhipster Nota: per installare una versione specifica del generator:   $ npm install -g generator-jhipster@6.0.5 2. Crea una nuova directory ed entra dentro questa:   $ mkdir ...