Come gestite l'estensibilità nei vostri sistemi multi-tenant?


13

Ora ho alcuni grandi prodotti multi-tenant basati sul web e molto presto vedo che ci saranno molte personalizzazioni specifiche per i tenant.

Un campo in più qua o là, forse una pagina in più o qualche logica in più nel mezzo di un flusso di lavoro - quel genere di cose.

Alcune di queste personalizzazioni possono essere integrate nel prodotto principale, ed è fantastico. Alcuni di loro sono altamente specifici e si metterebbero in mezzo a tutti gli altri.

Ho alcune idee in mente per gestirlo, ma nessuna sembra ridimensionarsi bene. La soluzione ovvia è introdurre una tonnellata di impostazioni a livello di client, consentendo di abilitare varie "funzionalità" su base per cliente. Il rovescio della medaglia con questo, ovviamente, è la massiccia complessità e disordine. Potresti introdurre un numero davvero enorme di impostazioni e nel tempo vari tipi di logica (presentazione, business) potrebbero sfuggire di mano. Quindi c'è il problema dei campi specifici del cliente, che richiede qualcosa di più pulito rispetto al semplice aggiungere un mucchio di campi nullable alle tabelle esistenti.

Cosa stanno facendo le persone per gestirlo? Force.com sembra essere il maestro dell'estensibilità; ovviamente hanno creato una piattaforma da zero che è super estensibile. Puoi aggiungere qualsiasi cosa con la loro interfaccia utente basata sul web. FogBugz ha fatto qualcosa di simile in cui ha creato un robusto modello di plug-in che, a pensarci bene, potrebbe essere stato effettivamente ispirato da Force. So che ci hanno speso molto tempo e denaro e, se non sbaglio, l'intenzione era di usarlo internamente per lo sviluppo futuro del prodotto.

Sembra il tipo di cosa che potrei essere tentato di costruire, ma probabilmente non dovrei. :)

Un massiccio investimento in architettura collegabile è l'unica strada da percorrere? Come gestisci questi problemi e che tipo di risultati stai vedendo?

EDIT: Sembra che FogBugz abbia gestito il problema costruendo una piattaforma abbastanza robusta e quindi utilizzandola per mettere insieme i loro schermi. Per estenderlo si crea una DLL contenente classi che implementano interfacce come ISearchScreenGridColumn e che diventa un modulo. Sono sicuro che sia stato incredibilmente costoso da costruire considerando che hanno molti sviluppatori e ci hanno lavorato per mesi, inoltre la loro superficie è forse il 5% delle dimensioni della mia applicazione.

In questo momento mi chiedo seriamente se Force.com è il modo giusto per gestirlo. E io sono un ragazzo ASP.Net hard core, quindi questa è una posizione strana in cui trovarmi.


3
Immagino che questa sia la domanda SO, che rende questo un post trasversale identico. Non farlo, o chiedi la domanda SO da migrare qui, o se stai cercando risposte diverse, dicci esattamente perché le risposte sulla domanda SO non sono soddisfacenti.
yannis,

Hai ragione, la domanda è migliore sui programmatori, ma sembra comunque che tu abbia ottenuto delle risposte abbastanza decenti. Ho modificato la domanda per fare riferimento alla domanda SO.
maple_shaft

Risposte:


8

Ho affrontato un problema simile e ti dirò come ho risolto il problema.

  1. Innanzitutto, esiste una libreria "core", o motore. Questo fondamentalmente gestisce lo spettacolo, proprio come hai già capito. Gestisce le cose comuni a tutti i sistemi, dal rendering di moduli dinamici, gestione utenti e account, ruoli, tu lo chiami, lo fa.

  2. Ogni parte del sistema è contenuta in un modulo. Un modulo ha dipendenze (altri moduli da cui dipende). Ad esempio, il sistema "core" ha Sicurezza (utenti, gruppi, ruoli, criteri password), Locale, (traduzioni, paesi, culture), Deposito file, Email, ecc. Ecc. Ogni modulo si definisce tramite un file XML. Il file XML specifica sostanzialmente gli schemi, le tabelle, le classi di calcolo, le definizioni delle schermate ecc. Vengono letti all'avvio dell'applicazione se la data del file è cambiata .

  3. I moduli specifici del cliente hanno i propri file xml e la propria DLL. Tutto in più e funziona di conseguenza e in modo trasparente con il resto del sistema. Giusto per sostituire le viste MVC esistenti con viste personalizzate, con codice personalizzato e modelli di vista personalizzati.

  4. Se un cliente desidera estendere la funzionalità esistente, xml / system fornisce un metodo in cui posso "derivare" un modulo da un altro. Il nuovo modulo ha tutte le funzionalità esistenti, ma con i requisiti specifici del cliente in una nuova DLL e con un file XML esteso che può apportare le modifiche. L'avvertimento è che non possono effettivamente rimuovere i campi esistenti in questo sistema, ma possiamo estenderlo e fornire oggetti e funzionalità completamente nuovi.


