todos con una migración de Flyway y atenderá solicitudes de creación, lectura, actualización y eliminación desde un controlador REST de Spring Data JPA. Todas las conexiones usan TLS con verificación completa del certificado.
Requisitos previos
- JDK 17 o posterior, como exige Spring Boot 4. Esta guía se probó con Java 25, Spring Boot 4.1.1, pgjdbc 42.7.13, Hibernate 7.4.5, HikariCP 7.0.2 y Flyway 12.4.0.
- Una cuenta de ClickHouse Cloud
psql, para crear la base de datos. También puede ejecutar la sentenciaCREATE DATABASEen la consola SQL.
Crear un servicio de ClickHouse Managed Postgres
En la consola de ClickHouse Cloud, haga clic en New service y seleccione Postgres. La instancia estará lista en unos minutos. Consulte la guía de inicio rápido para ver el proceso paso a paso.Obtener los datos de conexión
Haga clic en Conectar en la barra lateral izquierda de su servicio. El cuadro de diálogo muestra su nombre de usuario, contraseña, servidor y puerto, e incluye un toggle Directly / via PgBouncer. Con Directly seleccionado, active Use SSL y abra la pestaña jdbc. Allí verá una URL JDBC que podrá usar en Spring Boot tras realizar dos cambios, que se describen en Configurar la conexión: el nombre de la base de datos y el nombre del archivo del certificado de la CA.5432. Una aplicación Spring Boot es un proceso de larga duración que mantiene su propio grupo de conexiones de HikariCP (10 conexiones de forma predeterminada), por lo que no necesita un segundo pooler delante de Postgres. Asegúrese de que el número de instancias de la aplicación multiplicado por el tamaño del grupo se mantenga por debajo del valor de max_connections del servicio. Si ejecuta muchas instancias, consulte Usar PgBouncer.
En el cuadro de diálogo, haga clic en Download CA certificate. También puede descargarlo desde Settings → CA Certificate. El certificado es exclusivo de su instancia, de modo que el controlador puede usarlo para verificar que se está comunicando con su servidor.
Configurar el proyecto
Genere un proyecto Maven con Spring Initializr que incluya las dependencias Spring Web, Spring Data JPA, Flyway Migration y PostgreSQL Driver:Configurar la conexión
Mueva el certificado de CA que descargó al directorio del proyecto y cámbiele el nombre aca-certificate.pem.
Cree una base de datos para la aplicación. Sustituya <PASSWORD> y el host por los valores del cuadro de diálogo Conectar:
src/main/resources/application.properties por lo siguiente. En una aplicación existente, agregue las líneas spring.datasource y spring.jpa y elimine cualquier otra configuración de spring.datasource, como una URL de H2. La URL es la de la pestaña jdbc, cambiando la base de datos a guide_spring y sslrootcert al archivo renombrado:
src/main/resources/application.properties
sslmode=verify-full y sslrootcert de la URL. Carga todos los certificados del archivo de la CA y verifica tanto la cadena de certificados como el nombre del host, por lo que no necesita código TLS adicional. Spring Boot lee la contraseña de la variable de entorno DATABASE_PASSWORD, de modo que no queda expuesta en el archivo.
El resto de la configuración:
ddl-auto=validatehace que Hibernate compruebe durante el inicio que sus entidades coinciden con las tablas que crea Flyway. Hibernate no modifica el esquema.open-in-view=falsedevuelve cada conexión al grupo en cuanto finaliza su transacción, en lugar de retenerla hasta que se escribe la respuesta HTTP.
Una ruta relativa en
sslrootcert se resuelve con respecto al directorio de trabajo de la JVM. ./mvnw spring-boot:run inicia la aplicación en el directorio del proyecto, así que ca-certificate.pem funciona en ese caso. Si ejecuta el JAR empaquetado desde otra ubicación, use una ruta absoluta. pgjdbc no expande ~.Si copia la URL con Use SSL desactivado, esta no incluye sslmode y pgjdbc recurre a prefer: cifra la conexión, pero no verifica el servidor. Si la CA es incorrecta, la conexión falla con PKIX path building failed. Si falta el archivo, falla con Could not open SSL root certificate file. Si el host no coincide con el certificado (por ejemplo, al conectarse mediante una dirección IP), falla con The hostname ... could not be verified by hostnameverifier PgjdbcHostnameVerifier.Crear la tabla con Flyway
Flyway ejecuta los archivos SQL desrc/main/resources/db/migration por orden de versión al iniciarse la aplicación, antes de que Hibernate valide el esquema. Cree src/main/resources/db/migration/V1__create_todos.sql:
src/main/resources/db/migration/V1__create_todos.sql
flyway_schema_history y, en los inicios posteriores, solo ejecuta los archivos nuevos. Para modificar el esquema, agregue un archivo nuevo, como V2__add_due_date.sql, en lugar de editar uno que ya se haya ejecutado.
Una aplicación que usaba H2 normalmente dejaba que Hibernate creara sus tablas, ya que
ddl-auto toma por defecto el valor create-drop en las bases de datos embebidas. En Postgres, el valor predeterminado es none, por lo que debe agregar una migración que cree sus tablas existentes. Además, un @Id con un @GeneratedValue simple requiere una secuencia con el nombre de la entidad, como employee_seq para Employee, que se incremente en 50, el tamaño de asignación predeterminado de Hibernate. De lo contrario, el inicio falla con Schema validation: missing sequence [employee_seq] o, si la secuencia se incrementa en 1, con 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]:Consultar la base de datos
Cree la entidad ensrc/main/java/com/example/todos/Todo.java. Spring Boot mapea el campo createdAt a la columna created_at:
src/main/java/com/example/todos/Todo.java
src/main/java/com/example/todos/TodoRepository.java. Spring Data implementa la interfaz en tiempo de ejecución:
src/main/java/com/example/todos/TodoRepository.java
src/main/java/com/example/todos/TodoController.java, con una llamada al repositorio por ruta:
src/main/java/com/example/todos/TodoController.java
@Transactional.
Ejecutar y verificar
Configure la contraseña e inicie la aplicación:POST devuelven las filas nuevas y la solicitud PATCH devuelve la fila actualizada. -w '\n' añade un salto de línea después de cada respuesta:
pg_stat_ssl mientras la aplicación está en ejecución:
guide_spring y después public, y haga clic en la tabla todos. La tabla flyway_schema_history, que aparece junto a ella, almacena el historial de migraciones. La tabla todos contiene la fila restante:
Usar PgBouncer
Cuando el conjunto de instancias de la aplicación se acerque al límite de conexiones de Postgres, conecte la aplicación a través del PgBouncer incluido, en el puerto6432, y mantenga Flyway en la conexión directa. En application.properties, cambie el puerto de spring.datasource.url a 6432 y agregue debajo las líneas spring.flyway:
src/main/resources/application.properties
spring.flyway.url, Flyway abre su propia conexión y no utiliza el nombre de usuario ni la contraseña de spring.datasource, por lo que también debe establecer spring.flyway.user y spring.flyway.password. El mismo certificado de CA sirve para ambos puertos.
PgBouncer se ejecuta en modo de agrupación por transacción, por lo que cada transacción puede ejecutarse en una conexión de Postgres distinta. Con Spring Boot:
- Las sentencias preparadas funcionan con la configuración predeterminada del controlador, así que no necesita
prepareThreshold=0. A partir de la quinta ejecución de una sentencia en una misma conexión (prepareThreshold), pgjdbc utiliza una sentencia preparada con nombre del lado del servidor. Las sentencias se liberan mediante un mensajeClosea nivel de protocolo, que el PgBouncer incluido admite. - Se requiere pgjdbc 42.7.5 o posterior. Las versiones anteriores envían el parámetro de inicio
extra_float_digits, y PgBouncer rechaza la conexión conFATAL: unsupported startup parameter: extra_float_digits. Spring Boot 4 incluye una versión más reciente de pgjdbc. En versiones anteriores de Spring Boot, establezca<postgresql.version>42.7.13</postgresql.version>en la sección<properties>depom.xml. - La configuración de sesión no persiste. Las sentencias
SETyConnection.setSchema(que utiliza la propiedadspring.datasource.hikari.schemade HikariCP) solo se aplican a la conexión de Postgres que las ejecuta y pueden filtrarse a otros clientes. Los parámetros de URLcurrentSchemayoptionsfallan conFATAL: unsupported startup parameter. Utilice nombres de tabla calificados con el esquema oSET LOCALdentro de una transacción. - Flyway funciona a través de PgBouncer de forma predeterminada, ya que adquiere un bloqueo consultivo a nivel de transacción. Las migraciones que ejecutan
CREATE INDEX CONCURRENTLYrequierenspring.flyway.postgresql.transactional-lock=false, que hace que Flyway use un bloqueo a nivel de sesión. A través de PgBouncer, ese bloqueo falla conUnable to release PostgreSQL advisory locky queda retenido en una conexión agrupada, por lo que debe usar la conexión directa para Flyway. - Tamaño del grupo: cada conexión de HikariCP es una conexión de cliente a PgBouncer con un coste mínimo. PgBouncer limita las conexiones de Postgres que abre para cada base de datos y usuario (
default_pool_size), independientemente de cuántas conexiones de cliente abran las instancias de su aplicación. Las transacciones que superan ese límite esperan en PgBouncer hastaquery_wait_timeout(120 segundos de forma predeterminada) en lugar de fallar en HikariCP. Ampliar el grupo de HikariCP solo aumenta la concurrencia hasta ese límite, por lo que el valor predeterminado de 10 por instancia es un buen punto de partida. Consulte Límites de conexión de PgBouncer y Postgres.
pg_stat_ssl informa sobre la conexión entre PgBouncer y Postgres, por lo que la consulta de TLS de Ejecutar y verificar no muestra las conexiones de la aplicación a través de PgBouncer. Aun así, la conexión de la aplicación a PgBouncer sí se verifica: con un certificado de CA incorrecto, falla igualmente.
Próximos pasos
- Conexión: cadenas de conexión, PgBouncer y TLS
- Configuración: parámetros de Postgres y PgBouncer, como
max_connections - Réplicas de lectura: envíe consultas de solo lectura a una réplica
- Seguridad: listas de acceso por IP y redes privadas