Audience: first-time users. Zero to a running runtime (Docker or source), first publish, subscribe and receive. 5–10 minutes.
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.
memory backend needs no broker), or a local install of one storage backend for production-like runs:eventmesh-sdk-java on the classpathThe 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 |
|---|---|---|
| Memory (default) | memory | in-process WAL, zero dependency - dev/CI/quick start only |
| 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 \ -p 10105:10105 -p 10106:10106 \ apache/eventmesh:latest
The image defaults to the memory storage backend - zero external dependency, ready for a smoke test as-is. For a real broker add -e EVENTMESH_STORAGE_TYPE=kafka (or rocketmq / rocketmq5) and the backend address keys shown below.
Ports: 10105 = traffic HTTP (/events/*), 10106 = admin HTTP (/admin/*). The WebSocket push port (10107) is opt-in, and the legacy SDK gRPC bridge (10205, for old EventMeshGrpcProducer/EventMeshGrpcConsumer clients) is opt-in since #5411.
git clone https://github.com/apache/eventmesh.git cd eventmesh # the memory backend is the default - no env needed. For a real broker: # export EVENTMESH_STORAGE_TYPE=kafka (or rocketmq | rocketmq5) # export EVENTMESH_KAFKA_NAMESRV=localhost:9092 ./gradlew :eventmesh-runtime:clean :eventmesh-runtime:dist cd eventmesh-runtime/dist && bash bin/start.sh
Storage-specific keys (all overridable via -D system properties) are documented in eventmesh-configuration.md.
curl http://localhost:10106/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:10105/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:10105/events/subscribe \ -H "Content-Type: application/json" \ -d '{"clientId":"order-svc","topic":"orders","mode":"LOAD_BALANCE"}' # 2a. HTTP long-polling (params: clientId, max, timeoutMs) curl "http://localhost:10105/events/poll?clientId=order-svc&max=100&timeoutMs=30000" # → [{"deliveryId":"d-...","event":{...CloudEvent...}}, ...] # 2b. after processing, acknowledge so the offset advances (at-least-once). # One deliveryId per call - take it from the poll response above. curl -X POST http://localhost:10105/events/ack \ -H "Content-Type: application/json" \ -d '{"deliveryId":"d-..."}'
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:10105/events/stream?clientId=order-svc" \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:10107/events/stream?clientId=order-svc"
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:10105") .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.
/admin/*) quick reference: metrics, subscriptions, offsets, clients, client/reject, dlq/replay, dlq/browse, ratelimit, health, connectors, connector-workers on port 10106