UPSTREAM

UPSTREAM e' una piattaforma di deploy avanzata che permette il controllo totale dell'ambiente di esecuzione del proprio applicativo.

A differenza di UFCGI,uWSGI o uRack non propone un ambiente pre-impostato e ottimizzato per una particolare tecnologia ma lascia all'utente la scelta di application server, protocolli e comportamenti.

Gli unici due requisiti per poter utilizzare un application server con upstream e' che supporti l'ereditazione (si dice cosi' in italiano ???) di file descriptor associati a socket unix (la comunicazione avviene sul file descriptor 0, ovvero lo stdin) e che il protocollo utilizzato sia uwsgi, fastcgi, scgi o http.

Per la sua configurazione di base e' necessario disporre di almeno un processo (ovviamente dipende dall'applicazione), impostare il flag 'upstream' e il comando da eseguire tramite il parametro 'upstream_cmd'.

Ad esempio poniamo di aver compilato una versione di uWSGI personalizzata e di averla copiata in /bin (che e' automaticamente inserita nel PATH di sistema), e di aver copiato un semplice script wsgi all'interno della docroot (chiamato hello.py):

upstream_cmd:    uwsgi -w hello

Essendo nel PATH e' sufficiente specificare il solo comando, se ad esempio abbiamo copiato l'eseguibile di uwsgi all'interno della docroot il comando sara':

upstream_cmd:    ./uwsgi -w hello

questo perche' la directory corrente viene impostata alla docroot (tenetelo a mente poiche' e' importantissimo).

Se invece siamo ancora piu' temerari e abbiamo copiato il binario di uwsgi all'interno della directory "/pippo" e il mio account si chiama "gigio" dovremo usare

upstream_cmd:   /accounts/gigio/pippo/uwsgi -w hello

Il comando upstream_cmd segue quindi le regole di una normale shell UNIX.

Scrivere pero' i path a mano puo' essere poco pratico, sono state quindi previste delle variabili utilizzabili in tutti i parametri upstream (ad esclusione di quelli che si riferiscono a uri):

%u    nome account
%h    home account
%r    directory corrente (docroot)
%i    id numerico del dominio
%d    nome dominio
%s    percorso assoluto del socket unix (necessario per alcuni server)
%%    il carattere %

La nuova direttiva potra' quindi essere scritta in questo modo:

upstream_cmd:    %h/pippo/uwsgi -w hello

...decisamente meglio.

Le variabili d'ambiente

Come qualsiasi shell degna di questo nome anche UPSTREAM permette l'assegnazione di variabili d'ambiente.

Ad esempio per impostare la variabile RAILS_ENV a production potremo usare il parametro upstream_env in questo modo:

RAILS_ENV=production

Ricorda che puoi usare le variabili upstream anche per i valori delle variabili d'ambiente, ad esempio:

RAILS_ENV=production
RAILS_DOMAIN=%d
USER_HOME=%h

protocolli

Attualmente UPSTREAM supporta il protocollo uwsgi (il default), il protocollo HTTP, SCGI e FastCGI. Se ad esempio volessimo usare nginx come application server (per sfruttare il suo mod_perl o il modulo esterno wsgi o qualsiasi altra configurazione vi venga in mente) sara' sufficiente copiarlo in una directory del vostro account (ad esempio NGINX8) e impostare upstream:

upstream_cmd:        %h/NGINX8/sbin/nginx
upstream_env:        NGINX=0:
upstream_protocol:   http

La variabile NGINX serve a indicare quale file descriptor ereditare, per completare l'opera pero' dobbiamo specificare il nome del socket unix che nginx confrontera' con quello passato automaticamente (e' un hack che serve solo a bypassare i controlli interni di nginx).

in nginx.conf impostate la direttiva listen in questo modo:

listen unix:/var/lib/apache/upstream/1000_upstream.sock;

dove 1000 e' l'identificativo numerico del vostro dominio (lo ricavate dalle opzioni del dominio sul pannello).

E' importante avere chiaro che l'utente non ha accesso a questo socket, specificarlo serve solo a permettere a nginx di effettuare il confronto tramite la chiamata getsockname(). E' un comportamento diffuso che ritroverete in diversi application server. L'utente non deve mai preoccuparsi dell'inizializzazione del socket

Attenzione, solo il ramo 0.8 di nginx supporta l'ereditarieta' dei file descriptor di socket unix.

logging

Molto probabilmente il vostro application server ha un sistema interno di logging, tuttavia nelle fasi di avvio potrebbe non essere attivo, pertanto di default lo stderr e lo stdout vengono reindirizzati al file stderr_log nella vostra home. Potete scegliere il path (relativo alla home) di un file stderr_log alternativo usando il parametro upstream_stderr (ricordatevi di usare le variabili per configurazioni piu' sexy):

upstream_stderr:       myapp/stderr_%d_superlog

timeout

Come ogni tecnologia Unbit i timeout sono una componente fondamentale. Per upstream e' disponibile un unico timeout (se nullo o 0 equivale a 10 secondi) che indica il tempo massimo che il webserver restera' in attesa di risposta dalla nostra applicazione (ad ogni byte ricevuto il timeout viene resettato). Il massimo timeout impostabile e' 300 secondi.

upstream_off e upstream_only

Questi due parametri sono la chiave per miglioare le performance o per effettuare configurazioni rocambolesche. Il primo contiene tutte le uri per cui si vuole che upstream non venga chiamato in causa lasciando gestire il lavoro ad apache (ad esempio per servire file statici). Il secondo fa esattamente l'opposto, ovvero specifica le uri per le quali attivare upstream. Tutte le altre saranno servite da apache.

upstream_checkfile

Questo parametro permette di passare il controllo al vostro applicativo, solo dopo aver verificato l'esistenza di un file (che eventualmente verra' servito direttamente dal webserver).

