Learn how to set up Apache Zookeeper to register microservices (Spring Boot 3.4.1) for discovery and explore its KV store for dynamic configuration. Zookeeper offers distributed synchronization capabilities suitable for microservices needing coordination or shared config.
-
Download Zookeeper.
- Visit Zookeeper Releases and download the latest stable release (e.g.,
zookeeper-3.8.2
).
- Visit Zookeeper Releases and download the latest stable release (e.g.,
-
Extract the Zookeeper archive.
- Windows:
- Extract (e.g.,
apache-zookeeper-3.8.2-bin.tar.gz
) intoC:\Zookeeper
.
- Extract (e.g.,
- macOS/Linux:
- Extract:
tar -xvzf apache-zookeeper-3.8.2-bin.tar.gz -C ~/Zookeeper
- Extract:
- Windows:
-
Set up the Zookeeper configuration.
- In the
conf
folder:cp zoo_sample.cfg zoo.cfg
- Edit
zoo.cfg
to set a valid data directory:dataDir=/path/to/Zookeeper/data
- Create that directory:
mkdir -p /path/to/Zookeeper/data
- In the
-
Start the Zookeeper server.
- macOS/Linux example:
cd ~/Zookeeper/apache-zookeeper-3.8.2-bin bin/zkServer.sh start
- Windows (in Powershell or Command Prompt):
cd C:\Zookeeper\apache-zookeeper-3.8.2-bin .\bin\zkServer.cmd
- macOS/Linux example:
-
Verify Zookeeper is running.
- Check status:
bin/zkServer.sh status
- It should say "standalone mode" and "running" if successful.
- Check status:
-
Test Zookeeper using the CLI.
- Start the ZK shell:
bin/zkCli.sh
- Create a test node:
create /config "Hello Zookeeper"
- Retrieve the node value:
get /config
- Confirm it shows
Hello Zookeeper
.
- Start the ZK shell:
-
Generate a new Spring Boot project for
ZookeeperService
.- Visit https://start.spring.io/.
- Configure:
- Spring Boot Version: 3.4.1
- Group Id:
com.microservices
- Artifact Id:
zookeeper-service
- Name:
ZookeeperService
- Package Name:
com.microservices.zookeeperservice
- Dependencies:
- Spring Web
- Spring Cloud Zookeeper Discovery
- Spring Boot Actuator
- Extract into
ZookeeperService
.
-
Import the project into your IDE.
-
Enable Zookeeper Discovery.
- In
ZookeeperServiceApplication.java
:package com.microservices.zookeeperservice; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.discovery.EnableDiscoveryClient; @SpringBootApplication @EnableDiscoveryClient public class ZookeeperServiceApplication { public static void main(String[] args) { SpringApplication.run(ZookeeperServiceApplication.class, args); } }
- In
-
Configure Zookeeper in
application.properties
.- In
src/main/resources/application.properties
:spring.application.name=zookeeper-service spring.cloud.zookeeper.connect-string=localhost:2181 server.port=8083
- Port 2181 is the default Zookeeper port.
- In
-
Add a REST endpoint.
- In
src/main/java/com/microservices/zookeeperservice/ZookeeperController.java
:package com.microservices.zookeeperservice; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; @RestController public class ZookeeperController { @GetMapping("/zookeeper") public String getMessage() { return "Hello from Zookeeper Service!"; } }
- In
-
Run the
ZookeeperService
.- From the
ZookeeperService
directory:./mvnw spring-boot:run
- If everything works, Zookeeper logs should show registration of zookeeper-service.
- From the
-
Verify service registration.
- Open another terminal:
bin/zkCli.sh
- Run:
ls /services
- You should see
zookeeper-service
.
- Open another terminal:
-
Generate a new Spring Boot project:
ProductService
.- Same approach:
- Artifact Id:
product-service
- Name:
ProductService
- Package Name:
com.microservices.productservice
- Dependencies:
- Spring Web
- Spring Cloud Zookeeper Discovery
- Spring Boot Actuator
- Artifact Id:
- Extract into
ProductService
.
- Same approach:
-
Enable Zookeeper Discovery.
- In
ProductServiceApplication.java
:package com.microservices.productservice; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.discovery.EnableDiscoveryClient; @SpringBootApplication @EnableDiscoveryClient public class ProductServiceApplication { public static void main(String[] args) { SpringApplication.run(ProductServiceApplication.class, args); } }
- In
-
Configure Zookeeper for
ProductService
.- In
src/main/resources/application.properties
:spring.application.name=product-service spring.cloud.zookeeper.connect-string=localhost:2181 server.port=8084
- In
-
Add a REST endpoint for
ProductService
.- In
ProductController.java
:package com.microservices.productservice; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; @RestController public class ProductController { @GetMapping("/products") public String getProducts() { return "List of products from Zookeeper!"; } }
- In
-
Run
ProductService
.- Similar to before:
./mvnw spring-boot:run
- Check logs for any registration errors.
- Similar to before:
-
Verify
ProductService
in Zookeeper.- In the ZK CLI:
ls /services
- Should now list
zookeeper-service
andproduct-service
.
- In the ZK CLI:
-
Update Zookeeper’s KV data.
- In the ZK CLI:
set /config "Updated Configuration Value"
- This changes the node’s data at path
/config
.
- In the ZK CLI:
-
Retrieve the updated configuration in
ZookeeperService
.- Modify
ZookeeperController
:package com.microservices.zookeeperservice; import org.springframework.beans.factory.annotation.Value; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; @RestController public class ZookeeperController { @Value("${config:Default Config}") private String configValue; @GetMapping("/config") public String getConfig() { return configValue; } }
- Modify
-
Test the
/config
endpoint.- Access:
http://localhost:8083/config
- Should display Updated Configuration Value if
/config
node is read as a property.
- Access:
-
Simulate service failures.
- Kill one service. ZK should reflect it in the ephemeral node structure.
-
Add environment-specific configurations.
- E.g.,
/config/dev
vs./config/prod
. Use profiles or direct property binding to read them.
- E.g.,
-
Integrate watchers.
- Zookeeper watchers let you get notified of config changes in real-time.
By completing this lab, you have:
- Installed and ran Zookeeper locally.
- Registered multiple Spring Boot 3.4.1 services using Spring Cloud Zookeeper Discovery.
- Explored the KV store to set and retrieve dynamic configurations, which microservices can consume at runtime.
- Gained an understanding of how Zookeeper can provide service discovery and configuration management, similar to Eureka or Consul, but with additional synchronization primitives.