Skip to main content

Command Palette

Search for a command to run...

Developer Guide: Quarkus Nanoservices with CockroachDB Using Reactive Panache

Published
4 min read

Absolutely! Here’s a final, comprehensive developer write-up incorporating everything we’ve agreed on — small reactive pools per nanoservice, named datasources, safe parallel access, and CockroachDB configuration. This is ready for your team to use.



Overview

Your Quarkus application is composed of ~20 nanoservices (Verticles) running inside the same JVM process. Each nanoservice behaves like a microservice with its own business logic and database access layer.

Goals:

  • Each nanoservice performs its own DB queries to CockroachDB.

  • Maintain logical isolation per nanoservice while running in the same JVM.

  • Manage database connections efficiently to avoid overload.

  • Use reactive programming (Panache Reactive) to maximize throughput.

  • Ensure safe parallel access by multiple nanoservices.


Key Architecture Decision

  • Each nanoservice will use a named reactive datasource with a very small connection pool.

  • This gives:

    • Isolation: Each nanoservice has its own pool, independent of others.

    • Tunable pools: Small pool sizes (e.g., 5 connections) reduce total connections while supporting high concurrency.

    • Future-proofing: Easy to move a nanoservice to a different database, schema, or credentials if needed.

  • Total connections = sum of all nanoservice pools (e.g., 20 nanoservices × 5 connections = 100 connections).

  • Each pool is reactive, so even a small number of connections can handle many concurrent requests.


Dependencies to Add

Add the following dependencies in your Maven pom.xml:

<!-- Reactive Panache for Hibernate -->
<dependency>
    <groupId>io.quarkus</groupId>
    <artifactId>quarkus-hibernate-reactive-panache</artifactId>
</dependency>

<!-- Reactive PostgreSQL client (compatible with CockroachDB) -->
<dependency>
    <groupId>io.quarkus</groupId>
    <artifactId>quarkus-reactive-pg-client</artifactId>
</dependency>

Configuration (application.properties)

Create a named datasource for each nanoservice. Keep the pool small to reduce total connections.

# Nanoservice 1
quarkus.datasource.ns1.db-kind=postgresql
quarkus.datasource.ns1.reactive.url=postgresql://user:password@cockroachdb-host:26257/dbname
quarkus.datasource.ns1.reactive.max-size=5

# Nanoservice 2
quarkus.datasource.ns2.db-kind=postgresql
quarkus.datasource.ns2.reactive.url=postgresql://user:password@cockroachdb-host:26257/dbname
quarkus.datasource.ns2.reactive.max-size=5

# Repeat for all nanoservices

Optional tuning parameters:

quarkus.datasource.ns1.reactive.initial-size=2
quarkus.datasource.ns1.reactive.idle-removal-interval=PT10M
quarkus.datasource.ns1.reactive.max-lifetime=PT30M

Usage in Nanoservices

Each nanoservice injects its own reactive repository or session using the named datasource:

@ApplicationScoped
public class Nanoservice1Repository {

    @Inject
    @DataSource("ns1")
    ReactiveSession session;

    public Uni<List<Product>> findAll() {
        return session.createQuery("from Product", Product.class).getResultList();
    }

    public Uni<Product> findById(Long id) {
        return session.find(Product.class, id);
    }
}

Safe parallel access

  • Reactive Panache repositories and sessions are thread-safe.

  • R2DBC driver is non-blocking and supports multiplexing many queries over a small pool.

  • Multiple nanoservices can execute queries concurrently on the same JVM without locks or contention.

  • Queries are independent asynchronous operations; no global locks are held.

  • Connection pooling ensures queries wait briefly if all connections are busy, without blocking threads.


Best Practices

  1. Pool sizing:

    • Start with very small pools (5–10 connections) per nanoservice.

    • Adjust only if load increases or queries are long-running.

  2. Monitoring:

    • Use CockroachDB Admin UI or SQL to monitor sessions:

        SHOW SESSIONS;
      
    • Watch total connections to ensure you don’t exceed database limits.

  3. Isolation:

    • Each nanoservice uses its own @DataSource for full logical isolation.

    • Misbehaving or long-running queries in one service will not impact others.

  4. Reactive programming:

    • Always use Uni or Multi from reactive Panache.

    • Avoid blocking calls; leverage non-blocking DB access for high throughput.

  5. Future expansion:

    • Named datasources make it easy to point nanoservices to different DBs, schemas, or credentials in the future.

Summary Table

TopicRecommendation
DB DriverUse quarkus-reactive-pg-client (PostgreSQL compatible)
Connection PoolingNamed reactive datasource per nanoservice, small pool (5–10 connections)
Pool Size5–10 connections per nanoservice, adjust if needed
Reactive Frameworkquarkus-hibernate-reactive-panache
DB Access CodeInject reactive session or Panache repository with @DataSource("name")
Parallel AccessThread-safe; non-blocking queries; no locks
MonitoringCockroachDB Admin UI or SHOW SESSIONS
Future-proofingNamed datasources allow independent DB access per nanoservice

✅ Developer Notes

  • Do not open a connection per request; always rely on reactive pooling.

  • Keep nanoservice logic and DB access isolated via named datasources.

  • Use reactive queries for all DB access to maximize concurrency.

  • Monitor pool usage and total DB connections to prevent overload.

  • This approach balances isolation, safety, scalability, and simplicity.


This is the final recommended setup for your 20 nanoservices running in a single JVM with CockroachDB, giving you efficient, safe, and future-proof DB access.