NATS Streaming to JetStream Migration in Operations
This example demonstrates how to perform a migration of NATS Streaming channels and subscriptions to NATS JetStream streams and consumers using the stan2js migration tool. This is a one time exercise and stan2js only needs to be run once for each set of STAN channels that require migration to JetStream streams.
Code
#!/bin/bash
set -euo pipefail
Save connection contexts
The NATS CLI can be used to save and manage contexts which declare the server(s) to connect to as well as authentication and TLS options. For this example, we will create two contexts for the NATS and STAN servers. However, if channels and/or subscriptions need to be migrated to different accounts, then multiple contexts can be used.
echo 'Saving contexts...'
nats context save stan \
--server $STAN_URL
nats context save nats \
--server $NATS_URL
Generate STAN data
To showcase the migration, three channels and subscriptions will be
used. The first channel, foo, has a max_msgs limit of 400 and
one subscription. The second channel, bar, has a max_msgs
limit of 500 and two subscriptions, one of which is a queue.
The third channel, baz, has no limits and no subscriptions.
1000 messages are published to all channels.
echo 'Generating STAN data...'
generate-stan-data \
--context stan \
--cluster $STAN_CLUSTER \
--client app
Define the migration config
Define a config file required by stan2js to declare
which channels and subscriptions are to be migrated, as well
as some associated stream and consumer options. These options
are not exhaustive since many options on streams and consumers
can be changed after the migration. Refer to the stan2js
README for the full set of options.
echo 'Creating config file...'
cat <<-EOF > config.yaml
stan: stan
nats: nats
cluster: test-cluster
client: stan2js
channels:
foo:
stream:
name: FOO
replicas: 1
bar:
stream:
name: BAR
max_consumers: 10
max_bytes: 1GB
baz:
stream:
name: BAZ
max_age: 1h
clients:
app:
context: stan
subscriptions:
sub-foo:
channel: foo
consumer:
name: foo
pull: true
sub-bar-q:
channel: bar
queue: q
consumer:
name: bar-queue
queue: bar-queue
sub-bar:
channel: bar
consumer:
name: bar-consumer
EOF
Run the migration!
echo 'Running migration...'
stan2js config.yaml
Verify the migration
Since the NATS CLI supports introspecting JetStream assets, we can use it to verify that the migration was successful. Also we can inspect the streams to confirm the headers and data look correct.
echo 'Report the streams...'
nats --context nats stream report
echo 'View 3 messages from FOO...'
nats --context nats stream view FOO 3
echo 'View 3 messages from BAR...'
nats --context nats stream view BAR 3
echo 'View 3 messages from BAZ...'
nats --context nats stream view BAZ 3
echo 'Report the consumers...'
nats --context nats consumer report FOO
nats --context nats consumer report BAR
nats --context nats consumer report BAZ
Output
Saving contexts...
NATS Configuration Context "stan"
Server URLs: nats://stan:4222
Path: /root/.config/nats/context/stan.json
WARNING: Shell environment overrides in place using NATS_URL
NATS Configuration Context "nats"
Server URLs: nats://nats:4222
Path: /root/.config/nats/context/nats.json
WARNING: Shell environment overrides in place using NATS_URL
Generating STAN data...
Creating config file...
Running migration...
╭─────────────────────────────────────────────╮
│ Channels -> Streams │
├────────────┬────────────────┬───────────────┤
│ NAME │ FIRST SEQUENCE │ LAST SEQUENCE │
├────────────┼────────────────┼───────────────┤
│ bar -> BAR │ 301 -> 1 │ 1000 -> 700 │
│ baz -> BAZ │ 1 -> 1 │ 1000 -> 1000 │
│ foo -> FOO │ 501 -> 1 │ 1000 -> 500 │
╰────────────┴────────────────┴───────────────╯
╭────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ Subscriptions -> Consumers │
├────────┬───────────────────┬─────────────────────────┬────────────┬────────────────────┬───────────────┤
│ CLIENT │ CHANNEL -> STREAM │ NAME │ QUEUE NAME │ CONVERTED TO PULL? │ NEXT SEQUENCE │
├────────┼───────────────────┼─────────────────────────┼────────────┼────────────────────┼───────────────┤
│ app │ bar -> BAR │ sub-bar -> bar-consumer │ │ false │ 701 -> 401 │
│ app │ bar -> BAR │ sub-bar-q -> bar-queue │ bar-queue │ false │ 351 -> 51 │
│ app │ foo -> FOO │ sub-foo -> foo │ │ true │ 601 -> 101 │
╰────────┴───────────────────┴─────────────────────────┴────────────┴────────────────────┴───────────────╯
Report the streams...
Obtaining Stream stats
╭───────────────────────────────────────────────────────────────────────────────────────────╮
│ Stream Report │
├────────┬─────────┬───────────┬───────────┬──────────┬─────────┬──────┬─────────┬──────────┤
│ Stream │ Storage │ Placement │ Consumers │ Messages │ Bytes │ Lost │ Deleted │ Replicas │
├────────┼─────────┼───────────┼───────────┼──────────┼─────────┼──────┼─────────┼──────────┤
│ FOO │ File │ │ 1 │ 500 │ 85 KiB │ 0 │ 0 │ │
│ BAR │ File │ │ 2 │ 700 │ 119 KiB │ 0 │ 0 │ │
│ BAZ │ File │ │ 0 │ 1,000 │ 170 KiB │ 0 │ 0 │ │
╰────────┴─────────┴───────────┴───────────┴──────────┴─────────┴──────┴─────────┴──────────╯
View 3 messages from FOO...
[1] Subject: foo Received: 2023-10-24T10:50:07Z
Nats-Streaming-Channel: foo
Nats-Streaming-Sequence: 501
Nats-Streaming-Timestamp: 2023-10-24T10:50:06.980419925Z
foo: 500
[2] Subject: foo Received: 2023-10-24T10:50:07Z
Nats-Streaming-Channel: foo
Nats-Streaming-Sequence: 502
Nats-Streaming-Timestamp: 2023-10-24T10:50:06.980773425Z
foo: 501
[3] Subject: foo Received: 2023-10-24T10:50:07Z
Nats-Streaming-Channel: foo
Nats-Streaming-Sequence: 503
Nats-Streaming-Timestamp: 2023-10-24T10:50:06.981072175Z
foo: 502
View 3 messages from BAR...
[1] Subject: bar Received: 2023-10-24T10:50:07Z
Nats-Streaming-Sequence: 301
Nats-Streaming-Timestamp: 2023-10-24T10:50:06.886964217Z
Nats-Streaming-Channel: bar
bar: 300
[2] Subject: bar Received: 2023-10-24T10:50:07Z
Nats-Streaming-Timestamp: 2023-10-24T10:50:06.887295217Z
Nats-Streaming-Channel: bar
Nats-Streaming-Sequence: 302
bar: 301
[3] Subject: bar Received: 2023-10-24T10:50:07Z
Nats-Streaming-Channel: bar
Nats-Streaming-Sequence: 303
Nats-Streaming-Timestamp: 2023-10-24T10:50:06.887588425Z
bar: 302
View 3 messages from BAZ...
[1] Subject: baz Received: 2023-10-24T10:50:07Z
Nats-Streaming-Channel: baz
Nats-Streaming-Sequence: 1
Nats-Streaming-Timestamp: 2023-10-24T10:50:06.692320384Z
baz: 0
[2] Subject: baz Received: 2023-10-24T10:50:07Z
Nats-Streaming-Sequence: 2
Nats-Streaming-Timestamp: 2023-10-24T10:50:06.693268425Z
Nats-Streaming-Channel: baz
baz: 1
[3] Subject: baz Received: 2023-10-24T10:50:07Z
Nats-Streaming-Channel: baz
Nats-Streaming-Sequence: 3
Nats-Streaming-Timestamp: 2023-10-24T10:50:06.694051675Z
baz: 2
Report the consumers...
╭─────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ Consumer report for FOO with 1 consumers │
├──────────┬──────┬────────────┬──────────┬─────────────┬─────────────┬─────────────┬───────────┬─────────┤
│ Consumer │ Mode │ Ack Policy │ Ack Wait │ Ack Pending │ Redelivered │ Unprocessed │ Ack Floor │ Cluster │
├──────────┼──────┼────────────┼──────────┼─────────────┼─────────────┼─────────────┼───────────┼─────────┤
│ foo │ Pull │ Explicit │ 30.00s │ 0 │ 0 │ 400 / 80% │ 0 │ │
╰──────────┴──────┴────────────┴──────────┴─────────────┴─────────────┴─────────────┴───────────┴─────────╯
╭─────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ Consumer report for BAR with 2 consumers │
├──────────────┬──────┬────────────┬──────────┬─────────────┬─────────────┬─────────────┬───────────┬─────────┤
│ Consumer │ Mode │ Ack Policy │ Ack Wait │ Ack Pending │ Redelivered │ Unprocessed │ Ack Floor │ Cluster │
├──────────────┼──────┼────────────┼──────────┼─────────────┼─────────────┼─────────────┼───────────┼─────────┤
│ bar-consumer │ Push │ Explicit │ 30.00s │ 0 │ 0 │ 300 / 42% │ 0 │ │
│ bar-queue │ Push │ Explicit │ 30.00s │ 0 │ 0 │ 650 / 92% │ 0 │ │
╰──────────────┴──────┴────────────┴──────────┴─────────────┴─────────────┴─────────────┴───────────┴─────────╯
╭─────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ Consumer report for BAZ with 0 consumers │
├──────────┬──────┬────────────┬──────────┬─────────────┬─────────────┬─────────────┬───────────┬─────────┤
│ Consumer │ Mode │ Ack Policy │ Ack Wait │ Ack Pending │ Redelivered │ Unprocessed │ Ack Floor │ Cluster │
├──────────┼──────┼────────────┼──────────┼─────────────┼─────────────┼─────────────┼───────────┼─────────┤
╰──────────┴──────┴────────────┴──────────┴─────────────┴─────────────┴─────────────┴───────────┴─────────╯