+1: Sembra che ci siano voluti un'ora o due. :)
Brian MacKay,

1
@BrianMacKay, beh, una volta terminato il lavoro (ed è stato uno slogan), i nostri clienti sono rimasti molto soddisfatti della velocità con cui abbiamo potuto cambiare le personalizzazioni. Si noti che il framework MVC (per quanto riguarda le viste / le pagine) non si presta molto bene per essere multi-progetto. Abbiamo risolto il problema utilizzando le funzionalità di proprietà di SVN e facendo in modo che le viste principali vengano importate dal repository principale e abbiamo utilizzato CSS / layout per personalizzarlo. Ma anno, poche ore buone: P
Moo-Juice,

Solo curioso, quanto tempo pensi ci sia voluto per implementare l'architettura stessa e quanti sviluppatori sono stati coinvolti?
Brian MacKay,

1
@BrianMacKay, sono stati 5 mesi. Uno sviluppatore dell'interfaccia utente per eseguire tutte le visualizzazioni CSS / HTML / parziali, javascript, ecc. E uno sviluppatore back-end (me stesso) per fare il resto.
Moo-Juice,

4

Avere molta logica di controllo delle versioni e livelli di codice da gestire non aggiunge valore alla tua app / sito web. Richiede anche più potere cerebrale per capire cosa sta succedendo e ti distrae dal nocciolo di ciò che stai facendo.

Consiglio diversamente. Consiglio di mantenere le cose semplici piuttosto complesse.

Mantenere un'unica base di codice uguale per tutti. Ogni funzione che aggiungi è una funzionalità per tutti. Limita solo il numero di articoli o di archiviazione o alcune cose quantificabili, non le funzionalità. Il motivo è quantificare cose come l'archiviazione, il numero di voci di dati, ecc. È così semplice da programmare e può essere applicato a una manciata di cose che impediscono davvero all'utente di impazzire sulla tua app. Deve solo essere programmato sull'aggiunta di elementi invece di fare una logica di funzionalità. Cosa succede se le funzionalità sono legate ad altre funzionalità? Per questo diventa molto complicato programmare.

Per qualificare la mia risposta, ho costruito un framework di e-commerce che ho per molti clienti e ho imparato il duro modo di cercare di mantenere tutte le loro idiosincrasie. Ho finito per rompere la catena e ho creato un unico sito Web di amministrazione multi-tenant per l'e-commerce. Ho quindi siti Web che raccolgono dati dalle chiamate al servizio web. Ciò consente a diversi team di tecnologie diverse di implementare funzionalità specifiche per i siti di e-commerce mentre continuo a ricevere pagamenti ogni mese sulla stessa infrastruttura e non mi interessa cosa stanno facendo. Ho solo limitato l'uso di numeri, non di funzionalità. È più facile. Il cliente è in grado di scegliere il proprio fornitore per costruire il proprio sito Web e non sono più coinvolto in tali decisioni.

Ho anche un servizio di abbonamento per la gestione dei contenuti SAAS. Funziona anche per livelli di utilizzo e i client possono aggiungere i propri plug-in se lo desiderano, mentre il mio team aggiunge più funzionalità per tutti.

Questa è solo la mia esperienza da sbattere la testa contro il muro dopo così tanto tempo, poi inciampare su qualcosa di più semplice.

Se qualcosa sarà sempre specifico per ogni cliente, non creare un framework per esso. Suddividilo nelle parti più semplici in modo che la parte della struttura funzioni per tutti e quindi ritaglia il resto in modo da poterlo estendere per l'individuo.


