Introduzione allo strato web
Dopo aver analizzato il clustering di EJB nelle parti precedenti, concludiamo la serie esaminando lo strato web: load balancing HTTP e replicazione delle sessioni.
Load Balancing HTTP
Il load balancing distribui le richieste HTTP tra i vari nodi del cluster.
Tecniche di Load Balancing
Hardware Load Balancer
Dispositivi dedicati (F5, Cisco, etc.):
- Performance elevate
- Alta affidabilità
- Costo elevato
- Configurazione complessa
Software Load Balancer
Soluzioni software come modjk, modproxy:
- Costo contenuto
- Flessibilità
- Performance buone
- Configurazione semplice
DNS Round Robin
Tecnica basata su DNS:
- Semplicissima
- No single point of failure
- Nessun controllo sullo stato dei nodi
- Non consigliata per produzione
Configurazione Apache + mod_jk
Configurazione tipica per load balancing con Apache:
workers.properties
worker.list=loadbalancer,status worker.node1.type=ajp13 worker.node1.host=server1 worker.node1.port=8009 worker.node1.lbfactor=1 worker.node2.type=ajp13 worker.node2.host=server2 worker.node2.port=8009 worker.node2.lbfactor=1 worker.loadbalancer.type=lb worker.loadbalancer.balance_workers=node1,node2 worker.loadbalancer.sticky_session=1
httpd.conf
LoadModule jk_module modules/mod_jk.so
JkWorkersFile conf/workers.properties
JkLogFile logs/mod_jk.log
JkLogLevel info
<VirtualHost *:80>
ServerName www.example.com
JkMount /* loadbalancer
</VirtualHost>
Session Replication
Per garantire failover trasparente, le sessioni HTTP devono essere replicate.
Configurazione in JBoss
web.xml
<web-app>
<distributable/>
<session-config>
<session-timeout>30</session-timeout>
</session-config>
</web-app>
jboss-web.xml
<jboss-web>
<replication-config>
<replication-trigger>SET_AND_NON_PRIMITIVE_GET</replication-trigger>
<replication-granularity>SESSION</replication-granularity>
<use-jk>true</use-jk>
</replication-config>
</jboss-web>
Modalità di replica
SESSION granularity
Replica l'intera sessione ad ogni modifica:
- Semplice
- Overhead di rete maggiore
- Consigliata per sessioni piccole
ATTRIBUTE granularity
Replica solo gli attributi modificati:
- Più efficiente
- Complessità maggiore
- Consigliata per sessioni grandi
FIELD granularity
Replica solo i campi modificati degli oggetti:
- Massima efficienza
- Complessità massima
- Per casi specifici
Sticky Sessions
Le sticky session associano un client ad un nodo specifico:
worker.loadbalancer.sticky_session=1 worker.loadbalancer.sticky_session_force=0
Vantaggi
- Riduce traffico di replica
- Migliori performance
- Uso ottimale cache locali
Svantaggi
- Failover più complesso
- Possibile sbilanciamento
- Sessioni perse su restart
Best Practices per le sessioni
Minimizzare la dimensione
// Male: oggetti grandi in sessione
session.setAttribute("risultati", listaCompleta);
// Bene: solo riferimenti essenziali
session.setAttribute("risultatiId", idRisultati);
Usare oggetti serializzabili
public class CarrelloBean implements Serializable {
private static final long serialVersionUID = 1L;
private List<Prodotto> prodotti;
}
Configurare timeout appropriati
<session-config>
<session-timeout>30</session-timeout>
</session-config>
Implementare session cleanup
@WebListener
public class SessionCleanupListener implements HttpSessionListener {
public void sessionDestroyed(HttpSessionEvent event) {
// Pulizia risorse
}
}
Monitoring e troubleshooting
JMX MBeans
Per monitorare lo stato del cluster:
MBeanServer server = ManagementFactory.getPlatformMBeanServer();
ObjectName name = new ObjectName("jboss.web:type=Manager,*");
Set<ObjectInstance> instances = server.queryMBeans(name, null);
Log analysis
Analizzare i log per identificare problemi:
grep "Session replication" server.log grep "Failover" server.log grep "Load balancing" mod_jk.log
Testing del cluster web
Test di load balancing
Verificare la distribuzione delle richieste:
for i in {1..100}; do
curl -s http://www.example.com/test.jsp | grep "Server:"
done | sort | uniq -c
Test di failover
Simulare guasto di un nodo:
1. Creare una sessione 2. Annotare sessionId 3. Fermare il nodo corrente 4. Verificare che la sessione persista
Test di session replication
Verificare la replica:
@WebServlet("/test-replication")
public class ReplicationTestServlet extends HttpServlet {
protected void doGet(HttpServletRequest req, HttpServletResponse resp) {
HttpSession session = req.getSession();
Integer counter = (Integer)session.getAttribute("counter");
counter = (counter == null) ? 1 : counter + 1;
session.setAttribute("counter", counter);
resp.getWriter().println("Counter: " + counter);
resp.getWriter().println("Node: " + System.getProperty("jboss.node.name"));
}
}
Conclusioni
Il clustering dello strato web completa l'architettura ad alta disponibilità. La combinazione di load balancing e session replication permette di costruire applicazioni scalabili e resilienti. È fondamentale testare accuratamente il comportamento del cluster, specialmente i scenari di failover.
Questa serie di tre articoli ha coperto tutti gli aspetti del clustering J2EE: dalla configurazione base, al clustering EJB, fino allo strato web. Con queste competenze è possibile progettare e implementare architetture enterprise robuste e scalabili.
