Skip to main content

Command-line reference

CommandWhat it does
mq-gateway [serve]Serve MQTT, AMQP or both (the default command)
mq-gateway checkCheck the streams and buckets that a config file names, without serving
mq-gateway generatePrint the streams, buckets and NATS permissions that a config file needs
mq-gateway bindingPrint a bindings entry for MQTT topic filters
mq-gateway playgroundServe with an embedded NATS server that is ready to try
mq-gateway benchDrive a gateway or broker with clients and report throughput and latency
mq-gateway signal ldmPut a running gateway into lame duck mode

mq-gateway --help lists the commands, and --help after a command lists its flags. --version prints the version.

The config file holds the configuration. The serve flags cover the few settings that a deployment sets per process. Each flag takes the name of its key in the file, such as --log.level for log.level. Each also has an environment variable: MQGW_, then the name in upper case with . and - turned to _, such as MQGW_LOG_LEVEL. A flag wins over its variable, the variable over the file, and the file over the default. An empty variable counts as unset. Only serve reads these variables.

Every command prints an error on standard error as mq-gateway: error: <message>. Every command exits with status 2 on a usage error. Examples are an unknown flag, a missing required flag, a value that does not parse, or an extra argument.

serve​

mq-gateway [serve] [--config FILE] [--mqtt] [--amqp] [--id ID] [--nats.url URL] [flags]
FlagVariableDefaultDescription
--configMQGW_CONFIGnoneThe config file
--mqttMQGW_MQTTfrom the fileServe MQTT (--mqtt=false turns it off)
--amqpMQGW_AMQPfrom the fileServe AMQP (--amqp=false turns it off)
--idMQGW_IDrandomGateway id, unique per gateway
--nats.urlMQGW_NATS_URLnats://localhost:4222NATS server URLs, comma-separated, without credentials
--log.levelMQGW_LOG_LEVELinfodebug, info, warn or error
--log.formatMQGW_LOG_FORMATtexttext or json
--license.fileMQGW_LICENSE_FILEnoneFile with the license JWT
--license.tokenMQGW_LICENSE_TOKENnoneThe license JWT

Each flag overrides its key in the config file. --mqtt and --amqp turn a protocol on or off, whatever the file's blocks say. Without --config, every setting is its default, and --mqtt or --amqp must name a protocol. Only a licensed build reads the license flags.

Exit status: 0 after a stop by a signal or an ldm admin request. 1 when the gateway cannot start, or when a shutdown does not finish in time.

Health endpoint​

With monitor.addr set, the gateway answers these GET requests over plain HTTP:

PathAnswerUse it for
/livez200 while the process runsA liveness probe
/readyz200 when ready, 503 with the reason otherwiseA readiness probe or load balancer
/healthzAs /readyz, plus an errors list per accountAn operator or a monitor
/healthz?account=<name>503 when that account has an error, 404 when the gateway does not serve itA monitor per account
{"status":"unavailable","status_code":503,"error":"gateway in lame duck mode"}

/readyz returns 503 during start-up, while the gateway reconnects to NATS, and from the start of lame duck mode or shutdown. One failed account does not make the gateway unready, because the same config fails it on every gateway. /healthz names that account instead. The endpoints have no authentication, so bind monitor.addr to an address that only the load balancer or orchestrator can reach.

Signals​

SignalEffect
SIGUSR2Start lame duck mode, then exit 0 after ldm.duration
SIGTERMStop now and exit 0, except during lame duck mode
SIGINTStop now, also during lame duck mode
Second SIGINT or SIGTERMStop at once without waiting for connections, and exit 1
SIGHUPLog the signal and keep serving, because a config change needs a restart

Windows has no SIGUSR2. There, send $MQGW.admin.<id>.ldm instead. Ctrl+C acts as SIGINT.

check​

mq-gateway check --config FILE [--timeout 5s] [--verbose | --json] [--strict]

check reads the config file and its credentials as serve does. It then connects to NATS and runs the start-up checks in every account the gateway would serve, without serving. It prints nothing when every check passes. Run it where the gateway's secrets are reachable, because it runs any op or nsc command that a credential names.

FlagDefaultDescription
--configrequiredThe config file to check
--timeout5sTime for each account's check, connection included
--verbosefalsePrint every check on standard output, passed or not, then a summary
--jsonfalsePrint one JSON object on standard output and nothing on standard error (not with --verbose)
--strictfalseExit 1 on warnings as well as failures

A check fails in these cases:

  • A stream or bucket does not exist.
  • A stream does not capture its binding's subjects.
  • A stream cannot acknowledge a publish, because it is no-ack or sealed.
  • A replicated stream or bucket has no leader.