Le modalita' sono: off (disabilita il controllo), simple check (verifica se il file esiste e in caso positivo lo restituisce al client senza scomodare il vostro applicativo) e rails-style (permette di sfruttare i meccanismi di caching stile rails)

.htaccess e pagine di errore

Gli .htaccess sono pienamente supportati e potete personalizzare i terrificanti messaggi di errore di UPSTREAM caricando un file chiamato upstream_errorpage.html nella docroot.

X-Sendfile

Potete utilizzare senza problemi X-Sendfile nelle vostre applicazioni sotto UPSTREAM

... e dopo tanta teoria....

Un po' di esempi

Rails su uRack

caricate la vostra applicazione dentro la directory /www e impostate la docroot a nomeapp/public.

Se la vostra app si chiamera' quindi 'topo' la docroot andra impostata a topo/public.

Scaricate la versione piu' recente di urack.rb da qui:

http://projects.unbit.it/uwsgi/browser/contrib

e copiatela all'interno di topo/public

impostate upstream:

Se nella directory della vostra applicazione eiste un file chiamato config.ru

upstream_protocol:        uwsgi
upstream_cmd:             ruby urack.rb ../config.ru
upstream_checkfile:       rails-style

altrimenti

upstream_protocol:        uwsgi
upstream_cmd:             ruby urack.rb
upstream_checkfile:       rails-style

Attendete qualche secondo e la vostra applicazione rails si avviera'. Se qualcosa e' andato storto aprite il fiel stderr_log della vostra home.

In case non vogliate usare upstream_checkfile e' buona norma evitare di far servire i file statici a ruby, 'sganciate' quindi le directory di rilievo da upstream:

upstream_off: /images /stylesheets /javascripts

Delle buone opzioni per un ambiente di produzione sono

upstream_protocol:        uwsgi
upstream_cmd:             ruby urack.rb -M -p 2
upstream_checkfile:       rails-style
upstream_env:             RAILS_ENV=production

Rails su rackup

rackup e' il tool distribuito nel modulo Rack di ruby. E' disponibile un handler uwsgi per questo modulo:

http://projects.unbit.it/uwsgi/browser/contrib/uwsgi.rb

scaricatelo e copiatelo dentro la directory /public della vostra applicazione.

upstream_protocol:        uwsgi
upstream_cmd:             rackup -I .. -r uwsgi -s Uwsgi <config.ru>
upstream_env:             UWSGI_FD=0

dove <config.ru> e' il path (relativo alla docroot) del file config.ru

Rails su unicorn

Unicorn e' un server Rack molto efficiente, se non avete bisogno delle funzionalite' specifiche dei server Unbit potete tranquillamente prenderlo in considerazione:

http://unicorn.bogomips.org/

upstream_protocol:        http
upstream_cmd:             unicorn_rails -I .. -l %s
upstream_env:             UNICORN_FD=0

notare il %s che specificato il path del socket unix

Sinatra su uRack

copiate la vostra applicazione sinatra all'interno della docroot (impostatela come preferite). Nella docroot deve essere presente il file config.ru

upstream_protocol:        uwsgi
upstream_cmd:             ruby urack.rb config.ru

Catalyst su Plackup

Plackup e' il tool di deploy fornito con la distribuzione ufficiale dello standard PSGI (l'equivalente di WSGI per il mondo perl).

Come al solito e' consigliabile costruire un ambiente perl personalizzato. Poniamo quindi che tutta la distribuzione perl sia all'interno di /PERL5

Scaricate l'handler uwsgi per plackup da qui (il file si chiama Uwsgi.pm)

http://projects.unbit.it/uwsgi/browser/contrib/

e copiatelo nella docroot della vostra applicazione (dove ci sara' anche il file .psgi di avvio)

upstream_protocol:        uwsgi
upstream_cmd:             %h/PERL5/bin/plackup -s Uwsgi app.psgi
upstream_env:             UWSGI_FD=0

dove app.psgi e' il file entry point PSGI.

Note finali

Le possibilita' sono teoricamente illimitate, se siete affezionati a una tecnologia di deploy (o semplicemente vi fanno schifo le nostre) o avete bisogno del controllo totale della vostra applicazione allora UPSTREAM e' la scelta giusta.

UPSTREAM da' il massimo se usato con ambienti personalizzati, quindi se avete la possibilita', istallate le vostre distribuzioni custom di ruby, python, perl, java ecc. ecc.

Se un prodotto non e' compatibile con upstream (ma e' open source) contattate lo staff Unbit, e' molto probabile che troveremo una soluzione.

Attualmente e' in lavorazione un adapter per twisted.web2, se siete interessati contattate lo staff.

Upstream (l'ultima modifica รจ del 2011-09-22 05:26:58, fatta da RobertoDeIoris)