Quick Start Guide to Apache Pulsar with Docker Compose and Easy Spring Pulsar
This article walks through installing a local Apache Pulsar cluster with Docker Compose, using Pulsar Manager for administration, demonstrates native Java producer and consumer code, and introduces the Easy Spring Pulsar annotation library for concise Spring Boot integration.
1. Installing Pulsar with Docker Compose
Use Docker Compose to launch a local Pulsar cluster that includes Zookeeper, BookKeeper, a Pulsar broker, and optionally Pulsar Manager. The required containers are defined in a docker-compose.yml file.
version: '3'
networks:
pulsar:
driver: bridge
services:
zookeeper:
image: apachepulsar/pulsar:3.0.0
container_name: zookeeper
restart: on-failure
networks:
- pulsar
volumes:
- ./data/zookeeper:/pulsar/data/zookeeper
environment:
- metadataStoreUrl=zk:zookeeper:2181
- PULSAR_MEM=-Xms256m -Xmx256m -XX:MaxDirectMemorySize=256m
command: >
bash -c "bin/apply-config-from-env.py conf/zookeeper.conf && \
bin/generate-zookeeper-config.sh conf/zookeeper.conf && \
exec bin/pulsar zookeeper"
healthcheck:
test: ["CMD", "bin/pulsar-zookeeper-ruok.sh"]
interval: 10s
timeout: 5s
retries: 30
pulsar-init:
container_name: pulsar-init
hostname: pulsar-init
image: apachepulsar/pulsar:3.0.0
networks:
- pulsar
command: >
bin/pulsar initialize-cluster-metadata \
--cluster cluster-a \
--zookeeper zookeeper:2181 \
--configuration-store zookeeper:2181 \
--web-service-url http://broker:8080 \
--broker-service-url pulsar://broker:6650
depends_on:
zookeeper:
condition: service_healthy
bookie:
image: apachepulsar/pulsar:3.0.0
container_name: bookie
restart: on-failure
networks:
- pulsar
environment:
- clusterName=cluster-a
- zkServers=zookeeper:2181
- metadataServiceUri=metadata-store:zk:zookeeper:2181
- advertisedAddress=bookie
- BOOKIE_MEM=-Xms512m -Xmx512m -XX:MaxDirectMemorySize=256m
command: bash -c "bin/apply-config-from-env.py conf/bookkeeper.conf && exec bin/pulsar bookie"
depends_on:
zookeeper:
condition: service_healthy
pulsar-init:
condition: service_completed_successfully
volumes:
- ./data/bookkeeper:/pulsar/data/bookkeeper
broker:
image: apachepulsar/pulsar:3.0.0
container_name: broker
hostname: broker
restart: on-failure
networks:
- pulsar
environment:
- metadataStoreUrl=zk:zookeeper:2181
- zookeeperServers=zookeeper:2181
- clusterName=cluster-a
- managedLedgerDefaultEnsembleSize=1
- managedLedgerDefaultWriteQuorum=1
- managedLedgerDefaultAckQuorum=1
- advertisedAddress=broker
- advertisedListeners=external:pulsar://127.0.0.1:6650
- PULSAR_MEM=-Xms512m -Xmx512m -XX:MaxDirectMemorySize=256m
depends_on:
zookeeper:
condition: service_healthy
bookie:
condition: service_started
ports:
- "6650:6650"
- "8080:8080"
command: bash -c "bin/apply-config-from-env.py conf/broker.conf && exec bin/pulsar broker"
manager:
hostname: manager
container_name: manager
image: apachepulsar/pulsar-manager:v0.4.0
ports:
- "9527:9527"
- "7750:7750"
depends_on:
- broker
volumes:
- "./data/:/data:z"
environment:
REDIRECT_HOST: "http://127.0.0.1"
REDIRECT_PORT: "9527"
DRIVER_CLASS_NAME: "org.postgresql.Driver"
URL: "jdbc:postgresql://127.0.0.1:5432/pulsar_manager"
USERNAME: "pulsar"
PASSWORD: "pulsar"
LOG_LEVEL: "DEBUG"
networks:
- pulsarStart the stack with docker-compose up -d, verify the containers using docker ps, then create a Pulsar Manager admin account via curl commands. Access the manager UI at http://127.0.0.1:9527, create a new environment, and associate the Service URL ( pulsar://broker:6650) and Bookie URL with the cluster.
2. Native Java Client Examples
Producer example using the Pulsar Java client:
package com.example.springboot.pulsar;
import lombok.extern.slf4j.Slf4j;
import org.apache.pulsar.client.api.*;
@Slf4j
public class MyProducer {
public static void main(String[] args) {
String serviceUrl = "pulsar://localhost:6650";
PulsarClient pulsarClient = null;
Producer<String> producer = null;
try {
pulsarClient = PulsarClient.builder()
.serviceUrl(serviceUrl)
.build();
producer = pulsarClient.newProducer(Schema.STRING)
.producerName("produce-test")
.topic("my-topic")
.create();
producer.send("hello world!");
log.info("send success");
} catch (PulsarClientException e) {
throw new RuntimeException(e);
} finally {
try {
pulsarClient.close();
producer.close();
} catch (PulsarClientException e) {
throw new RuntimeException(e);
}
}
}
}Consumer example using the Pulsar Java client:
package com.example.springboot.pulsar;
import lombok.extern.slf4j.Slf4j;
import org.apache.pulsar.client.api.*;
@Slf4j
public class MyConsumer {
public static void main(String[] args) {
String serviceUrl = "pulsar://localhost:6650";
PulsarClient pulsarClient = null;
Consumer<String> consumer = null;
try {
pulsarClient = PulsarClient.builder()
.serviceUrl(serviceUrl)
.build();
consumer = pulsarClient.newConsumer(Schema.STRING)
.consumerName("consumer-test")
.topic("my-topic")
.subscriptionName("my-sub")
.subscribe();
Message<String> message = consumer.receive();
String content = message.getValue();
consumer.acknowledge(message);
log.info("content:{}", content);
} catch (PulsarClientException e) {
throw new RuntimeException(e);
} finally {
try {
pulsarClient.close();
consumer.close();
} catch (PulsarClientException e) {
throw new RuntimeException(e);
}
}
}
}3. Annotation‑Based Development with Easy Spring Pulsar
Easy Spring Pulsar is a lightweight Spring Boot component that simplifies Pulsar usage through annotations such as @ConsumerHandler, @ProducerHandler, and @Subscription. Add the Maven dependency and configure the server URL:
com.allen.component:easy-spring-pulsar:${version} pulsar:
server:
url: pulsar://localhost:6650
common:
env: devConsumer implementation using annotations:
@Slf4j
@ConsumerHandler(name = "order-consumer", topic = "order-created")
public class OrderConsumer implements CustomerConsumer {
@Override
@Subscription
public void receive(DomainMessage eventMessage) {
log.info("收到订单创建消息:{}", GsonUtil.toJson(eventMessage));
// process order logic
}
}Producer implementation using annotations:
@Slf4j
@ProducerHandler(name = "order-producer", topic = "order-created")
public class OrderProducer implements CustomerProducer {
public void createOrder(Order order) throws PulsarClientException {
OrderCreatedMessage message = new OrderCreatedMessage();
message.setData(order);
message.setTimestamp(System.currentTimeMillis());
Producer<String> producer = getProducer();
String msg = serialize(message);
log.info("发送订单创建消息:{}", msg);
producer.send(msg);
}
}Compared with the raw API, Easy Spring Pulsar offers concise code, automatic connection handling, clear separation of business and messaging logic, environment‑aware topic isolation, and type‑safe generic message bodies.
Source Code Insights
The component’s core consists of PulsarBeanPostProcessor (detects annotated beans), PulsarInitializer (creates and manages producers/consumers), and the annotation definitions themselves. These classes leverage Spring’s BeanPostProcessor mechanism to register beans at runtime.
Conclusion
Apache Pulsar provides a robust distributed messaging backbone for micro‑service architectures. By combining Docker‑Compose‑based local deployment with the Easy Spring Pulsar annotation library, developers can quickly prototype and then scale production‑grade messaging with minimal boilerplate.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