+1 per condividere la tua esperienza. Molto di ciò che mi sembra di sentire è "questo è un problema molto difficile". La realtà con cui ho a che fare è che questo sistema avrà tonnellate di personalizzazioni e non sono tutte appropriate per tutti ... Sembra che tu stia dicendo che hai adottato l'approccio di esporre un livello di servizio e quindi lasciare che le persone lo consumino comunque vogliono - ho almeno il vantaggio di scrivere internamente tutte le estensioni. Ma è ancora un casino da gestire (CNT)
Brian MacKay,

La conclusione a cui sto arrivando è che dovresti scrivere una piattaforma che supporti la propria nozione di componenti dell'interfaccia utente e composizione dinamica, quindi creare l'intera applicazione utilizzando quella piattaforma. E quindi sto iniziando a pensare che sarebbe intelligente scrivere semplicemente tutto su force.com, perché questo è force.com!
Brian MacKay,

Brian, FYI kitgui.com e hubsoft.com se sei curioso.
Jason Sebring,

2

Il prodotto software su cui lavoro ha campi extra per l'estensibilità dell'utente. Ciascun elemento di dati per questi campi può essere impostato su una riga esistente nelle tabelle principali dell'applicazione. Ad esempio, se il software contiene un elenco di ordini per i clienti e per ciascun cliente, la tabella dei dati personalizzabili avrà una colonna per le chiavi esterne della tabella dei clienti e della tabella degli ordini, solo una delle quali sarà non nulla. Quello o un numero di tabelle ognuna con i campi personalizzati per una tabella.

Questo è un modo semplice e performante per memorizzare dati extra per l'utente. Ulteriori informazioni dovrebbero essere memorizzate sui nomi e sui tipi di questi campi.

Quello copre i campi personalizzati per un cliente. Per un comportamento personalizzato, un'API dei servizi Web consentirebbe le estensioni.


1

1) Eseguire il codice di qualcun altro su scatole che possiedi è un problema piuttosto difficile. O puoi fidarti di loro o puoi differire ragionevolmente la responsabilità, dovrai eseguire il sandbox del loro codice molto pesantemente e avere una dedizione alla sicurezza superiore alla media. Poiché il tuo sistema di plug-in consente più funzionalità, aumenta la difficoltà di renderlo sicuro. Cose come la negazione del servizio (i plug-in consumano troppe risorse), la perdita di informazioni (i plug-in possono accedere ai dati di altri inquilini), ecc. Possono essere molto reali e problematici, non prenderei parte a questo a meno che non potessi fare conoscenza con le persone questi problemi o persone molto capaci con molto tempo per farlo bene.

2) Sì, la modularità e la personalizzazione sono difficili. Cose come il modello di strategia possono aiutare (un nome di fantasia per i puntatori a funzione; in Java è in genere implementato dichiarando un'interfaccia che gli utenti della classe possono implementare per personalizzare il comportamento del codice), ma vorrai molto isolato e disaccoppiato codice affinché funzioni.

3) Per quanto riguarda i dati, questo potrebbe essere uno degli esempi di archiviazione schematica utile. Se hai un modello di dati relazionali, avere tabelle con molte colonne per diversi clienti è problematico (sì, finisci con molte colonne nullable, il che è male ; una ragione è che è difficile o impossibile impostare i vincoli corretti [es. vincoli che non consentono la visualizzazione di combinazioni non valide di valori null]). È meglio aggiungere tabelle specifiche per il cliente (vale a dire userse foo_users, userstenendo i campi validi per tutti i clienti e foo_usersavere i file specifici di Foo); puoi avere facilmente i vincoli corretti, ma il tuo RDBMS potrebbe non gestirlo con grazia (a causa dell'esplosione dei join, limiti sul numero di tabelle, ecc.) e probabilmente apparirà brutto nel tuo codice.

Potresti finire per implementare un archivio di valori-chiave nel tuo RDBMS, il che rende il tuo modello di dati meno relazionale e causerà disagio (vale a dire i database relazionali funzionano meglio con i modelli relazionali). Non sono sicuro che una soluzione NoSQL si adatti al problema in generale, ma lo schema di gran parte delle implementazioni potrebbe essere un vantaggio.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.