sentinel-kafka-manager 1.0.2 → 1.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +446 -467
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -27,6 +27,36 @@ In most services, Kafka setup gets repeated:
|
|
|
27
27
|
|
|
28
28
|
`sentinel-kafka-manager` wraps those common tasks in one small class: `KafkaManager`.
|
|
29
29
|
|
|
30
|
+
## Enterprise Features
|
|
31
|
+
|
|
32
|
+
This version now includes a stronger production baseline:
|
|
33
|
+
|
|
34
|
+
- config validation for client id, brokers, and broker discovery inputs
|
|
35
|
+
- shared producer, admin, and consumer lifecycle
|
|
36
|
+
- logger and metrics hooks
|
|
37
|
+
- standard message envelope publishing
|
|
38
|
+
- managed consumer runner with dead-letter topic support
|
|
39
|
+
- health snapshot reporting
|
|
40
|
+
- safer startup behavior for concurrent connections
|
|
41
|
+
- stable error codes and structured exception details
|
|
42
|
+
|
|
43
|
+
## Recommended Usage Level
|
|
44
|
+
|
|
45
|
+
This package is now suitable as a shared internal Kafka module for SaaS microservices.
|
|
46
|
+
|
|
47
|
+
Recommended use:
|
|
48
|
+
|
|
49
|
+
- internal platform package for Node.js services
|
|
50
|
+
- event publishing with standard envelopes
|
|
51
|
+
- managed consumers with DLQ handling
|
|
52
|
+
- consistent service-layer success and error responses
|
|
53
|
+
|
|
54
|
+
Still recommended outside the package:
|
|
55
|
+
|
|
56
|
+
- automated unit and integration tests in the consuming service or platform repo
|
|
57
|
+
- schema validation for business payloads when required by your organization
|
|
58
|
+
- organization-specific tracing, alerting, and compliance rules
|
|
59
|
+
|
|
30
60
|
## Installation
|
|
31
61
|
|
|
32
62
|
Install from npm:
|
|
@@ -48,321 +78,63 @@ npm run build
|
|
|
48
78
|
- Kafka cluster reachable from the service
|
|
49
79
|
- `kafkajs` is included automatically as a dependency of this package
|
|
50
80
|
|
|
51
|
-
##
|
|
52
|
-
|
|
53
|
-
This repository already includes a full local Kafka server setup in [docker-compose.yml](/var/www/html/matrix-project/sentinel-kafka-manager/docker-compose.yml) and sample environment values in [.env.local.example](/var/www/html/matrix-project/sentinel-kafka-manager/.env.local.example).
|
|
54
|
-
|
|
55
|
-
The stack includes:
|
|
56
|
-
|
|
57
|
-
- 3 KRaft controllers
|
|
58
|
-
- 3 Kafka brokers
|
|
59
|
-
- 1 Kafka UI instance
|
|
60
|
-
|
|
61
|
-
### 1. Create your `.env`
|
|
62
|
-
|
|
63
|
-
Copy the example file:
|
|
64
|
-
|
|
65
|
-
```bash
|
|
66
|
-
cp .env.local.example .env
|
|
67
|
-
```
|
|
68
|
-
|
|
69
|
-
If you want a standard localhost setup, the example values are already suitable.
|
|
70
|
-
|
|
71
|
-
### 2. Start the Kafka cluster
|
|
72
|
-
|
|
73
|
-
```bash
|
|
74
|
-
docker compose --env-file .env up -d
|
|
75
|
-
```
|
|
76
|
-
|
|
77
|
-
This creates:
|
|
78
|
-
|
|
79
|
-
- controller quorum on port `9093` inside Docker
|
|
80
|
-
- internal broker traffic on port `9092` inside Docker
|
|
81
|
-
- host-accessible broker ports `29092`, `39092`, and `49092`
|
|
82
|
-
- Kafka UI on `127.0.0.1:5001`
|
|
83
|
-
|
|
84
|
-
### 3. Stop the Kafka cluster
|
|
85
|
-
|
|
86
|
-
```bash
|
|
87
|
-
docker compose --env-file .env down
|
|
88
|
-
```
|
|
89
|
-
|
|
90
|
-
To also remove persisted Kafka data volumes:
|
|
91
|
-
|
|
92
|
-
```bash
|
|
93
|
-
docker compose --env-file .env down -v
|
|
94
|
-
```
|
|
95
|
-
|
|
96
|
-
### 4. Check container status
|
|
97
|
-
|
|
98
|
-
```bash
|
|
99
|
-
docker compose --env-file .env ps
|
|
100
|
-
```
|
|
101
|
-
|
|
102
|
-
### 5. Current broker endpoints
|
|
103
|
-
|
|
104
|
-
For applications running on your host machine:
|
|
105
|
-
|
|
106
|
-
```text
|
|
107
|
-
localhost:29092
|
|
108
|
-
localhost:39092
|
|
109
|
-
localhost:49092
|
|
110
|
-
```
|
|
111
|
-
|
|
112
|
-
For applications running inside Docker on the same Compose network:
|
|
113
|
-
|
|
114
|
-
```text
|
|
115
|
-
broker-1:9092
|
|
116
|
-
broker-2:9092
|
|
117
|
-
broker-3:9092
|
|
118
|
-
```
|
|
119
|
-
|
|
120
|
-
Important:
|
|
121
|
-
|
|
122
|
-
- application clients must connect to brokers, not controllers
|
|
123
|
-
- controllers are internal cluster metadata nodes only
|
|
124
|
-
- `mode: 'external'` is for host-based apps
|
|
125
|
-
- `mode: 'internal'` is for Dockerized apps on the same network
|
|
126
|
-
|
|
127
|
-
## Kafka UI Usage
|
|
128
|
-
|
|
129
|
-
The Docker stack also starts Kafka UI for cluster inspection.
|
|
130
|
-
|
|
131
|
-
### Open the UI
|
|
132
|
-
|
|
133
|
-
Visit:
|
|
134
|
-
|
|
135
|
-
```text
|
|
136
|
-
http://127.0.0.1:5001
|
|
137
|
-
```
|
|
138
|
-
|
|
139
|
-
### Login credentials
|
|
140
|
-
|
|
141
|
-
By default, the UI uses the credentials from `.env`:
|
|
142
|
-
|
|
143
|
-
```env
|
|
144
|
-
KAFKA_UI_USERNAME=admin
|
|
145
|
-
KAFKA_UI_PASSWORD=Admin@007
|
|
146
|
-
```
|
|
147
|
-
|
|
148
|
-
### What the UI connects to
|
|
149
|
-
|
|
150
|
-
Kafka UI is preconfigured in `docker-compose.yml` to use all three brokers:
|
|
151
|
-
|
|
152
|
-
```text
|
|
153
|
-
broker-1:9092,broker-2:9092,broker-3:9092
|
|
154
|
-
```
|
|
155
|
-
|
|
156
|
-
The cluster name shown in the UI comes from:
|
|
157
|
-
|
|
158
|
-
```env
|
|
159
|
-
KAFKA_UI_CLUSTER_NAME=Project Omni Enterprise Kafka
|
|
160
|
-
```
|
|
161
|
-
|
|
162
|
-
### What you can do in the UI
|
|
163
|
-
|
|
164
|
-
- view brokers and cluster health
|
|
165
|
-
- inspect topics and partitions
|
|
166
|
-
- browse messages
|
|
167
|
-
- inspect consumer groups
|
|
168
|
-
- check offsets and lag
|
|
169
|
-
|
|
170
|
-
### Read-only mode
|
|
171
|
-
|
|
172
|
-
The example `.env` sets:
|
|
173
|
-
|
|
174
|
-
```env
|
|
175
|
-
KAFKA_UI_READONLY=true
|
|
176
|
-
```
|
|
177
|
-
|
|
178
|
-
That means the UI is intended for safe inspection only.
|
|
179
|
-
|
|
180
|
-
If you want to create topics or make changes from the UI, change it to:
|
|
181
|
-
|
|
182
|
-
```env
|
|
183
|
-
KAFKA_UI_READONLY=false
|
|
184
|
-
```
|
|
185
|
-
|
|
186
|
-
Then restart the stack:
|
|
187
|
-
|
|
188
|
-
```bash
|
|
189
|
-
docker compose --env-file .env up -d
|
|
190
|
-
```
|
|
191
|
-
|
|
192
|
-
### Typical UI flow
|
|
193
|
-
|
|
194
|
-
1. Start the Docker stack.
|
|
195
|
-
2. Open `http://127.0.0.1:5001`.
|
|
196
|
-
3. Log in with `KAFKA_UI_USERNAME` and `KAFKA_UI_PASSWORD`.
|
|
197
|
-
4. Open the configured cluster.
|
|
198
|
-
5. Go to Topics, Consumer Groups, or Brokers as needed.
|
|
199
|
-
|
|
200
|
-
## Docker Compose And `.env` Reference
|
|
201
|
-
|
|
202
|
-
This project does not use a separate `Dockerfile` for Kafka. The Kafka server is created from `docker-compose.yml` and environment values from `.env`.
|
|
203
|
-
|
|
204
|
-
### Core Kafka image and cluster identity
|
|
205
|
-
|
|
206
|
-
```env
|
|
207
|
-
KAFKA_IMAGE=confluentinc/cp-kafka:7.6.6
|
|
208
|
-
KAFKA_CLUSTER_ID=MkU3OEVBNTcwNTJENDM2Qk
|
|
209
|
-
KAFKA_RESTART_POLICY=unless-stopped
|
|
210
|
-
KAFKA_STOP_GRACE_PERIOD=60s
|
|
211
|
-
KAFKA_NETWORK_NAME=kafka-network
|
|
212
|
-
```
|
|
213
|
-
|
|
214
|
-
- `KAFKA_IMAGE`: Kafka container image used by controllers and brokers
|
|
215
|
-
- `KAFKA_CLUSTER_ID`: shared KRaft cluster id for all nodes
|
|
216
|
-
- `KAFKA_NETWORK_NAME`: Docker network name used by the full stack
|
|
217
|
-
|
|
218
|
-
### Controller quorum settings
|
|
219
|
-
|
|
220
|
-
```env
|
|
221
|
-
KAFKA_CONTROLLER_PORT=9093
|
|
222
|
-
KAFKA_CONTROLLER_LISTENER_NAMES=CONTROLLER
|
|
223
|
-
KAFKA_CONTROLLER_QUORUM_VOTERS=1@controller-1:9093,2@controller-2:9093,3@controller-3:9093
|
|
224
|
-
```
|
|
225
|
-
|
|
226
|
-
- controllers run only inside Docker
|
|
227
|
-
- apps should never use these controller addresses as Kafka client brokers
|
|
228
|
-
|
|
229
|
-
### Broker listener settings
|
|
230
|
-
|
|
231
|
-
```env
|
|
232
|
-
KAFKA_BROKER_BIND_ADDRESS=0.0.0.0
|
|
233
|
-
KAFKA_EXTERNAL_HOST=localhost
|
|
234
|
-
KAFKA_BROKER_INTERNAL_PORT=9092
|
|
235
|
-
KAFKA_BROKER_EXTERNAL_CONTAINER_PORT=19092
|
|
236
|
-
KAFKA_BROKER_1_EXTERNAL_PORT=29092
|
|
237
|
-
KAFKA_BROKER_2_EXTERNAL_PORT=39092
|
|
238
|
-
KAFKA_BROKER_3_EXTERNAL_PORT=49092
|
|
239
|
-
KAFKA_INTER_BROKER_LISTENER_NAME=INTERNAL
|
|
240
|
-
KAFKA_LISTENER_SECURITY_PROTOCOL_MAP=CONTROLLER:PLAINTEXT,INTERNAL:PLAINTEXT,EXTERNAL:PLAINTEXT
|
|
241
|
-
```
|
|
242
|
-
|
|
243
|
-
- `KAFKA_EXTERNAL_HOST=localhost` exposes brokers to your host machine
|
|
244
|
-
- `KAFKA_BROKER_1_EXTERNAL_PORT`, `KAFKA_BROKER_2_EXTERNAL_PORT`, and `KAFKA_BROKER_3_EXTERNAL_PORT` are the ports your local apps should use
|
|
245
|
-
- `KAFKA_BROKER_INTERNAL_PORT=9092` is used by containers on the Docker network
|
|
246
|
-
|
|
247
|
-
### Replication and durability defaults
|
|
248
|
-
|
|
249
|
-
```env
|
|
250
|
-
KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR=3
|
|
251
|
-
KAFKA_TRANSACTION_STATE_LOG_REPLICATION_FACTOR=3
|
|
252
|
-
KAFKA_TRANSACTION_STATE_LOG_MIN_ISR=2
|
|
253
|
-
KAFKA_DEFAULT_REPLICATION_FACTOR=3
|
|
254
|
-
KAFKA_MIN_INSYNC_REPLICAS=2
|
|
255
|
-
KAFKA_NUM_PARTITIONS=6
|
|
256
|
-
```
|
|
257
|
-
|
|
258
|
-
These values are designed for the included three-broker cluster.
|
|
259
|
-
|
|
260
|
-
### Broker behavior
|
|
261
|
-
|
|
262
|
-
```env
|
|
263
|
-
KAFKA_AUTO_CREATE_TOPICS_ENABLE=false
|
|
264
|
-
KAFKA_DELETE_TOPIC_ENABLE=true
|
|
265
|
-
KAFKA_LOG_RETENTION_HOURS=168
|
|
266
|
-
KAFKA_LOG_SEGMENT_BYTES=1073741824
|
|
267
|
-
KAFKA_MESSAGE_MAX_BYTES=10485880
|
|
268
|
-
KAFKA_REPLICA_FETCH_MAX_BYTES=10485880
|
|
269
|
-
KAFKA_SOCKET_REQUEST_MAX_BYTES=104857600
|
|
270
|
-
```
|
|
271
|
-
|
|
272
|
-
- topics are not auto-created by default
|
|
273
|
-
- deleting topics is allowed
|
|
274
|
-
- retention is 7 days by default
|
|
275
|
-
|
|
276
|
-
### Storage and safety limits
|
|
277
|
-
|
|
278
|
-
```env
|
|
279
|
-
KAFKA_LOG_DIRS=/var/lib/kafka/data
|
|
280
|
-
KAFKA_ULIMIT_NOFILE_SOFT=65536
|
|
281
|
-
KAFKA_ULIMIT_NOFILE_HARD=65536
|
|
282
|
-
KAFKA_LOG_MAX_SIZE=100m
|
|
283
|
-
KAFKA_LOG_MAX_FILE=5
|
|
284
|
-
```
|
|
285
|
-
|
|
286
|
-
### Kafka UI settings
|
|
287
|
-
|
|
288
|
-
```env
|
|
289
|
-
KAFKA_UI_IMAGE=provectuslabs/kafka-ui:latest
|
|
290
|
-
KAFKA_UI_CONTAINER_NAME=kafka-ui
|
|
291
|
-
KAFKA_UI_HOSTNAME=kafka-ui
|
|
292
|
-
KAFKA_UI_RESTART_POLICY=unless-stopped
|
|
293
|
-
KAFKA_UI_BIND_ADDRESS=127.0.0.1
|
|
294
|
-
KAFKA_UI_PORT=5001
|
|
295
|
-
KAFKA_UI_DYNAMIC_CONFIG_ENABLED=false
|
|
296
|
-
KAFKA_UI_CLUSTER_NAME=Project Omni Enterprise Kafka
|
|
297
|
-
KAFKA_UI_READONLY=true
|
|
298
|
-
KAFKA_UI_AUTH_TYPE=LOGIN_FORM
|
|
299
|
-
KAFKA_UI_USERNAME=admin
|
|
300
|
-
KAFKA_UI_PASSWORD=Admin@007
|
|
301
|
-
```
|
|
302
|
-
|
|
303
|
-
- `KAFKA_UI_BIND_ADDRESS=127.0.0.1` keeps the UI local-only
|
|
304
|
-
- `KAFKA_UI_PORT=5001` publishes the UI on your machine
|
|
305
|
-
- `KAFKA_UI_READONLY=true` prevents write actions from the UI
|
|
306
|
-
|
|
307
|
-
### Healthcheck settings
|
|
308
|
-
|
|
309
|
-
```env
|
|
310
|
-
KAFKA_HEALTHCHECK_INTERVAL=10s
|
|
311
|
-
KAFKA_HEALTHCHECK_TIMEOUT=5s
|
|
312
|
-
KAFKA_HEALTHCHECK_RETRIES=15
|
|
313
|
-
KAFKA_HEALTHCHECK_START_PERIOD=30s
|
|
314
|
-
```
|
|
315
|
-
|
|
316
|
-
## Creating Topics
|
|
317
|
-
|
|
318
|
-
Because `KAFKA_AUTO_CREATE_TOPICS_ENABLE=false`, topics should be created deliberately.
|
|
319
|
-
|
|
320
|
-
You have two good options:
|
|
321
|
-
|
|
322
|
-
- create topics from your service with `kafkaManager.provisionTopics()`
|
|
323
|
-
- allow UI-based creation by setting `KAFKA_UI_READONLY=false`
|
|
324
|
-
|
|
325
|
-
Example with this package:
|
|
81
|
+
## Full Service Example
|
|
326
82
|
|
|
327
83
|
```ts
|
|
328
|
-
|
|
329
|
-
{
|
|
330
|
-
topic: 'claims.created',
|
|
331
|
-
numPartitions: 6,
|
|
332
|
-
replicationFactor: 3,
|
|
333
|
-
},
|
|
334
|
-
])
|
|
335
|
-
```
|
|
336
|
-
|
|
337
|
-
## Enterprise Features
|
|
338
|
-
|
|
339
|
-
This version now includes a stronger production baseline:
|
|
84
|
+
import { KafkaManager } from 'sentinel-kafka-manager'
|
|
340
85
|
|
|
341
|
-
|
|
342
|
-
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
- managed consumer runner with dead-letter topic support
|
|
346
|
-
- health snapshot reporting
|
|
347
|
-
- safer startup behavior for concurrent connections
|
|
348
|
-
- stable error codes and structured exception details
|
|
86
|
+
const kafkaManager = KafkaManager.fromEnv({
|
|
87
|
+
clientId: 'claims-api',
|
|
88
|
+
mode: 'external',
|
|
89
|
+
})
|
|
349
90
|
|
|
350
|
-
|
|
91
|
+
async function bootstrap(): Promise<void> {
|
|
92
|
+
await kafkaManager.provisionTopics([
|
|
93
|
+
{
|
|
94
|
+
topic: 'claims.created',
|
|
95
|
+
numPartitions: 6,
|
|
96
|
+
replicationFactor: 3,
|
|
97
|
+
},
|
|
98
|
+
])
|
|
351
99
|
|
|
352
|
-
|
|
100
|
+
await kafkaManager.publish({
|
|
101
|
+
topic: 'claims.created',
|
|
102
|
+
key: 'claim-1001',
|
|
103
|
+
payload: {
|
|
104
|
+
claimId: 'claim-1001',
|
|
105
|
+
source: 'claims-api',
|
|
106
|
+
},
|
|
107
|
+
})
|
|
353
108
|
|
|
354
|
-
|
|
109
|
+
await kafkaManager.runConsumer({
|
|
110
|
+
groupId: 'claims-api-group',
|
|
111
|
+
topic: 'claims.created',
|
|
112
|
+
dlqTopic: 'claims.created.dlq',
|
|
113
|
+
onMessage: async ({ message, headers }) => {
|
|
114
|
+
console.log('Received event:', {
|
|
115
|
+
traceId: headers['x-trace-id'],
|
|
116
|
+
payload: message,
|
|
117
|
+
})
|
|
118
|
+
},
|
|
119
|
+
})
|
|
120
|
+
}
|
|
355
121
|
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
122
|
+
bootstrap().catch(async (error) => {
|
|
123
|
+
console.error('Kafka bootstrap failed:', error)
|
|
124
|
+
await kafkaManager.disconnect()
|
|
125
|
+
process.exit(1)
|
|
126
|
+
})
|
|
360
127
|
|
|
361
|
-
|
|
128
|
+
process.on('SIGINT', async () => {
|
|
129
|
+
await kafkaManager.disconnect()
|
|
130
|
+
process.exit(0)
|
|
131
|
+
})
|
|
362
132
|
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
133
|
+
process.on('SIGTERM', async () => {
|
|
134
|
+
await kafkaManager.disconnect()
|
|
135
|
+
process.exit(0)
|
|
136
|
+
})
|
|
137
|
+
```
|
|
366
138
|
|
|
367
139
|
## Basic Usage
|
|
368
140
|
|
|
@@ -702,190 +474,420 @@ console.log(health)
|
|
|
702
474
|
|
|
703
475
|
## Environment Setup
|
|
704
476
|
|
|
705
|
-
This package supports two environment styles:
|
|
477
|
+
This package supports two environment styles:
|
|
478
|
+
|
|
479
|
+
1. one explicit broker list with `KAFKA_BROKERS`
|
|
480
|
+
2. derived brokers from your existing Kafka runtime variables
|
|
481
|
+
|
|
482
|
+
### Option 1: Use `KAFKA_BROKERS`
|
|
483
|
+
|
|
484
|
+
This is the simplest option.
|
|
485
|
+
|
|
486
|
+
### `.env`
|
|
487
|
+
|
|
488
|
+
```env
|
|
489
|
+
KAFKA_BROKERS=localhost:29092,localhost:39092,localhost:49092
|
|
490
|
+
```
|
|
491
|
+
|
|
492
|
+
### Code
|
|
493
|
+
|
|
494
|
+
```ts
|
|
495
|
+
const kafkaManager = KafkaManager.fromEnv({
|
|
496
|
+
clientId: 'claims-service',
|
|
497
|
+
})
|
|
498
|
+
```
|
|
499
|
+
|
|
500
|
+
### Option 2: Use your current Kafka cluster variables
|
|
501
|
+
|
|
502
|
+
This matches the Kafka server setup you shared.
|
|
503
|
+
|
|
504
|
+
### For host machine apps
|
|
505
|
+
|
|
506
|
+
Use this when your Node.js service runs on the host machine.
|
|
507
|
+
|
|
508
|
+
### `.env`
|
|
509
|
+
|
|
510
|
+
```env
|
|
511
|
+
KAFKA_EXTERNAL_HOST=localhost
|
|
512
|
+
KAFKA_BROKER_1_EXTERNAL_PORT=29092
|
|
513
|
+
KAFKA_BROKER_2_EXTERNAL_PORT=39092
|
|
514
|
+
KAFKA_BROKER_3_EXTERNAL_PORT=49092
|
|
515
|
+
KAFKA_BROKER_INTERNAL_PORT=9092
|
|
516
|
+
```
|
|
517
|
+
|
|
518
|
+
### Code
|
|
519
|
+
|
|
520
|
+
```ts
|
|
521
|
+
const kafkaManager = KafkaManager.fromEnv({
|
|
522
|
+
clientId: 'claims-service',
|
|
523
|
+
mode: 'external',
|
|
524
|
+
})
|
|
525
|
+
```
|
|
526
|
+
|
|
527
|
+
This resolves to:
|
|
528
|
+
|
|
529
|
+
```text
|
|
530
|
+
localhost:29092
|
|
531
|
+
localhost:39092
|
|
532
|
+
localhost:49092
|
|
533
|
+
```
|
|
534
|
+
|
|
535
|
+
### For Dockerized apps on the Kafka network
|
|
536
|
+
|
|
537
|
+
Use this when your Node.js service runs inside Docker on the same Kafka network.
|
|
538
|
+
|
|
539
|
+
### `.env`
|
|
540
|
+
|
|
541
|
+
```env
|
|
542
|
+
KAFKA_BROKER_INTERNAL_PORT=9092
|
|
543
|
+
```
|
|
544
|
+
|
|
545
|
+
### Code
|
|
546
|
+
|
|
547
|
+
```ts
|
|
548
|
+
const kafkaManager = KafkaManager.fromEnv({
|
|
549
|
+
clientId: 'claims-service',
|
|
550
|
+
mode: 'internal',
|
|
551
|
+
})
|
|
552
|
+
```
|
|
553
|
+
|
|
554
|
+
This resolves to:
|
|
555
|
+
|
|
556
|
+
```text
|
|
557
|
+
broker-1:9092
|
|
558
|
+
broker-2:9092
|
|
559
|
+
broker-3:9092
|
|
560
|
+
```
|
|
561
|
+
|
|
562
|
+
### Which Mode Should You Use?
|
|
563
|
+
|
|
564
|
+
- Use `mode: 'external'` when your service uses `localhost` broker ports like `29092`, `39092`, and `49092`
|
|
565
|
+
- Use `mode: 'internal'` when your service is inside Docker and should reach brokers like `broker-1:9092`
|
|
566
|
+
- Use `KAFKA_BROKERS` when you want the simplest and most explicit configuration
|
|
567
|
+
|
|
568
|
+
### Your Current Running Kafka Cluster
|
|
569
|
+
|
|
570
|
+
Based on your running Docker containers, your Kafka cluster is exposed like this:
|
|
571
|
+
|
|
572
|
+
- `broker-1` -> host port `29092`
|
|
573
|
+
- `broker-2` -> host port `39092`
|
|
574
|
+
- `broker-3` -> host port `49092`
|
|
575
|
+
- `controller-1`, `controller-2`, and `controller-3` are controller-only nodes and should not be used by application clients
|
|
576
|
+
|
|
577
|
+
If your Node.js service runs on the host machine, use:
|
|
578
|
+
|
|
579
|
+
```env
|
|
580
|
+
KAFKA_EXTERNAL_HOST=localhost
|
|
581
|
+
KAFKA_BROKER_1_EXTERNAL_PORT=29092
|
|
582
|
+
KAFKA_BROKER_2_EXTERNAL_PORT=39092
|
|
583
|
+
KAFKA_BROKER_3_EXTERNAL_PORT=49092
|
|
584
|
+
KAFKA_BROKER_INTERNAL_PORT=9092
|
|
585
|
+
```
|
|
586
|
+
|
|
587
|
+
```ts
|
|
588
|
+
const kafkaManager = KafkaManager.fromEnv({
|
|
589
|
+
clientId: 'claims-service',
|
|
590
|
+
mode: 'external',
|
|
591
|
+
})
|
|
592
|
+
```
|
|
593
|
+
|
|
594
|
+
If your Node.js service runs inside Docker on the same Kafka network, use:
|
|
595
|
+
|
|
596
|
+
```ts
|
|
597
|
+
const kafkaManager = KafkaManager.fromEnv({
|
|
598
|
+
clientId: 'claims-service',
|
|
599
|
+
mode: 'internal',
|
|
600
|
+
})
|
|
601
|
+
```
|
|
602
|
+
|
|
603
|
+
This package is designed to work with that exact broker layout.
|
|
604
|
+
|
|
605
|
+
## Local Infrastructure And Operations
|
|
606
|
+
|
|
607
|
+
### Create A Kafka Server With This Repo
|
|
608
|
+
|
|
609
|
+
This repository already includes a full local Kafka server setup in [docker-compose.yml](/var/www/html/matrix-project/sentinel-kafka-manager/docker-compose.yml) and sample environment values in [.env.local.example](/var/www/html/matrix-project/sentinel-kafka-manager/.env.local.example).
|
|
610
|
+
|
|
611
|
+
The stack includes:
|
|
612
|
+
|
|
613
|
+
- 3 KRaft controllers
|
|
614
|
+
- 3 Kafka brokers
|
|
615
|
+
- 1 Kafka UI instance
|
|
616
|
+
|
|
617
|
+
### 1. Create your `.env`
|
|
618
|
+
|
|
619
|
+
Copy the example file:
|
|
620
|
+
|
|
621
|
+
```bash
|
|
622
|
+
cp .env.local.example .env
|
|
623
|
+
```
|
|
624
|
+
|
|
625
|
+
If you want a standard localhost setup, the example values are already suitable.
|
|
626
|
+
|
|
627
|
+
### 2. Start the Kafka cluster
|
|
628
|
+
|
|
629
|
+
```bash
|
|
630
|
+
docker compose --env-file .env up -d
|
|
631
|
+
```
|
|
632
|
+
|
|
633
|
+
This creates:
|
|
634
|
+
|
|
635
|
+
- controller quorum on port `9093` inside Docker
|
|
636
|
+
- internal broker traffic on port `9092` inside Docker
|
|
637
|
+
- host-accessible broker ports `29092`, `39092`, and `49092`
|
|
638
|
+
- Kafka UI on `127.0.0.1:5001`
|
|
639
|
+
|
|
640
|
+
### 3. Stop the Kafka cluster
|
|
641
|
+
|
|
642
|
+
```bash
|
|
643
|
+
docker compose --env-file .env down
|
|
644
|
+
```
|
|
645
|
+
|
|
646
|
+
To also remove persisted Kafka data volumes:
|
|
647
|
+
|
|
648
|
+
```bash
|
|
649
|
+
docker compose --env-file .env down -v
|
|
650
|
+
```
|
|
651
|
+
|
|
652
|
+
### 4. Check container status
|
|
653
|
+
|
|
654
|
+
```bash
|
|
655
|
+
docker compose --env-file .env ps
|
|
656
|
+
```
|
|
657
|
+
|
|
658
|
+
### 5. Current broker endpoints
|
|
659
|
+
|
|
660
|
+
For applications running on your host machine:
|
|
661
|
+
|
|
662
|
+
```text
|
|
663
|
+
localhost:29092
|
|
664
|
+
localhost:39092
|
|
665
|
+
localhost:49092
|
|
666
|
+
```
|
|
667
|
+
|
|
668
|
+
For applications running inside Docker on the same Compose network:
|
|
669
|
+
|
|
670
|
+
```text
|
|
671
|
+
broker-1:9092
|
|
672
|
+
broker-2:9092
|
|
673
|
+
broker-3:9092
|
|
674
|
+
```
|
|
675
|
+
|
|
676
|
+
Important:
|
|
677
|
+
|
|
678
|
+
- application clients must connect to brokers, not controllers
|
|
679
|
+
- controllers are internal cluster metadata nodes only
|
|
680
|
+
- `mode: 'external'` is for host-based apps
|
|
681
|
+
- `mode: 'internal'` is for Dockerized apps on the same network
|
|
682
|
+
|
|
683
|
+
### Kafka UI Usage
|
|
684
|
+
|
|
685
|
+
The Docker stack also starts Kafka UI for cluster inspection.
|
|
686
|
+
|
|
687
|
+
### Open the UI
|
|
688
|
+
|
|
689
|
+
Visit:
|
|
690
|
+
|
|
691
|
+
```text
|
|
692
|
+
http://127.0.0.1:5001
|
|
693
|
+
```
|
|
694
|
+
|
|
695
|
+
### Login credentials
|
|
696
|
+
|
|
697
|
+
By default, the UI uses the credentials from `.env`:
|
|
698
|
+
|
|
699
|
+
```env
|
|
700
|
+
KAFKA_UI_USERNAME=admin
|
|
701
|
+
KAFKA_UI_PASSWORD=Admin@007
|
|
702
|
+
```
|
|
703
|
+
|
|
704
|
+
### What the UI connects to
|
|
705
|
+
|
|
706
|
+
Kafka UI is preconfigured in `docker-compose.yml` to use all three brokers:
|
|
707
|
+
|
|
708
|
+
```text
|
|
709
|
+
broker-1:9092,broker-2:9092,broker-3:9092
|
|
710
|
+
```
|
|
711
|
+
|
|
712
|
+
The cluster name shown in the UI comes from:
|
|
713
|
+
|
|
714
|
+
```env
|
|
715
|
+
KAFKA_UI_CLUSTER_NAME=Project Omni Enterprise Kafka
|
|
716
|
+
```
|
|
717
|
+
|
|
718
|
+
### What you can do in the UI
|
|
719
|
+
|
|
720
|
+
- view brokers and cluster health
|
|
721
|
+
- inspect topics and partitions
|
|
722
|
+
- browse messages
|
|
723
|
+
- inspect consumer groups
|
|
724
|
+
- check offsets and lag
|
|
725
|
+
|
|
726
|
+
### Read-only mode
|
|
706
727
|
|
|
707
|
-
|
|
708
|
-
2. derived brokers from your existing Kafka runtime variables
|
|
728
|
+
The example `.env` sets:
|
|
709
729
|
|
|
710
|
-
|
|
730
|
+
```env
|
|
731
|
+
KAFKA_UI_READONLY=true
|
|
732
|
+
```
|
|
711
733
|
|
|
712
|
-
|
|
734
|
+
That means the UI is intended for safe inspection only.
|
|
713
735
|
|
|
714
|
-
|
|
736
|
+
If you want to create topics or make changes from the UI, change it to:
|
|
715
737
|
|
|
716
738
|
```env
|
|
717
|
-
|
|
739
|
+
KAFKA_UI_READONLY=false
|
|
718
740
|
```
|
|
719
741
|
|
|
720
|
-
|
|
742
|
+
Then restart the stack:
|
|
721
743
|
|
|
722
|
-
```
|
|
723
|
-
|
|
724
|
-
clientId: 'claims-service',
|
|
725
|
-
})
|
|
744
|
+
```bash
|
|
745
|
+
docker compose --env-file .env up -d
|
|
726
746
|
```
|
|
727
747
|
|
|
728
|
-
|
|
748
|
+
### Typical UI flow
|
|
729
749
|
|
|
730
|
-
|
|
750
|
+
1. Start the Docker stack.
|
|
751
|
+
2. Open `http://127.0.0.1:5001`.
|
|
752
|
+
3. Log in with `KAFKA_UI_USERNAME` and `KAFKA_UI_PASSWORD`.
|
|
753
|
+
4. Open the configured cluster.
|
|
754
|
+
5. Go to Topics, Consumer Groups, or Brokers as needed.
|
|
731
755
|
|
|
732
|
-
###
|
|
756
|
+
### Docker Compose And `.env` Reference
|
|
733
757
|
|
|
734
|
-
|
|
758
|
+
This project does not use a separate `Dockerfile` for Kafka. The Kafka server is created from `docker-compose.yml` and environment values from `.env`.
|
|
735
759
|
|
|
736
|
-
###
|
|
760
|
+
### Core Kafka image and cluster identity
|
|
737
761
|
|
|
738
762
|
```env
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
763
|
+
KAFKA_IMAGE=confluentinc/cp-kafka:7.6.6
|
|
764
|
+
KAFKA_CLUSTER_ID=MkU3OEVBNTcwNTJENDM2Qk
|
|
765
|
+
KAFKA_RESTART_POLICY=unless-stopped
|
|
766
|
+
KAFKA_STOP_GRACE_PERIOD=60s
|
|
767
|
+
KAFKA_NETWORK_NAME=kafka-network
|
|
744
768
|
```
|
|
745
769
|
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
const kafkaManager = KafkaManager.fromEnv({
|
|
750
|
-
clientId: 'claims-service',
|
|
751
|
-
mode: 'external',
|
|
752
|
-
})
|
|
753
|
-
```
|
|
770
|
+
- `KAFKA_IMAGE`: Kafka container image used by controllers and brokers
|
|
771
|
+
- `KAFKA_CLUSTER_ID`: shared KRaft cluster id for all nodes
|
|
772
|
+
- `KAFKA_NETWORK_NAME`: Docker network name used by the full stack
|
|
754
773
|
|
|
755
|
-
|
|
774
|
+
### Controller quorum settings
|
|
756
775
|
|
|
757
|
-
```
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
776
|
+
```env
|
|
777
|
+
KAFKA_CONTROLLER_PORT=9093
|
|
778
|
+
KAFKA_CONTROLLER_LISTENER_NAMES=CONTROLLER
|
|
779
|
+
KAFKA_CONTROLLER_QUORUM_VOTERS=1@controller-1:9093,2@controller-2:9093,3@controller-3:9093
|
|
761
780
|
```
|
|
762
781
|
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
Use this when your Node.js service runs inside Docker on the same Kafka network.
|
|
782
|
+
- controllers run only inside Docker
|
|
783
|
+
- apps should never use these controller addresses as Kafka client brokers
|
|
766
784
|
|
|
767
|
-
###
|
|
785
|
+
### Broker listener settings
|
|
768
786
|
|
|
769
787
|
```env
|
|
788
|
+
KAFKA_BROKER_BIND_ADDRESS=0.0.0.0
|
|
789
|
+
KAFKA_EXTERNAL_HOST=localhost
|
|
770
790
|
KAFKA_BROKER_INTERNAL_PORT=9092
|
|
791
|
+
KAFKA_BROKER_EXTERNAL_CONTAINER_PORT=19092
|
|
792
|
+
KAFKA_BROKER_1_EXTERNAL_PORT=29092
|
|
793
|
+
KAFKA_BROKER_2_EXTERNAL_PORT=39092
|
|
794
|
+
KAFKA_BROKER_3_EXTERNAL_PORT=49092
|
|
795
|
+
KAFKA_INTER_BROKER_LISTENER_NAME=INTERNAL
|
|
796
|
+
KAFKA_LISTENER_SECURITY_PROTOCOL_MAP=CONTROLLER:PLAINTEXT,INTERNAL:PLAINTEXT,EXTERNAL:PLAINTEXT
|
|
771
797
|
```
|
|
772
798
|
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
const kafkaManager = KafkaManager.fromEnv({
|
|
777
|
-
clientId: 'claims-service',
|
|
778
|
-
mode: 'internal',
|
|
779
|
-
})
|
|
780
|
-
```
|
|
799
|
+
- `KAFKA_EXTERNAL_HOST=localhost` exposes brokers to your host machine
|
|
800
|
+
- `KAFKA_BROKER_1_EXTERNAL_PORT`, `KAFKA_BROKER_2_EXTERNAL_PORT`, and `KAFKA_BROKER_3_EXTERNAL_PORT` are the ports your local apps should use
|
|
801
|
+
- `KAFKA_BROKER_INTERNAL_PORT=9092` is used by containers on the Docker network
|
|
781
802
|
|
|
782
|
-
|
|
803
|
+
### Replication and durability defaults
|
|
783
804
|
|
|
784
|
-
```
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
805
|
+
```env
|
|
806
|
+
KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR=3
|
|
807
|
+
KAFKA_TRANSACTION_STATE_LOG_REPLICATION_FACTOR=3
|
|
808
|
+
KAFKA_TRANSACTION_STATE_LOG_MIN_ISR=2
|
|
809
|
+
KAFKA_DEFAULT_REPLICATION_FACTOR=3
|
|
810
|
+
KAFKA_MIN_INSYNC_REPLICAS=2
|
|
811
|
+
KAFKA_NUM_PARTITIONS=6
|
|
788
812
|
```
|
|
789
813
|
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
- Use `mode: 'external'` when your service uses `localhost` broker ports like `29092`, `39092`, and `49092`
|
|
793
|
-
- Use `mode: 'internal'` when your service is inside Docker and should reach brokers like `broker-1:9092`
|
|
794
|
-
- Use `KAFKA_BROKERS` when you want the simplest and most explicit configuration
|
|
814
|
+
These values are designed for the included three-broker cluster.
|
|
795
815
|
|
|
796
|
-
|
|
816
|
+
### Broker behavior
|
|
797
817
|
|
|
798
|
-
|
|
818
|
+
```env
|
|
819
|
+
KAFKA_AUTO_CREATE_TOPICS_ENABLE=false
|
|
820
|
+
KAFKA_DELETE_TOPIC_ENABLE=true
|
|
821
|
+
KAFKA_LOG_RETENTION_HOURS=168
|
|
822
|
+
KAFKA_LOG_SEGMENT_BYTES=1073741824
|
|
823
|
+
KAFKA_MESSAGE_MAX_BYTES=10485880
|
|
824
|
+
KAFKA_REPLICA_FETCH_MAX_BYTES=10485880
|
|
825
|
+
KAFKA_SOCKET_REQUEST_MAX_BYTES=104857600
|
|
826
|
+
```
|
|
799
827
|
|
|
800
|
-
-
|
|
801
|
-
-
|
|
802
|
-
-
|
|
803
|
-
- `controller-1`, `controller-2`, and `controller-3` are controller-only nodes and should not be used by application clients
|
|
828
|
+
- topics are not auto-created by default
|
|
829
|
+
- deleting topics is allowed
|
|
830
|
+
- retention is 7 days by default
|
|
804
831
|
|
|
805
|
-
|
|
832
|
+
### Storage and safety limits
|
|
806
833
|
|
|
807
834
|
```env
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
```
|
|
814
|
-
|
|
815
|
-
```ts
|
|
816
|
-
const kafkaManager = KafkaManager.fromEnv({
|
|
817
|
-
clientId: 'claims-service',
|
|
818
|
-
mode: 'external',
|
|
819
|
-
})
|
|
835
|
+
KAFKA_LOG_DIRS=/var/lib/kafka/data
|
|
836
|
+
KAFKA_ULIMIT_NOFILE_SOFT=65536
|
|
837
|
+
KAFKA_ULIMIT_NOFILE_HARD=65536
|
|
838
|
+
KAFKA_LOG_MAX_SIZE=100m
|
|
839
|
+
KAFKA_LOG_MAX_FILE=5
|
|
820
840
|
```
|
|
821
841
|
|
|
822
|
-
|
|
842
|
+
### Kafka UI settings
|
|
823
843
|
|
|
824
|
-
```
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
844
|
+
```env
|
|
845
|
+
KAFKA_UI_IMAGE=provectuslabs/kafka-ui:latest
|
|
846
|
+
KAFKA_UI_CONTAINER_NAME=kafka-ui
|
|
847
|
+
KAFKA_UI_HOSTNAME=kafka-ui
|
|
848
|
+
KAFKA_UI_RESTART_POLICY=unless-stopped
|
|
849
|
+
KAFKA_UI_BIND_ADDRESS=127.0.0.1
|
|
850
|
+
KAFKA_UI_PORT=5001
|
|
851
|
+
KAFKA_UI_DYNAMIC_CONFIG_ENABLED=false
|
|
852
|
+
KAFKA_UI_CLUSTER_NAME=Project Omni Enterprise Kafka
|
|
853
|
+
KAFKA_UI_READONLY=true
|
|
854
|
+
KAFKA_UI_AUTH_TYPE=LOGIN_FORM
|
|
855
|
+
KAFKA_UI_USERNAME=admin
|
|
856
|
+
KAFKA_UI_PASSWORD=Admin@007
|
|
829
857
|
```
|
|
830
858
|
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
859
|
+
- `KAFKA_UI_BIND_ADDRESS=127.0.0.1` keeps the UI local-only
|
|
860
|
+
- `KAFKA_UI_PORT=5001` publishes the UI on your machine
|
|
861
|
+
- `KAFKA_UI_READONLY=true` prevents write actions from the UI
|
|
834
862
|
|
|
835
|
-
|
|
836
|
-
import { KafkaManager } from 'sentinel-kafka-manager'
|
|
863
|
+
### Healthcheck settings
|
|
837
864
|
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
865
|
+
```env
|
|
866
|
+
KAFKA_HEALTHCHECK_INTERVAL=10s
|
|
867
|
+
KAFKA_HEALTHCHECK_TIMEOUT=5s
|
|
868
|
+
KAFKA_HEALTHCHECK_RETRIES=15
|
|
869
|
+
KAFKA_HEALTHCHECK_START_PERIOD=30s
|
|
870
|
+
```
|
|
842
871
|
|
|
843
|
-
|
|
844
|
-
await kafkaManager.provisionTopics([
|
|
845
|
-
{
|
|
846
|
-
topic: 'claims.created',
|
|
847
|
-
numPartitions: 6,
|
|
848
|
-
replicationFactor: 3,
|
|
849
|
-
},
|
|
850
|
-
])
|
|
872
|
+
### Creating Topics
|
|
851
873
|
|
|
852
|
-
|
|
853
|
-
topic: 'claims.created',
|
|
854
|
-
key: 'claim-1001',
|
|
855
|
-
payload: {
|
|
856
|
-
claimId: 'claim-1001',
|
|
857
|
-
source: 'claims-api',
|
|
858
|
-
},
|
|
859
|
-
})
|
|
874
|
+
Because `KAFKA_AUTO_CREATE_TOPICS_ENABLE=false`, topics should be created deliberately.
|
|
860
875
|
|
|
861
|
-
|
|
862
|
-
groupId: 'claims-api-group',
|
|
863
|
-
topic: 'claims.created',
|
|
864
|
-
dlqTopic: 'claims.created.dlq',
|
|
865
|
-
onMessage: async ({ message, headers }) => {
|
|
866
|
-
console.log('Received event:', {
|
|
867
|
-
traceId: headers['x-trace-id'],
|
|
868
|
-
payload: message,
|
|
869
|
-
})
|
|
870
|
-
},
|
|
871
|
-
})
|
|
872
|
-
}
|
|
876
|
+
You have two good options:
|
|
873
877
|
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
await kafkaManager.disconnect()
|
|
877
|
-
process.exit(1)
|
|
878
|
-
})
|
|
878
|
+
- create topics from your service with `kafkaManager.provisionTopics()`
|
|
879
|
+
- allow UI-based creation by setting `KAFKA_UI_READONLY=false`
|
|
879
880
|
|
|
880
|
-
|
|
881
|
-
await kafkaManager.disconnect()
|
|
882
|
-
process.exit(0)
|
|
883
|
-
})
|
|
881
|
+
Example with this package:
|
|
884
882
|
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
883
|
+
```ts
|
|
884
|
+
await kafkaManager.provisionTopics([
|
|
885
|
+
{
|
|
886
|
+
topic: 'claims.created',
|
|
887
|
+
numPartitions: 6,
|
|
888
|
+
replicationFactor: 3,
|
|
889
|
+
},
|
|
890
|
+
])
|
|
889
891
|
```
|
|
890
892
|
|
|
891
893
|
## API Summary
|
|
@@ -1138,7 +1140,9 @@ const kafkaManager = new KafkaManager({
|
|
|
1138
1140
|
})
|
|
1139
1141
|
```
|
|
1140
1142
|
|
|
1141
|
-
##
|
|
1143
|
+
## Operational Guidance
|
|
1144
|
+
|
|
1145
|
+
### Common Mistakes
|
|
1142
1146
|
|
|
1143
1147
|
- Do not connect application clients to KRaft controller nodes. Connect only to brokers.
|
|
1144
1148
|
- Do not use `mode: 'external'` inside Docker unless you truly want host-published ports.
|
|
@@ -1149,7 +1153,7 @@ const kafkaManager = new KafkaManager({
|
|
|
1149
1153
|
- Do not publish business-critical events without metadata. Prefer `publishEnvelope()` for traceability.
|
|
1150
1154
|
- Do not depend on raw driver error strings in application logic. Use `KafkaManagerError.code`.
|
|
1151
1155
|
|
|
1152
|
-
|
|
1156
|
+
### Recommended SaaS Pattern
|
|
1153
1157
|
|
|
1154
1158
|
For most SaaS services, the cleanest pattern is:
|
|
1155
1159
|
|
|
@@ -1160,38 +1164,13 @@ For most SaaS services, the cleanest pattern is:
|
|
|
1160
1164
|
5. Catch `KafkaManagerError` and branch on `error.code`.
|
|
1161
1165
|
6. Wrap service outcomes in `OperationResponse<T>` where useful.
|
|
1162
1166
|
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
Build:
|
|
1166
|
-
|
|
1167
|
-
```bash
|
|
1168
|
-
npm run build
|
|
1169
|
-
```
|
|
1170
|
-
|
|
1171
|
-
Publish:
|
|
1172
|
-
|
|
1173
|
-
```bash
|
|
1174
|
-
npm publish
|
|
1175
|
-
```
|
|
1176
|
-
|
|
1177
|
-
If npm rejects the publish:
|
|
1178
|
-
|
|
1179
|
-
- `403` usually means authentication, 2FA, or token permission issues
|
|
1180
|
-
- `404` usually means the package name is unavailable or not publishable by your account
|
|
1181
|
-
|
|
1182
|
-
Useful check:
|
|
1183
|
-
|
|
1184
|
-
```bash
|
|
1185
|
-
npm whoami
|
|
1186
|
-
```
|
|
1187
|
-
|
|
1188
|
-
## Notes
|
|
1167
|
+
### Notes
|
|
1189
1168
|
|
|
1190
1169
|
- Your current Kafka cluster works fine with PLAINTEXT, so SSL and SASL are optional unless your environment changes
|
|
1191
1170
|
- This package is designed for both host-based services and Dockerized services
|
|
1192
1171
|
- If you want the least surprise, use `KAFKA_BROKERS`
|
|
1193
1172
|
|
|
1194
|
-
##
|
|
1173
|
+
## Additional Documentation
|
|
1195
1174
|
|
|
1196
1175
|
- npm deployment guide: [NPM_DEPLOYMENT.md](/var/www/html/matrix-project/sentinel-kafka-manager/NPM_DEPLOYMENT.md)
|
|
1197
1176
|
- Example folder: [examples/service-module-usage/README.md](/var/www/html/matrix-project/sentinel-kafka-manager/examples/service-module-usage/README.md)
|