A plain Java Dubbo provider used by the Rust-Java REST consumer sample.
- It does not use Spring Boot.
- It can run without ZooKeeper.
- It can register itself in ZooKeeper.
- It can serve ready JSON or typed records.
- The full profile uses PostgreSQL and HikariCP.
Current versions: java-rust-dubbo:0.5.0, rest-sample-utility:0.3.0, rust-sample-model:0.3.0.
Choose one provider shape.
| Need | Maven profile | Includes |
|---|---|---|
| Small ready-JSON catalog provider | catalog-static-provider |
One catalog interface; no DB and no ZooKeeper |
| Read-only PostgreSQL provider | db-query-provider |
Customer queries and HikariCP; no commands |
| Catalog, queries, and commands | full-provider |
Full sample; active by default |
Do not package the full provider when the service only needs one catalog method. The smaller profile loads fewer classes and uses less memory.
Run from this repository:
$env:GITHUB_PACKAGES_TOKEN="YOUR_TOKEN_WITH_READ_PACKAGES"
mvn -q -Pcatalog-static-provider clean package
java `
"-Ddubbo.provider.host=127.0.0.1" `
"-Ddubbo.provider.bind-host=127.0.0.1" `
"-Ddubbo.provider.port=20880" `
"-Dreactor.dubbo.registry-enabled=false" `
-jar target/rest-sample-dubbo-provider-0.4.0.jarUse it with the consumer's native-static-consumer profile.
Start PostgreSQL:
docker rm -f rs-provider-postgres-test 2>$null
docker run -d --name rs-provider-postgres-test `
-e POSTGRES_DB=reactor_sample `
-e POSTGRES_USER=reactor `
-e POSTGRES_PASSWORD=reactor `
-p 15432:5432 postgres:16-alpineBuild and start the provider:
$env:GITHUB_PACKAGES_TOKEN="YOUR_TOKEN_WITH_READ_PACKAGES"
mvn -q clean package
java `
"-Dreactor.dubbo.registry-enabled=false" `
"-Dsample.db.jdbc-url=jdbc:postgresql://127.0.0.1:15432/reactor_sample" `
"-Dsample.db.username=reactor" `
"-Dsample.db.password=reactor" `
"-Dsample.db.schema-init=true" `
"-Dsample.db.warmup=true" `
-jar target/rest-sample-dubbo-provider-0.4.0.jarThe provider listens on 127.0.0.1:20880.
Start the consumer with:
sample.dubbo.discovery=static
reactor.dubbo.providers=127.0.0.1:20880The provider does not expose HTTP endpoints. It exports Dubbo interfaces.
| Interface | Example methods | Data shape |
|---|---|---|
CatalogJsonService |
getNestedCatalogJson() |
Ready JSON byte[] |
NestedCatalogService |
title, count, info, item list, attributes | String, primitive, record, list, map |
CustomerQueryService |
customer, segment list, stats, exists | Ready JSON and typed results |
CustomerCommandService |
create, patch, delete | JSON bytes and typed command records |
The shared interface package must stay com.reactor.rust.dubbo.sample. Dubbo uses the full interface name as the service identity.
Use this when the consumer reaches the provider through a known address or Kubernetes Service DNS.
reactor.dubbo.registry-enabled=false
dubbo.provider.bind-host=0.0.0.0
dubbo.provider.port=20880Kubernetes example:
rest-sample-dubbo-provider:20880
The Service can point to one or many provider pods.
Use this when the provider must register itself in a Dubbo registry.
reactor.dubbo.registry-enabled=true
reactor.dubbo.registry-address=zookeeper://zookeeper-client.platform.svc.cluster.local:2181
reactor.dubbo.registry-root=dubboZooKeeper is optional. Do not enable it only because the provider uses Dubbo.
The default production shape is intentionally small:
sample.db.maximum-pool-size=2
sample.db.minimum-idle=0
dubbo.provider.executor.core-threads=1
dubbo.provider.executor.max-threads=8
dubbo.provider.executor.queue-capacity=16
dubbo.provider.service.CustomerQueryService.max-concurrent=2
dubbo.provider.service.CustomerCommandService.max-concurrent=2
dubbo.provider.service.CustomerCommandService.method.patchCustomerStatus.max-concurrent=1Why:
- HikariCP has two database connections.
- Query and command concurrency stays close to real DB capacity.
- Same-row updates run one at a time.
- A bounded queue prevents unlimited memory growth.
Increase the DB pool and service limits together. First check PostgreSQL CPU, connection count, lock wait, and query latency.
Do not increase only the queue. That delays failures and usually slows the worst requests.
| Need | Provider return type | Result |
|---|---|---|
| Consumer forwards JSON without reading fields | byte[] containing UTF-8 JSON |
Creates the fewest Java objects |
| Consumer needs one value | Primitive or String |
Small typed contract |
| Consumer makes business decisions | Small immutable record |
Clear contract with Hessian decode cost |
| Consumer forwards a large page | Ready JSON byte[] |
Avoids a large record/list graph |
Typed DTO packages must be present on both sides and allowed by Hessian security:
src/main/resources/security/serialize.allowlist
The application reads configuration in this order:
src/main/resources/rest-sample-dubbo-provider.properties- Files passed through
reactor.config.fileorREACTOR_CONFIG_FILE - JVM
-D...values and supported environment variables
| File | Purpose |
|---|---|
rest-sample-dubbo-provider.properties |
Local provider, registry, service limit, and DB defaults |
config/production.properties |
Kubernetes bind address and low-memory HikariCP defaults |
config/advanced-tuning.properties |
Per-method limits and Netty/Dubbo memory controls |
Production should run database migrations outside this process:
sample.db.schema-init=falseThe sample sets it to true only for an easy local start.
| Image definition | Use |
|---|---|
docker/images/Dockerfile.jlink.catalog-static |
Small catalog-only provider |
docker/images/Dockerfile.jlink.db-query |
PostgreSQL query-only provider |
docker/images/Dockerfile.jlink |
Full provider |
docker/images/Dockerfile |
Full Docker Compose provider |
See docker/images/README.md before building a jlink image. Container builds also need Maven access to the private shared packages.
| File | Why it matters |
|---|---|
RestSampleDubboProviderApplication.java |
Starts the full provider |
CatalogStaticProviderApplication.java |
Starts the catalog-only provider |
DbQueryOnlyProviderApplication.java |
Starts the DB query-only provider |
*ProviderModule.java |
Declares exported services |
CustomerQueryServiceImpl.java |
DB read examples |
CustomerCommandServiceImpl.java |
DB command examples |
PostgresCustomerRepository.java |
SQL, transaction, and paging logic |
rest-sample-dubbo-provider.properties |
Local settings |
GitHub Packages requires a token with read:packages. The token also needs access to the private shared sample repositories.
The server IDs in ~/.m2/settings.xml must match the POM:
<servers>
<server>
<id>github-java-rust-dubbo</id>
<username>YOUR_GITHUB_USERNAME</username>
<password>${env.GITHUB_PACKAGES_TOKEN}</password>
</server>
<server>
<id>github-rest-sample-utility</id>
<username>YOUR_GITHUB_USERNAME</username>
<password>${env.GITHUB_PACKAGES_TOKEN}</password>
</server>
<server>
<id>github-rust-sample-model</id>
<username>YOUR_GITHUB_USERNAME</username>
<password>${env.GITHUB_PACKAGES_TOKEN}</password>
</server>
</servers>| Symptom | Check |
|---|---|
Maven returns 401 |
Token, private repo access, and all server IDs |
Port 20880 is unavailable |
Another provider or container already uses it |
| Consumer cannot connect | Bind host, advertised host, port, Service DNS, and firewall |
| PostgreSQL connection fails | JDBC URL, 15432 port, username, and password |
| Typed DTO is rejected | Shared model version and serialize.allowlist |
| Some write requests are much slower | DB lock wait, Hikari pool wait, method limit, and same-row contention |