Come adattare un motore di regole in un'architettura di microservizi quando richiede molti dati di input?


12

Situazione attuale

Stiamo implementando (e ora gestendo) un'applicazione web per lo shopping online in un'architettura a microservizi.

Uno dei requisiti è che l'azienda deve essere in grado di applicare le regole su ciò che i nostri clienti aggiungono al loro carrello, al fine di personalizzare la loro esperienza e l'eventuale ordine. Ovviamente, è stato necessario istituire un motore per le regole aziendali e per questo abbiamo implementato uno specifico "microservizio" (se potessimo ancora chiamarlo così).

Nel corso di un anno, questo motore di regole è diventato sempre più complesso, richiedendo sempre più dati (ad es. Contenuto del carrello ma anche informazioni sull'utente, il suo ruolo, i suoi servizi esistenti, alcune informazioni di fatturazione ecc.) Per poter calcolare quelle regole.

Per il momento, il nostro shopping-cartmicroservizio sta raccogliendo tutti questi dati da altri microservizi. Anche se una parte di questi dati viene utilizzata shopping-cart, la maggior parte delle volte viene utilizzata principalmente per alimentare il motore delle regole.

Nuovi requisiti

Ora arriva la necessità che altre applicazioni / microservizi riutilizzino il motore delle regole per requisiti simili. Nella situazione attuale, dovrebbero quindi trasmettere lo stesso tipo di dati, chiamare gli stessi microservizi e costruire (quasi) le stesse risorse per poter chiamare il motore delle regole.

Continuando così com'è, dovremo affrontare diversi problemi:

  • tutti (chiamando il motore delle regole) devono reimplementare il recupero dei dati, anche se non ne hanno bisogno per se stessi;
  • le richieste al motore delle regole sono complesse;
  • proseguendo in questa direzione, dovremo trasportare questi dati in tutta la rete per molte richieste (pensate a μs A che chiama μs B che chiama il motore delle regole, ma A ha già alcuni dei dati necessari al motore delle regole);
  • shopping-cart è diventato enorme a causa di tutto il recupero dei dati;
  • Probabilmente dimentico molti ...

Cosa possiamo fare per evitare questi problemi?

Idealmente, eviteremmo di aggiungere più complessità al motore delle regole. Dobbiamo anche assicurarci che non diventi un collo di bottiglia, ad esempio alcuni dati sono piuttosto lenti da recuperare (10 o anche più), quindi abbiamo implementato il pre-recupero in modo shopping-carttale che i dati abbiano maggiori probabilità di essere lì prima di chiamare le regole motore e mantenere un'esperienza utente accettabile.

Qualche idea

  1. Lascia che il motore delle regole recuperi i dati di cui ha bisogno. Ciò aggiungerebbe ancora più complessità, violando il principio della singola responsabilità ( ancora di più ... );
  2. Implementare un proxy μs prima del motore delle regole per recuperare i dati;
  3. Implementa un "fetcher di dati" che il motore delle regole chiama per recuperare tutti i dati di cui ha bisogno in una sola volta (richiesta composita).

Consentitemi di riassumere (con domande): avete implementato diversi microservizi per un negozio. Uno di questi è un carrello . Nel carrello è incorporato un motore di regole (homebrew o alcuni prodotti), giusto? Quando un utente aggiunge un articolo al carrello, il motore delle regole si inserisce come parte della logica aziendale e modifica il carrello in qualche modo (ad esempio sconto o prodotti in bundle), giusto? Ora un altro microservizio vuole anche usare regole che potrebbero essere basate su dati di input simili, giusto? E i dati di input sono forniti da altri microservizi, giusto? Perché il recupero dei dati è così complesso?
Andy,

3
La soluzione migliore per evitare questi problemi è quella di sbarazzarsi del motore delle regole.
whatsisname

@Andy Il motore delle regole è un microservizio separato. La sua API è un po 'su misura per shopping-cart, ma potremmo facilmente adattarla alle esigenze degli altri microservizi (sono ancora legati a utenti, prodotti e ordini). A nostro avviso, avranno bisogno degli stessi dati di input, soprattutto perché l'azienda è in grado di scegliere i predicati da applicare. Tutti i dati sono forniti da altri microservizi ad eccezione del contenuto del carrello stesso. Il recupero dei dati non è di per sé complesso, ma diventa complesso quando si devono chiamare ~ 10 altri microservizi e mantenere la struttura prevista dal motore delle regole.
Didier L

@whatsisname Non sono un grande fan di avere un motore di regole in generale, ma al momento attuale dobbiamo affrontarlo e comunque, e l'azienda sta cambiando la sua configurazione su base giornaliera. Anche se ci liberassimo, avremmo comunque bisogno di alcuni componenti configurabili per fare le stesse cose, che richiedano gli stessi dati di input ... Sarebbe comunque un motore di regole, solo con un altro nome, e dovremmo ancora affrontare gli stessi problemi.
Didier L

Risposte:


8

Facciamo un passo indietro di un secondo e valutiamo il nostro punto di partenza prima di scrivere questa probabile risposta da romanzo. Hai:

  • Un grande monolite (il motore delle regole)
  • Una grande quantità di dati non modularizzati che vengono inviati in blocco
  • È difficile ottenere dati da e verso il motore delle regole
  • Non è possibile rimuovere il motore delle regole

Ok, questo non è eccezionale per i microservizi. Un problema immediatamente evidente è che voi ragazzi non avete capito bene quali siano i microservizi.

tutti (chiamando il motore delle regole) devono reimplementare il recupero dei dati, anche se non ne hanno bisogno per se stessi;

È necessario definire una sorta di API o metodo di comunicazione utilizzato dai microservizi e renderlo comune. Questa potrebbe essere una libreria che tutti possono importare. Potrebbe essere la definizione di un protocollo di messaggio. Potrebbe utilizzare uno strumento esistente ( cercare i bus dei messaggi di microservizio come un buon punto di partenza).

La questione della comunicazione interservizi non è di per sé un problema "risolto", ma a questo punto non è nemmeno un problema "roll your own". Un sacco di strumenti e strategie esistenti possono rendere la tua vita molto più semplice.

Indipendentemente da ciò che fai, scegli un singolo sistema e prova ad adattare le tue API di comunicazione per usarlo. Senza un modo definito per interagire con i tuoi servizi, avrai tutti gli svantaggi dei microservizi e dei servizi monolitici e nessuno dei vantaggi di entrambi.

La maggior parte dei tuoi problemi deriva da questo.

le richieste al motore delle regole sono complesse;

Rendili meno complessi.

Trova modi per renderli meno complessi. Sul serio. Modelli di dati comuni, suddividi il tuo singolo motore delle regole in quelli più piccoli o qualcosa del genere. Fai funzionare meglio il tuo motore delle regole. Non prendere l'approccio "inceppa tutto nella query e continua a renderli complicati" - guarda seriamente cosa stai facendo e perché.

Definisci una sorta di protocollo per i tuoi dati. La mia ipotesi è che voi ragazzi non hanno definito piano di API (come da sopra) e hanno iniziato a scrivere RESTO chiama ad hoc in caso di necessità. Questo diventa sempre più complesso in quanto ora è necessario mantenere ogni microservizio ogni volta che qualcosa viene aggiornato.

Meglio ancora, non sei esattamente la prima azienda a implementare uno strumento di shopping online. Vai a cercare altre aziende.

Ora cosa ...

Dopo questo, hai almeno risolto alcuni dei problemi più grandi.

Il prossimo numero è questa domanda del tuo motore delle regole. Spero che questo sia ragionevolmente apolide, in modo da poterlo ridimensionare. Se lo è, anche se non ottimale non morirai in un tripudio di gloria o costruirai soluzioni folli.

Vuoi che il tuo motore delle regole sia apolide. Rendilo tale da elaborare solo i dati. Se lo trovi come un collo di bottiglia, fallo in modo da poterne eseguire diversi dietro un proxy / bilanciamento del carico. Non ideale, ma comunque praticabile.

Dedica un po 'di tempo a considerare se qualcuno dei tuoi microservizi dovrebbe davvero essere inserito nel tuo motore delle regole. Se si sta aumentando il sovraccarico del sistema in modo così significativo solo per ottenere una "architettura di microservizi" è necessario dedicare più tempo alla pianificazione.

In alternativa, il tuo motore delle regole può essere suddiviso in pezzi? Potresti ottenere guadagni semplicemente facendo pezzi dei tuoi servizi specifici del motore delle regole.

Dobbiamo anche assicurarci che non diventi un collo di bottiglia, ad esempio alcuni dati sono piuttosto lenti da recuperare (10 o anche più)

Supponendo che questo problema esista dopo aver risolto i problemi di cui sopra, è necessario indagare seriamente sul perché ciò accada. Hai un incubo che si svolge ma invece di capire perché (10 secondi? Per l'invio dei dati del portale di shopping in giro? Chiamami cinico, ma questo sembra un po 'assurdo) sembra che tu stia correggendo i sintomi piuttosto che guardare il problema che causa i sintomi in il primo posto.

Hai usato ripetutamente la frase "recupero dei dati". Questi dati sono in un database? Altrimenti, considera di farlo - se stai spendendo così tanto tempo "manualmente" per recuperare i dati sembra che usare un vero database sarebbe una buona idea.

Potresti essere in grado di avere una progettazione con un database per i dati che recuperi (a seconda di cosa si tratta, l'hai menzionato molte volte), alcuni motori di regole e i tuoi clienti.

Un'ultima nota è che si desidera assicurarsi di utilizzare il controllo delle versioni corretto delle API e dei servizi. Una versione minore non dovrebbe interrompere la retrocompatibilità. Se ti ritrovi a rilasciare tutti i tuoi servizi allo stesso tempo affinché funzionino, non hai un'architettura a microservizi, hai un'architettura monolitica distribuita.

Infine, i microservizi non sono una soluzione adatta a tutti. Per favore, per il bene di tutto ciò che è santo, non farlo solo perché è la nuova cosa dell'anca.


Grazie per la tua risposta, @enderland. In effetti l'architettura dei microservizi è ancora relativamente nuova per noi, quindi questa domanda. Questo motore delle regole si è evoluto un po 'organicamente per guidarci qui, quindi ora abbiamo bisogno di indicazioni stradali per risolverlo. È (fortunatamente) completamente apolide, quindi la quantità di dati che prende come input. E questo è ciò che vorremmo affrontare prima per renderlo un componente riutilizzabile. Ma come ridurre la quantità di dati di input senza ridurre il numero di predicati disponibili? Immagino che abbiamo bisogno di un'API in grado di recuperare i dati da sola, ma come architettarli correttamente?
Didier L,

Per quanto riguarda i problemi di prestazioni, questi provengono da microservizi che in realtà chiamano servizi JMS e SOAP lenti implementati da back-end. Hanno i loro database ma le prestazioni non sono proprio il loro primo obiettivo (purché gestiscano il carico). E ce ne sono troppi per considerare di replicare i propri dati e mantenerli (per alcuni lo facciamo, però). Il meglio che possiamo fare è quindi la memorizzazione nella cache e il pre-recupero.
Didier L,

Quindi quando menzioni " pochi motori di regole ", capisco che intendi motori di regole specializzati che valutano solo i predicati con 1 tipo di input, giusto? Consiglieresti di recuperare i dati di cui hanno bisogno o dovrebbero essere recuperati in anticipo? Avremmo anche bisogno di alcuni componenti per orchestrare la combinazione di predicati, giusto? E fai attenzione a non aggiungere troppi costi di rete a causa di questa orchestrazione.
Didier L,

1

Con la quantità di informazioni presentate sul motore delle regole e sui suoi input e output, penso che il tuo suggerimento n. 2 è sulla buona strada.

Gli attuali consumatori del motore delle regole potrebbero esternalizzare il processo di raccolta delle informazioni richieste a una componente più specifica.

Esempio: stai attualmente utilizzando il motore delle regole per calcolare gli sconti che devono essere applicati ai contenuti del carrello. Gli acquisti precedenti, la geografia e le offerte attuali ne fanno parte.

Il nuovo requisito è utilizzare gran parte di queste stesse informazioni per inviare via e-mail offerte ai clienti precedenti in base alle offerte speciali imminenti e agli acquisti precedenti. Gli acquisti precedenti, le offerte attuali e imminenti ne fanno parte.

Avrei due servizi separati per questo. Ognuno di loro si sarebbe affidato al servizio motore delle regole per alcuni dei suoi pesanti sollevamenti. Ognuno di loro avrebbe raccolto i dati richiesti necessari per la sua richiesta al motore delle regole.

Il motore delle regole applica solo le regole, i consumatori non devono preoccuparsi di quali dati esatti il ​​motore delle regole ha bisogno per il particolare contesto e questi nuovi servizi di intermediazione fanno solo una cosa: assemblare il contesto e passare la richiesta al motore delle regole e restituisce la risposta non modificata.


0

L'aggregazione dei dati richiesti per la decisione dovrebbe avvenire al di fuori del motore delle regole. Questo perché sono concepiti come servizi senza stato quanto più possibile. Il recupero dei dati comporta necessariamente l'elaborazione asincrona e il mantenimento dello stato. Non importa se il recupero viene eseguito da un proxy che affronta il servizio decisionale, dai chiamanti o da un processo aziendale.

Come questione pratica per l'implementazione, menzionerò che IBM Operational Decision Manager sta iniziando a documentare e supporta già l'uso del prodotto all'interno di contenitori docker . Sono sicuro che anche altri prodotti forniranno questo supporto e diventeranno mainstream.


0

Nel mio semplice pensiero, suppongo, aiuterà a precaricare tutti i dati richiesti effettuando una serie di chiamate asincrone ai servizi di recupero dati non appena il cliente inizia ad acquistare e memorizzare nella cache i dati. Quindi quando devi chiamare il servizio regole i dati sono già lì. E continua ad essere disponibile per altri servizi anche durante la sessione.

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.