Chapitre 1: Configuration des Datasources
Introduction
Chaque fois que votre application Spring Boot interagit avec la base de données, elle utilise une connexion. Mais d'où viennent ces connexions? Comment sont-elles gérées? C'est le rôle de la Datasource.
🎯 Objectifs du Chapitre
À la fin de ce chapitre, vous saurez:
- ✅ Ce qu'est une Datasource et pourquoi c'est important
- ✅ Comment Spring Boot configure automatiquement les connexions
- ✅ Configurer HikariCP (le pool par défaut)
- ✅ Optimiser les paramètres pour la production
- ✅ Configurer plusieurs datasources
1. Qu'est-ce qu'une Datasource?
Définition Simple
Une Datasource est un objet qui fournit des connexions à la base de données.
Le Problème Sans Pool de Connexions
// ❌ MAUVAISE PRATIQUE: Nouvelle connexion à chaque requête
public void getUser(Long id) {
Connection conn = DriverManager.getConnection(url, user, password);
// ... utiliser la connexion
conn.close();
}
Problèmes:
- Créer une connexion = 500ms à 1s (très lent!)
- 100 utilisateurs simultanés = 100 connexions = BDD saturée
- Pas de réutilisation = gaspillage de ressources
La Solution: Pool de Connexions
// ✅ BONNE PRATIQUE: Réutiliser les connexions
public void getUser(Long id) {
Connection conn = dataSource.getConnection(); // ← Connexion du pool (< 1ms)
// ... utiliser la connexion
conn.close(); // ← Retourne au pool (pas vraiment fermée)
}
Avantages:
- Connexions pré-créées = réponse instantanée
- Réutilisation = moins de charge sur la BDD
- Limite le nombre max de connexions
2. HikariCP: Le Pool par Défaut
Pourquoi HikariCP?
Spring Boot utilise HikariCP (光 = "lumière" en japonais) car c'est:
- 🚀 Le plus rapide (benchmarks prouvés)
- 💪 Le plus fiable (utilisé par de grosses entreprises)
- 🔧 Simple à configurer
Auto-Configuration Spring Boot
Quand vous ajoutez une dépendance de base de données, Spring Boot configure automatiquement HikariCP:
<!-- pom.xml -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
<!-- HikariCP est inclus automatiquement! -->
</dependency>
3. Configuration de Base
Configuration Minimale (H2)
# application.properties
spring.datasource.url=jdbc:h2:mem:testdb
spring.datasource.driver-class-name=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=
Configuration PostgreSQL
# application.properties
spring.datasource.url=jdbc:postgresql://localhost:5432/mydb
spring.datasource.driver-class-name=org.postgresql.Driver
spring.datasource.username=postgres
spring.datasource.password=secret
Configuration MySQL
# application.properties
spring.datasource.url=jdbc:mysql://localhost:3306/mydb?useSSL=false&serverTimezone=UTC
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.username=root
spring.datasource.password=secret
4. Configuration HikariCP Avancée
Paramètres Essentiels
# application.properties
# Taille du pool
spring.datasource.hikari.minimum-idle=5 # Connexions minimum maintenues
spring.datasource.hikari.maximum-pool-size=10 # Connexions maximum
# Timeouts
spring.datasource.hikari.connection-timeout=30000 # Attente max pour obtenir une connexion (30s)
spring.datasource.hikari.idle-timeout=600000 # Temps avant de fermer une connexion idle (10min)
spring.datasource.hikari.max-lifetime=1800000 # Durée de vie max d'une connexion (30min)
# Nom du pool (pour les logs)
spring.datasource.hikari.pool-name=MyAppPool
Visualisation du Pool
┌─────────────────────────────────────────────────────┐
│ HikariCP Pool │
│ │
│ minimum-idle=5 maximum-pool-size=10 │
│ ┌─────┐ ┌─────┐ ┌─────┐ ┌─────┐ ┌─────┐ │
│ │Conn1│ │Conn2│ │Conn3│ │Conn4│ │Conn5│ (idle) │
│ └─────┘ └─────┘ └─────┘ └─────┘ └─────┘ │
│ │
│ + 5 connexions supplémentaires si besoin │
│ │
│ connection-timeout=30s (attente max si pool plein) │
└─────────────────────────────────────────────────────┘
Format YAML (Alternative)
# application.yml
spring:
datasource:
url: jdbc:postgresql://localhost:5432/mydb
username: postgres
password: secret
hikari:
minimum-idle: 5
maximum-pool-size: 10
connection-timeout: 30000
idle-timeout: 600000
max-lifetime: 1800000
pool-name: MyAppPool
5. Recommandations par Environnement
Développement (H2)
# application-dev.properties
spring.datasource.url=jdbc:h2:mem:devdb
spring.datasource.hikari.minimum-idle=2
spring.datasource.hikari.maximum-pool-size=5
# Console H2 activée
spring.h2.console.enabled=true
Production (PostgreSQL)
# application-prod.properties
spring.datasource.url=jdbc:postgresql://db.server.com:5432/proddb
spring.datasource.hikari.minimum-idle=10
spring.datasource.hikari.maximum-pool-size=50
# Pas de console H2!
spring.h2.console.enabled=false
# Validation des connexions
spring.datasource.hikari.connection-test-query=SELECT 1
Formule pour maximum-pool-size
Règle empirique:
maximum-pool-size = (nombre de CPU * 2) + nombre de disques
Exemple:
- Serveur avec 4 CPU et 1 disque SSD
- Pool size = (4 * 2) + 1 = 9 ≈ 10
Ne surdimensionnez pas! Un pool trop grand peut dégrader les performances car la BDD doit gérer trop de connexions simultanées.
6. Configuration Multi-Datasources
Cas d'Utilisation
Parfois, une application doit se connecter à plusieurs bases de données:
Configuration
# application.properties
# Datasource primaire (PostgreSQL)
spring.datasource.primary.url=jdbc:postgresql://localhost:5432/usersdb
spring.datasource.primary.username=postgres
spring.datasource.primary.password=secret
spring.datasource.primary.driver-class-name=org.postgresql.Driver
# Datasource secondaire (MySQL)
spring.datasource.secondary.url=jdbc:mysql://localhost:3306/productsdb
spring.datasource.secondary.username=root
spring.datasource.secondary.password=secret
spring.datasource.secondary.driver-class-name=com.mysql.cj.jdbc.Driver
Configuration Java
@Configuration
public class DataSourceConfig {
// Datasource primaire
@Primary
@Bean(name = "primaryDataSource")
@ConfigurationProperties(prefix = "spring.datasource.primary")
public DataSource primaryDataSource() {
return DataSourceBuilder.create().build();
}
// Datasource secondaire
@Bean(name = "secondaryDataSource")
@ConfigurationProperties(prefix = "spring.datasource.secondary")
public DataSource secondaryDataSource() {
return DataSourceBuilder.create().build();
}
}
Utilisation avec JPA
// Configuration EntityManager pour Primary
@Configuration
@EnableJpaRepositories(
basePackages = "com.example.repository.users",
entityManagerFactoryRef = "primaryEntityManager",
transactionManagerRef = "primaryTransactionManager"
)
public class PrimaryDatabaseConfig {
// ... configuration
}
// Configuration EntityManager pour Secondary
@Configuration
@EnableJpaRepositories(
basePackages = "com.example.repository.products",
entityManagerFactoryRef = "secondaryEntityManager",
transactionManagerRef = "secondaryTransactionManager"
)
public class SecondaryDatabaseConfig {
// ... configuration
}
7. Monitoring du Pool
Via Actuator
Ajoutez Spring Boot Actuator pour monitorer le pool:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
# application.properties
management.endpoints.web.exposure.include=health,metrics
management.endpoint.health.show-details=always
Métriques Disponibles
# Vérifier le pool
GET /actuator/metrics/hikaricp.connections
# Connexions actives
GET /actuator/metrics/hikaricp.connections.active
# Connexions en attente
GET /actuator/metrics/hikaricp.connections.pending
# Timeouts
GET /actuator/metrics/hikaricp.connections.timeout
Exemple de Réponse
{
"name": "hikaricp.connections.active",
"measurements": [
{
"statistic": "VALUE",
"value": 3.0
}
],
"availableTags": [
{
"tag": "pool",
"values": ["MyAppPool"]
}
]
}
8. Problèmes Courants et Solutions
❌ Connection Timeout
HikariPool-1 - Connection is not available, request timed out after 30000ms.
Causes:
- Pool trop petit
- Connexions non fermées (fuite)
- Requêtes trop lentes
Solutions:
# Augmenter le pool
spring.datasource.hikari.maximum-pool-size=20
# Augmenter le timeout
spring.datasource.hikari.connection-timeout=60000
# Activer les logs de fuite
spring.datasource.hikari.leak-detection-threshold=60000
❌ Too Many Connections
PostgreSQL: FATAL: too many connections for role "postgres"
Cause: Pool trop grand ou plusieurs instances
Solution:
# Réduire le pool
spring.datasource.hikari.maximum-pool-size=5
# Vérifier le max_connections de PostgreSQL
# SHOW max_connections;
❌ Connection Leak
HikariPool-1 - Connection leak detection triggered
Cause: Connexion jamais retournée au pool
Solution:
# Activer la détection de fuite
spring.datasource.hikari.leak-detection-threshold=30000
Puis trouver et corriger le code fautif (connexion non fermée).
9. Résumé
Points Clés
| Concept | Description |
|---|---|
| Datasource | Fournit les connexions à la BDD |
| HikariCP | Pool de connexions par défaut (le plus rapide) |
| minimum-idle | Connexions minimum maintenues |
| maximum-pool-size | Connexions maximum |
| connection-timeout | Temps max pour obtenir une connexion |
Checklist de Configuration
✅ Définir spring.datasource.url
✅ Définir username/password
✅ Configurer minimum-idle et maximum-pool-size
✅ Ajuster les timeouts selon l'environnement
✅ Monitorer avec Actuator
Configuration Recommandée
# Production
spring.datasource.url=jdbc:postgresql://localhost:5432/mydb
spring.datasource.username=myuser
spring.datasource.password=${DB_PASSWORD}
spring.datasource.hikari.minimum-idle=5
spring.datasource.hikari.maximum-pool-size=20
spring.datasource.hikari.connection-timeout=30000
spring.datasource.hikari.idle-timeout=600000
spring.datasource.hikari.max-lifetime=1800000
spring.datasource.hikari.pool-name=MyAppPool
🎯 Prochaine Étape
Maintenant que vous comprenez comment les connexions sont gérées, il est temps d'apprendre comment protéger l'intégrité de vos données avec les transactions.
➡️ Chapitre 2: Gestion des Transactions (@Transactional)