This guide takes you from zero to a running EventMesh Runtime with a working publisher and
subscriber, using the recommended HTTP + CloudEvents path. Configuration reference:
eventmesh-configuration.md. SDK details:
eventmesh-client-guide.md.
Capability maturity levels (GA / Beta / Experimental / Legacy) are defined in the capability status table in the main README.
- JDK 21+ (Temurin recommended)
- Docker (for the container path), or a local install of one storage backend:
- Apache RocketMQ 4.x or 5.x, or
- Apache Kafka 2.8+ (3.x recommended)
- (SDK only) Java 11+ application with
eventmesh-sdk-javaon the classpath
The EventMesh Runtime is stateless — it owns subscriptions, offsets and delivery, and uses the MQ purely as a write-ahead log (WAL). Pick one backend per deployment; the client side never changes.
| Backend | Type value | Notes |
|---|---|---|
| RocketMQ 4.x | rocketmq |
classic PULL over remoting |
| RocketMQ 5.x | rocketmq5 |
5.x POP + Lite Topic support |
| Kafka | kafka |
assign+seek+poll (no consumer groups), SASL/SSL supported |
sudo docker pull apache/eventmesh:latest
sudo docker run -d --name eventmesh \
-e EVENTMESH_STORAGE_TYPE=kafka \
-e EVENTMESH_KAFKA_NAMESRV=YOUR_KAFKA:9092 \
-p 8080:8080 -p 8081:8081 \
apache/eventmesh:latestPorts: 8080 = traffic HTTP (/events/*), 8081 = admin HTTP (/admin/*). The WebSocket
push port (8082) and the connector runtime admin port (8083) are opt-in.
git clone https://github.com/apache/eventmesh.git
cd eventmesh
# pick your backend via EVENTMESH_STORAGE_TYPE (rocketmq | rocketmq5 | kafka)
export EVENTMESH_STORAGE_TYPE=kafka
export EVENTMESH_KAFKA_NAMESRV=localhost:9092
./gradlew :eventmesh-runtime:clean :eventmesh-runtime:dist
cd eventmesh-runtime/dist && bash bin/start.shStorage-specific keys (all overridable via -D system properties) are documented in
eventmesh-configuration.md.
curl http://localhost:8081/admin/health
# {"status":"UP"}Applications send standard CloudEvents 1.0 over HTTP. 202 Accepted
means the event is durably in the WAL:
curl -X POST "http://localhost:8080/events/publish?topic=orders" \
-H "Content-Type: application/cloudevents+json" \
-d '{
"specversion": "1.0",
"id": "89010a5a-3c6f-4a1e-9b2d-0f7c1f2e3a4b",
"source": "/example/producer",
"type": "com.example.order.created",
"datacontenttype": "application/json",
"data": {"orderId": 42, "amount": 99.5}
}'Register a subscription (there are no consumer groups — EventMesh tracks offsets itself), then receive via one of three transports:
# 1. register: clientId + topic + distribution mode
curl -X POST http://localhost:8080/events/subscribe \
-H "Content-Type: application/json" \
-d '{"clientId":"order-svc","topic":"orders","mode":"LOAD_BALANCE"}'
# 2a. HTTP long-polling
curl "http://localhost:8080/events/poll?clientId=order-svc&topics=orders&timeout=30000"
# 2b. after processing, acknowledge so the offset advances (at-least-once)
curl -X POST http://localhost:8080/events/ack \
-H "Content-Type: application/json" \
-d '{"clientId":"order-svc","deliveryIds":["..."]}'Distribution modes:
| Mode | Semantics |
|---|---|
LOAD_BALANCE |
one subscriber among the group receives each event (partition-key sticky variant available) |
BROADCAST |
every subscriber receives every event |
MULTICAST |
subscriber-side predicate filters events per client |
SSE and WebSocket push are also available; the raw HTTP forms are:
# SSE — server push over a long-lived HTTP connection
curl -N "http://localhost:8080/events/stream?clientId=order-svc&topics=orders" \r
-H "Accept: text/event-stream"
# WebSocket — full-duplex server push over the dedicated WS port
# (raw curl works for a one-shot smoke test; real use goes through the SDK)
curl --include --no-buffer \r
-H "Connection: Upgrade" -H "Upgrade: websocket" \r
-H "Sec-WebSocket-Version: 13" -H "Sec-WebSocket-Key: dGVzdA==" \r
"http://localhost:8082/events/stream?clientId=order-svc&topics=orders"The CloudEventsClient Java SDK wraps all three transports —
subscribe (long-poll) / subscribeSse / subscribeWs — see the
client guide for the trade-offs.
CloudEventsClient client = CloudEventsClient.builder()
.baseUrl("http://localhost:8080")
.build();
client.init();
// publish
client.publish("orders", CloudEventBuilder.v1()
.withId(UUID.randomUUID().toString())
.withSource(URI.create("/order-svc"))
.withType("com.example.order.created")
.withData("application/json", "{\"orderId\":42}".getBytes(UTF_8))
.build());
// subscribe — handler return implies auto-ACK
client.subscribe("orders", "LOAD_BALANCE", event -> {
System.out.println("got " + event.getType());
});Full API (request/reply, streaming sessions, lite topics, SSE/WS): see the client guide.
- Configuration reference — every runtime key, per-backend settings
- Client guide — complete SDK walkthrough
- Production readiness — verified capabilities, SLOs, runbooks
- A2A gateway — agent-to-agent messaging (Experimental)
- Admin API (
/admin/*) quick reference:metrics,subscriptions,offsets,clients,client/reject,dlq/replay,dlq/browse,ratelimit,health,connectors,connector-workerson port 8081