todos à l’aide d’une migration Flyway, puis traiter les requêtes de création, de lecture, de mise à jour et de suppression à partir d’un contrôleur REST Spring Data JPA. Toutes les connexions utilisent TLS avec vérification complète des certificats.
Prérequis
- JDK 17 ou version ultérieure, comme l’exige Spring Boot 4. Ce guide a été testé avec Java 25, Spring Boot 4.1.1, pgjdbc 42.7.13, Hibernate 7.4.5, HikariCP 7.0.2 et Flyway 12.4.0.
- Un compte ClickHouse Cloud
psql, pour créer la base de données. Vous pouvez également exécuter le statementCREATE DATABASEdans la console SQL.
Créer un service ClickHouse Managed Postgres
Dans la console ClickHouse Cloud, cliquez sur New service et sélectionnez Postgres. L’instance est prête en quelques minutes. Pour une présentation pas à pas, consultez le guide de démarrage rapide.Obtenir vos informations de connexion
Cliquez sur Connect dans la barre latérale gauche de votre service. La fenêtre modale affiche votre nom d’utilisateur, votre mot de passe, le serveur et le port, ainsi qu’un sélecteur Directly / via PgBouncer. Une fois Directly sélectionné, activez Use SSL et ouvrez l’onglet jdbc. Celui-ci affiche une URL JDBC utilisable dans Spring Boot moyennant deux modifications, que vous effectuerez dans la section Configurer la connexion : le nom de la base de données et le nom du fichier du certificat de CA.5432. Une application Spring Boot est un processus de longue durée qui gère son propre pool HikariCP (10 connexions par défaut) ; elle n’a donc pas besoin d’un second pooler devant Postgres. Veillez à ce que le nombre d’instances de l’application multiplié par la taille du pool reste inférieur à la valeur max_connections du service. Si vous exécutez de nombreuses instances, consultez Utiliser PgBouncer.
Dans la fenêtre modale, cliquez sur Download CA certificate. Vous pouvez également le télécharger depuis Settings → CA Certificate. Ce certificat étant propre à votre instance, le driver peut s’en servir pour vérifier qu’il communique bien avec votre serveur.
Configurer le projet
Générez un projet Maven avec Spring Initializr en ajoutant les dépendances Spring Web, Spring Data JPA, Flyway Migration et PostgreSQL Driver :Configurer la connexion
Déplacez le certificat de CA que vous avez téléchargé dans le répertoire du projet, puis renommez-le enca-certificate.pem.
Créez une base de données pour l’application. Remplacez <PASSWORD> et l’hôte par les valeurs affichées dans la fenêtre modale Connect :
src/main/resources/application.properties par ce qui suit. Dans une application existante, ajoutez les lignes spring.datasource et spring.jpa, puis supprimez tout autre paramètre spring.datasource, par exemple une URL H2. Il s’agit de l’URL de l’onglet jdbc, en remplaçant la base de données par guide_spring et en faisant pointer sslrootcert vers le fichier renommé :
src/main/resources/application.properties
sslmode=verify-full et sslrootcert dans l’URL. Il charge chaque certificat du fichier de CA et vérifie à la fois la chaîne de certificats et le nom d’hôte : vous n’avez donc besoin d’aucun code TLS supplémentaire. Spring Boot lit le mot de passe dans la variable d’environnement DATABASE_PASSWORD, si bien qu’il n’apparaît pas dans le fichier.
Les autres paramètres :
ddl-auto=validateindique à Hibernate de vérifier au démarrage que vos entités correspondent aux tables créées par Flyway. Hibernate ne modifie pas le schéma.open-in-view=falserestitue chaque connexion au pool dès la fin de sa transaction, au lieu de la conserver jusqu’à l’écriture de la réponse HTTP.
Un path
sslrootcert relatif est résolu par rapport au répertoire de travail de la JVM. ./mvnw spring-boot:run démarre l’application dans le répertoire du projet : ca-certificate.pem y est donc trouvé. Si vous exécutez le JAR empaqueté depuis un autre emplacement, utilisez un path absolu. pgjdbc ne développe pas ~.Si vous copiez l’URL avec Use SSL désactivé, elle ne contient pas de sslmode et pgjdbc utilise alors prefer : il chiffre la connexion, mais ne vérifie pas le serveur. Si la CA est incorrecte, la connexion échoue avec PKIX path building failed. Si le fichier est introuvable, elle échoue avec Could not open SSL root certificate file. Si l’hôte ne correspond pas au certificat, par exemple lorsque vous vous connectez via une adresse IP, elle échoue avec The hostname ... could not be verified by hostnameverifier PgjdbcHostnameVerifier.Créer la table avec Flyway
Au démarrage de l’application, Flyway exécute les fichiers SQL situés danssrc/main/resources/db/migration dans l’ordre de leurs versions, avant que Hibernate ne valide le schéma. Créez le fichier src/main/resources/db/migration/V1__create_todos.sql :
src/main/resources/db/migration/V1__create_todos.sql
flyway_schema_history et n’exécute que les nouveaux fichiers lors des démarrages suivants. Pour modifier le schéma, ajoutez un nouveau fichier, par exemple V2__add_due_date.sql, plutôt que de modifier un fichier déjà exécuté.
Une application qui utilisait H2 laissait généralement Hibernate créer ses tables, car
ddl-auto vaut par défaut create-drop pour les bases de données embarquées. Pour Postgres, la valeur par défaut est none : ajoutez donc une migration qui crée vos tables existantes. Un @Id associé à un simple @GeneratedValue nécessite également une séquence nommée d’après l’entité, par exemple employee_seq pour Employee, avec un incrément de 50, soit la taille d’allocation par défaut d’Hibernate. À défaut, le démarrage échoue avec l’erreur Schema validation: missing sequence [employee_seq], ou avec The increment size of the [employee_seq] sequence is set to [50] in the entity mapping but the mapped database sequence increment size is [1] si la séquence s’incrémente de 1 :Interroger la base de données
Créez l’entité danssrc/main/java/com/example/todos/Todo.java. Spring Boot mappe le champ createdAt sur la colonne created_at :
src/main/java/com/example/todos/Todo.java
src/main/java/com/example/todos/TodoRepository.java. Spring Data se charge d’implémenter l’interface au moment de l’exécution :
src/main/java/com/example/todos/TodoRepository.java
src/main/java/com/example/todos/TodoController.java, avec un seul appel au repository par route :
src/main/java/com/example/todos/TodoController.java
@Transactional.
Exécuter et vérifier
Définissez le mot de passe et lancez l’application :POST renvoient les nouvelles lignes et la requête PATCH renvoie la ligne mise à jour. L’option -w '\n' ajoute un saut de ligne après chaque réponse :
pg_stat_ssl pendant que l’application s’exécute :
guide_spring puis public, et cliquez sur la table todos. La table flyway_schema_history, juste à côté, contient l’historique des migrations. La table todos contient la ligne restante :
Utiliser PgBouncer
Lorsque l’ensemble des instances de l’application approche de la limite de connexions Postgres, connectez l’application via le PgBouncer intégré, sur le port6432, et conservez la connexion directe pour Flyway. Dans application.properties, remplacez le port dans spring.datasource.url par 6432, puis ajoutez en dessous les lignes spring.flyway suivantes :
src/main/resources/application.properties
spring.flyway.url est défini, Flyway ouvre sa propre connexion et n’utilise pas le nom d’utilisateur ni le mot de passe de spring.datasource. Définissez donc également spring.flyway.user et spring.flyway.password. Le même certificat de CA fonctionne pour les deux ports.
PgBouncer fonctionne en mode pool de connexions par transaction : chaque transaction peut donc s’exécuter sur une connexion Postgres différente. Avec Spring Boot :
- Les requêtes préparées fonctionnent avec les paramètres par défaut du driver ; vous n’avez donc pas besoin de
prepareThreshold=0. À partir de la cinquième exécution d’un statement sur une connexion (prepareThreshold), pgjdbc utilise une requête préparée nommée côté serveur. Il libère les statements à l’aide d’un messageCloseau niveau du protocole, que le PgBouncer fourni prend en charge. - pgjdbc 42.7.5 ou version ultérieure est obligatoire. Les versions plus anciennes envoient le paramètre de démarrage
extra_float_digits, et PgBouncer rejette alors la connexion avecFATAL: unsupported startup parameter: extra_float_digits. Spring Boot 4 embarque une version plus récente de pgjdbc. Avec les versions antérieures de Spring Boot, définissez<postgresql.version>42.7.13</postgresql.version>dans la section<properties>depom.xml. - Les paramètres de session ne sont pas conservés. Les statements
SETetConnection.setSchema(utilisé par la propriétéspring.datasource.hikari.schemade HikariCP) ne s’appliquent qu’à la connexion Postgres qui les exécute, et peuvent déborder sur d’autres clients. Les paramètres d’URLcurrentSchemaetoptionséchouent avecFATAL: unsupported startup parameter. Utilisez des noms de tables qualifiés par le schéma, ouSET LOCALà l’intérieur d’une transaction. - Flyway fonctionne par défaut via PgBouncer, car il acquiert un verrou consultatif (advisory lock) au niveau de la transaction. Les migrations qui exécutent
CREATE INDEX CONCURRENTLYnécessitentspring.flyway.postgresql.transactional-lock=false, ce qui fait basculer Flyway sur un verrou au niveau de la session. Via PgBouncer, ce verrou échoue avecUnable to release PostgreSQL advisory locket reste détenu sur une connexion du pool ; utilisez donc la connexion directe pour Flyway. - Taille du pool : chaque connexion HikariCP est une connexion client peu coûteuse vers PgBouncer. PgBouncer limite le nombre de connexions Postgres qu’il ouvre pour chaque base de données et chaque utilisateur (
default_pool_size), quel que soit le nombre de connexions client ouvertes par les instances de votre application. Les transactions au-delà de cette limite patientent dans PgBouncer jusqu’àquery_wait_timeout(120 secondes par défaut) au lieu d’échouer dans HikariCP. Agrandir le pool HikariCP n’augmente la concurrence que dans la limite de cette valeur ; la valeur par défaut de 10 par instance constitue donc un bon point de départ. Consultez PgBouncer et limites de connexions Postgres.
pg_stat_ssl rend compte de la connexion entre PgBouncer et Postgres ; la requête TLS de la section Exécuter et vérifier n’affiche donc pas les connexions de l’application passant par PgBouncer. La connexion de l’application à PgBouncer est néanmoins bien vérifiée : un certificat de CA incorrect provoque le même échec.
Prochaines étapes
- Connexion : chaînes de connexion, PgBouncer et TLS
- Paramètres : paramètres de Postgres et de PgBouncer, comme
max_connections - Répliques en lecture : envoyer des requêtes en lecture seule vers une réplique
- Sécurité : listes d’accès IP et réseau privé