Come accoppiare in modo univoco i moduli nell'architettura orientata ai servizi

4

Stiamo sviluppando una soluzione totale e abbiamo scelto un'architettura orientata ai servizi per allentare i sottosistemi. Tuttavia, ora abbiamo un problema.

Quando il cliente ordina qualcosa, Ordina sottosistema è responsabile di ottenere quell'ordine e registrarlo. Tuttavia, ci sono anche altri moduli che sono responsabili, nel processo di registrazione degli ordini, e ogni modulo dovrebbe fare qualcosa su di esso:

  1. Il modulo Contabilità clienti dovrebbe controllare il saldo del cliente e impedire la registrazione dell'ordine se non ci sono abbastanza soldi nell'account del cliente.
  2. Il modulo di gestione delle risorse dovrebbe aumentare / diminuire le risorse del cliente
  3. Il motore di regole dovrebbe applicare dinamicamente alcune regole aziendali (come impedire un cliente specifico, o notificare un operatore, ecc.)
  4. CRM dovrebbe visualizzare la cronologia del cliente e offrire ai buoni clienti uno sconto
  5. ...

Al momento, lo stiamo facendo in questo modo:

public void RegisterOrder(Order order) 
{
    RuleEngineService.ApplyBusinessRules(order);
    // some code here
    CrmService.GiveDiscountIfApplicable(order);
    // some code here
    CustomerAccountingService.CheckBalance(order);
    // some code here
    AssetManagementService.ChangeAssetCount(order);
    // some code here
}

Ciò significa che se aggiungiamo un altro sottosistema (modulo) che deve fare qualcosa in ordine, dobbiamo ricompilare il codice del nostro OMS (Order Management System) per supportarlo. Inoltre, in qualche misura siamo accoppiati ad altri sottosistemi, e se uno di essi fallisce, questo processo di registrazione fallisce.

Un modo per rendere questo pezzo di codice dinamico e liberamente accoppiato è utilizzare interfacce o contratti , come:

public void RegisterOrder(Order order)
{
   // Finding a list of all IOrderProcessors.
   // Looping over each, calling orderProcessor.Process(order);
}

Tuttavia, ha due problemi:

  1. Non possiamo usare le interfacce su SOAP e HTTP (non abbiamo accesso ai file DLL di altri sottosistemi)
  2. Questi devono essere eseguiti in un ordine specifico (il motore delle regole è il primo)

Cosa dovremmo fare qui? Quali sono i modelli e le pratiche conosciuti?

    
posta Saeed Neamati 21.08.2013 - 15:07
fonte

3 risposte

3

Dai un'occhiata al modello Pub-Sub in quanto è adatto per fornire tale disaccoppiamento stai cercando. Il modello di osservatore potrebbe avere una certa applicabilità anche nel tuo caso.

In sostanza, l'applicazione "principale" che gestisce la richiesta invierà un messaggio a una coda che gli altri sistemi prenderanno e gestiranno a loro piacimento. Dovrai definire un'interfaccia o un contratto standard per il formato del messaggio, ma questo è ciò che ti farà ottenere il disaccoppiamento che stai cercando. Aggiungere e rimuovere applicazioni è semplice come aggiungere e rimuovere sottoscrittori.

Un altro vantaggio è che un sistema di supporto può andare offline, e quando ritorna riprende da dove era stato interrotto nella coda dei messaggi.

Se hai transazioni atomiche, dovrai estendere un po 'il pattern. I messaggi di risposta su un'altra coda sono uno dei mezzi per ottenerlo. Presumibilmente hai già una logica in atto per gestire lo stato della transazione, quindi dovresti semplicemente modificarlo per rispondere ai messaggi di risposta.

    
risposta data 21.08.2013 - 16:21
fonte
1

Ci sono alcuni modi per risolvere i tuoi problemi:

  1. Come sopra, usa Message queue per perdere tutti i moduli. Puoi usare il modello Pub / Sub per perdere requester e responser. MQ è un'architettura asincrona.

  2. Usa SOA.SOA è un'architettura che usa SOAP e XML per esportare il servizio. Ogni servizio fornisce un segmento SOAP e xml. Il servizio registerOrder può essere implementato con un xml che combina un segmento xml fornito da altri servizi. SOA è un file xml. Puoi facilmente modificarlo. SOA è un'architettura di sincronizzazione. L'architettura sincrona potrebbe avere problemi di prestazioni quando si verifica un'inondazione.

  3. Utilizza il flusso di lavoro (BPM). Puoi utilizzare un motore di flusso di lavoro per organizzare la tua logica di bussiness.Workflow è anche un file XML. Puoi modificarlo facilmente. Ti suggerisco di utilizzare JBPM come motore del flusso di lavoro. Il flusso di lavoro generalmente utilizza un registratore di database per tracciare un'istanza del flusso di lavoro. Quindi un'istanza del flusso di lavoro può essere viva per sempre. Se si dispone di transazioni atomiche, è necessario impostare alcuni processi nel flusso di lavoro. Al termine del flusso di lavoro, le transazioni atomiche saranno sempre coerenti.
    Il flusso di lavoro è anche un'architettura asincrona.

    Ti suggerisco di utilizzare il flusso di lavoro (ad esempio JBPM) per combinare i tuoi servizi. Per quanto ne so, la maggior parte del sistema di ordine utilizza il motore del flusso di lavoro.

risposta data 22.08.2013 - 07:43
fonte
1

Vorrei utilizzare un framework di ServiceBus che supporti il pattern Saga.

Inoltre, puoi continuare a seguire la tua soluzione con le interfacce. Non vedo alcun problema con il contenitore DI per la risoluzione delle interfacce in una raccolta. Le classi proxy che implementano le interfacce parleranno con i servizi effettivi e queste classi sono locali. È possibile avere DLL separate per classe proxy e registrarlo mediante scansione dell'assembly o configurazione. Puoi avere una proprietà per l'ordine di esecuzione nell'interfaccia che ti consentirà facilmente di ordinare la tua raccolta per eseguire i proxy nella sequenza corretta.

    
risposta data 08.10.2013 - 23:36
fonte

Leggi altre domande sui tag