Clustering di EJB
Dopo aver visto nella prima parte come configurare un cluster JBoss, in questo articolo analizziamo come clusterizzare gli Enterprise JavaBeans.
Session Bean Clustering
I session bean possono essere di due tipi: stateless e stateful. Entrambi possono essere clusterizzati ma con modalità diverse.
Stateless Session Beans
Il clustering di stateless session bean è semplice poiché non mantengono stato:
@Stateless
@Clustered
public class CalcoloBean implements Calcolo {
public double somma(double a, double b) {
return a + b;
}
}
Il load balancer può distribuire le chiamate su qualsiasi nodo del cluster.
Stateful Session Beans
Per i stateful session bean è necessaria la replicazione dello stato:
@Stateful
@Clustered
@CacheConfig(maxSize=1000, idleTimeoutSeconds=300)
public class CarrelloBean implements Carrello {
private List<Prodotto> prodotti = new ArrayList<>();
public void aggiungi(Prodotto p) {
prodotti.add(p);
}
public List<Prodotto> getProdotti() {
return prodotti;
}
}
Strategie di replicazione
JBoss supporta diverse strategie:
- Session state replication: replica completa dello stato
- Buddy replication: replica solo su nodi vicini
- Database persistence: persistenza su DB condiviso
Entity Bean Clustering
Gli entity bean presentano sfide particolari per il clustering.
Cache distribuita
Per evitare inconsistenze, è necessaria una cache distribuita:
<cache-invalidation>true</cache-invalidation>
<cache-invalidation-config>
<invalidation-manager-name>
jboss.cache:service=InvalidationManager
</invalidation-manager-name>
</cache-invalidation-config>
Commit options
Le diverse commit option hanno implicazioni diverse in cluster:
- Option A: cache sempre valida (problematica in cluster)
- Option B: rivalidazione ad ogni transazione
- Option C: ricaricamento ad ogni invocazione
Lock management distribuito
Per garantire consistenza è necessario un meccanismo di lock distribuito:
@Entity
@Table(name="PRODOTTO")
@Cache(usage=CacheConcurrencyStrategy.TRANSACTIONAL)
public class Prodotto {
@Id
private Long id;
private String nome;
private double prezzo;
}
HA-JNDI
Per il lookup in ambiente cluster, JBoss fornisce HA-JNDI:
Properties props = new Properties();
props.put(Context.INITIAL_CONTEXT_FACTORY,
"org.jboss.naming.NamingContextFactory");
props.put(Context.PROVIDER_URL, "jnp://node1:1100,node2:1100");
InitialContext ctx = new InitialContext(props);
Calcolo calcolo = (Calcolo)ctx.lookup("CalcoloBean/remote");
Load Balancing Policy
È possibile configurare diverse politiche di load balancing:
Round Robin
@Clustered(loadBalancePolicy="org.jboss.ha.client.loadbalance.RoundRobin")
First Available
@Clustered(loadBalancePolicy="org.jboss.ha.client.loadbalance.FirstAvailable")
Random
@Clustered(loadBalancePolicy="org.jboss.ha.client.loadbalance.RandomRobin")
Failover
In caso di guasto di un nodo, il client viene automaticamente reindirizzato:
1. Il client riceve un'eccezione 2. Lo stub consulta la lista dei nodi disponibili 3. La chiamata viene reinviata ad un altro nodo 4. Lo stato (per stateful) viene recuperato dalla replica
Best Practices
- Minimizzare lo stato nei session bean stateful
- Usare stateless quando possibile
- Configurare timeout appropriati per le cache
- Monitorare la replicazione
- Testare il failover
Conclusioni
Il clustering di EJB richiede attenzione particolare alla gestione dello stato e alla configurazione della replicazione. JBoss fornisce strumenti potenti ma è necessario comprenderne il funzionamento per evitare problemi di performance e consistenza.