A warning names a setting that works but may cause trouble:

  • A bound stream has no max_bytes, max_msgs or max_age limit.
  • A bucket keeps more than one value per key with no TTL and no byte limit.
  • The retained bucket keeps one value per key (history 1).
  • A bound stream allows deletes, purges, per-subject limits or message TTLs, or does not use limits retention. MQTT deliveries from it are then slower.
  • Another stream also captures a bound subject.
  • A bound stream allows 1,000 consumers or fewer. Each MQTT session with a QoS 1 or 2 subscription uses one.
mq-gateway: warning: binding "orders.>" -> stream "ORDERS": stream "ORDERS" has no MaxBytes, MaxMsgs or MaxAge limit, so it can grow without bound
mq-gateway: error: 4 checked, 1 failed, 1 warnings

Exit status: 0 when every check passes, 1 when a check fails, an account cannot be checked, or (with --strict) a check warns.

generate​

mq-gateway generate --config FILE [--format FORMAT]

generate prints what the config file's routing needs, in the format of a provisioning tool. Names, subjects and domains come from the file. Each limit, such as replicas or max_bytes, is a placeholder that fails until you fill it in. generate never reads a credential and never connects to NATS.

FlagDefaultDescription
--configrequiredThe config file to read
--formatjsonOne of the formats below
FormatOutput
nats-cliA bash script of nats stream add and nats kv add commands
nackNACK Stream and KeyValue manifests
terraformResources for the JetStream Terraform provider
nats-serverNATS user permissions as nats-server.conf variables, for the gateway's users and client users
jsonStreams, buckets and user permissions as one JSON document

With accounts that have their own tables, the output has a section for each account. Provision streams and buckets uses these formats.

Exit status: 0 when generate writes the output, 1 when it refuses the config file.

binding​

mq-gateway binding --mqtt FILTER [--mqtt FILTER]... --stream NAME [--domain DOMAIN]

binding prints a bindings entry that stores exactly the topics that the MQTT filters match. A # filter also includes its parent level, as in MQTT. List the stream in mqtt.bindings so that MQTT uses the entry.

$ mq-gateway binding --mqtt 'orders/#' --stream ORDERS
- {subjects: [orders, orders.>], stream: ORDERS}
FlagDefaultDescription
--mqttrequiredAn MQTT topic filter (repeat the flag for more)
--streamrequiredThe stream that stores the topics
--domainnoneThe JetStream domain of the stream, when it differs from the connection's own

binding refuses a $share filter, and a filter that starts with a wildcard, such as # or +/alarms.

Exit status: 0 when binding prints the entry, 1 when it refuses it.

playground​

mq-gateway playground [--config FILE] [--ui.addr HOST:PORT] [flags]

playground starts the gateway with an embedded NATS server. The server has one account, DEMO, with JetStream. The gateway connects as user mqgw. A client that sends no credentials connects as user demo. The playground creates the streams and buckets that the routing names. Without a routing table, it stores demo.>, orders.> and plant1.*.*.temp and plant1.*.*.alarms. NATS, MQTT and AMQP listen on 127.0.0.1 at their usual ports. It also serves a web page to publish and subscribe from. It is not for production.

FlagDefaultDescription
--confignoneA config file over the playground's defaults
--ui.addr127.0.0.1:8080Address of the web page (empty for none)
--nats.store-dirtemporaryJetStream directory to keep across runs
--idrandomGateway id
--log.levelinfodebug, info, warn or error
--log.formattexttext or json

Each flag overrides its key in the config file. The playground refuses config keys that reach another server, user, account or domain: nats.url, the nats credential keys, nats.tls, nats.config, accounts, a domain, tls, and fixed listeners.

Exit status: as for serve.

bench​

mq-gateway bench MODE [flags] [topic]

bench drives a gateway or another broker with a fleet of MQTT, AMQP or NATS clients. It prints throughput and latency, then one result key=value ... line for scripts. Each mode has its own flags. mq-gateway bench MODE -h lists them.

The modes are pub, sub, natssub, request, churn, idle, retained, resume, js, failover, amqp-pub, amqp-sub, amqp-request, amqp-reply, amqp-churn and amqp-idle.

mq-gateway bench sub -s localhost:1883 -clients 2 -msgs 200000 -latency bench/x &
mq-gateway bench pub -s localhost:1883 -clients 4 -msgs 100000 -latency bench/x

Exit status: 0 when the run finishes, 1 when a client fails or fewer messages arrive than expected.

signal ldm​

mq-gateway signal ldm [--pid PID]

signal ldm sends SIGUSR2 to a running gateway, which starts lame duck mode. Use it in a Kubernetes preStop hook, because the container image has no kill command. It returns once it sends the signal, and does not wait for the gateway to stop. See Deploy for high availability.

FlagDefaultDescription
--pid1Process ID of the gateway (1 is the gateway in its own container)

Exit status: 0 when the command sends the signal, 1 when it cannot, as on Windows.