Archiviazione e pubblicazione basata su Git, consulenza sulle infrastrutture

1

Volevo avere qualche consiglio su come spostare un sistema su "the cloud" ... in particolare, sto cercando di passare ad alcuni dei servizi gestiti di Windows Azure, dato che adesso sto gestendo una VM. Fondamentalmente, il sistema funziona su alcuni dati memorizzati in un repository github git. Descriverò l'architettura corrente:

Sistema corrente (tutto ospitato su un singolo server):

  • GitHub - configurato con un webhook che punta a ...
  • Applicazione ASP.NET MVC - per accettare il webhook da git. Spinge un messaggio su ...
  • Coda del bus del servizio di Azure - che viene svuotato da ...
  • Servizio Windows: estrae il messaggio dalla coda e ...
  • Rileva gli ultimi dati dal repository git (utilizzando GitLib2Sharp ) sul disco locale e infine ...
  • Funziona sui dati in git per produrre un sito Web HTML statico ospitato / servito da IIS.

Il sistema funziona davvero bene, in realtà ... ma vorrei uscire dall'attività di gestione della VM e passare all'utilizzo di una combinazione di ruoli Web e di lavoro di Azure. Ma poiché il sistema si basa molto sul repository git sul filesystem locale, trovo difficile capire come progettare nel cloud. So che puoi ottenere l'accesso al file system, quindi in teoria potrei semplicemente recuperare il repository se non c'è nulla sul disco ... ma le prestazioni / reattività del sistema dipendono dal fatto che il repository sia disponibile e che debba solo recuperare diff, che è relativamente veloce. Invece di dover periodicamente recuperare l'intero (un po 'più grande) repository git se il ruolo web o worker è stato riciclato, o qualcosa del genere.

Quindi mi piacerebbe qualche consiglio su come si dovrebbe architettare un tale sistema :) In definitiva, l'unico vero requisito è quello di essere in grado di servire contenuto HTML che è stato prodotto dal contenuto di un repository git (in modo relativamente reattivo, dal punto di vista editoriale) ... non esitate a chiedere chiarimenti se c'è qualcosa che ho omesso. Grazie!

    
posta Joel Martinez 21.08.2014 - 16:17
fonte

1 risposta

1

È stato un esempio perché non si adattava ai commenti: è PHP, ma credo che sia abbastanza leggibile per te capire il concetto.

<?PHP

/**
 * Simple example of loading the git repository
 * Then do a conversion on some files
 * Then publish them in the /public repository
 * 
 * Handles loading the repository from github and understands whether it 
 * needs to clone because it's the first run or update.
 * 
 * Timing on slow internet connection:
 * 
 * update: 0.96 - 1.53 seconds
 * new clone: ~100 seconds
 * 
 * Clearly most time happens in the downloading of the repository.
 * 
 * Uses rename() as atomic function to allow updating and processing to
 * happen without the users having issues. When processing is totally complete
 * the public directory is instantly replaced.
 * 
 */

$time_start = microtime(true);

//git repo
$repoDir=__DIR__.'/linux/';

//public directory
$publicationDir=__DIR__.'/public/';

//temporary directory for publication to be built
$newPublicationDir=__DIR__.'/tmp-'.time().'/';

//archive location for old version (for fallback in case of errors)
$archiveDir=__DIR__.'/archive-'.time().'/';

//ensure we have all directories, yes ugly without error catching
@mkdir($repoDir);
@mkdir($newPublicationDir);
@mkdir($archiveDir);

//detect a new install or an update of the repository
if(!file_exists($repoDir.'.git')) {
    //new install
    exec('git clone git://github.com/torvalds/linux.git --depth 1');
}else{
    //update
    exec('cd '.$repoDir.'; git fetch --depth 1');
}

//processing your contents (no idea what you do on them)
//in example we convert newlines of a textdocument to <br> tags
$documentationFile=$repoDir.'Documentation/aoe/aoe.txt';

file_put_contents(
    $newPublicationDir.'index.html',
    '<h1>Converted document from git</h1>'.nl2br(file_get_contents($documentationFile))
);

//back-up the current publication
if(file_exists($publicationDir)) {
    rename($publicationDir, $archiveDir);
}else{
    @mkdir($publicationDir);
}

//add the new publication
rename($newPublicationDir, $publicationDir);


$time_end = microtime(true);
$time = $time_end - $time_start;

echo "ready in $time seconds\n";

Questo esempio funziona con il repository linux che è abbastanza grande secondo me con un sacco di storia irrilevante. Usa le idee discusse nei commenti. Generalmente questa cosa si aggiornerà in 2 secondi. Quindi, mentre aspetto i tuoi numeri esatti sulla dimensione del repository e sui tempi di elaborazione, penso che questo dovrebbe essere sufficiente per risolvere il tuo problema.

coda

Capisco che ora usi una coda eccetera. Puoi mantenerlo tutto se lo desideri ed elaborarlo come nell'esempio.

alternativa più semplice

Un'altra alternativa più semplice (secondo me) è: solo web server, non lavoratori.

Avvia uno o più web worker. Elaborano lo script al momento dell'avvio. Al termine (convalidare se la directory pubblica è piena), aprono la porta e sono pronti per il servizio. Forse dovrebbero notificare qualche bilanciamento del carico o qualsiasi altra cosa per far sapere al sistema che sono pronti per le richieste.

Quindi esegui un cron (operazione pianificata) per aggiornarli ogni x minuti / secondi. Ciò garantirà che non esegui l'attività più volte contemporaneamente e non devi configurare i tuoi hook.

Se ciò non è permesso puoi anche scegliere di usare gli hook eccetera con la tua coda, ma penso che renda il processo troppo complesso se la tua domanda è corretta e con tutte le informazioni rilevanti.

elaborazione nei lavoratori

Ora potresti scegliere di mettere un livello separato tra i lavoratori, per analizzare i dati dal repository, se davvero ti serve. Potresti usare gli stessi principi ma solo pubblicare su un disco condiviso. I server Web leggono quel disco e il gioco è fatto.

In alternativa al disco condiviso puoi inserire i risultati del worker anche in un repository git e utilizzare lo stesso script che punta a un repository git ospitato in azzurro che carica solo i risultati.

Su Azure puoi elaborare questo script con: link

Per lo spazio di archiviazione condiviso puoi dare un'occhiata all'archiviazione di file in questo documento: link C'è anche un elenco abbastanza chiaro delle alternative. In generale è possibile condividere lo spazio di archiviazione in azzurro tra più tipi e più istanze di server che si adatta alle proprie esigenze.

attenti che metto nelle directory degli archivi, rimuovilo di sicuro in produzione perché continua a riempire il tuo filesystem.

    
risposta data 29.08.2014 - 11:21
fonte

Leggi altre domande sui tag