From fb0d5c835521ac09a16bc83e918886e6dbe37394 Mon Sep 17 00:00:00 2001 From: Ginger Collison Date: Fri, 4 Oct 2019 17:48:52 +0000 Subject: [PATCH] GitBook: [master] 326 pages and 16 assets modified --- .gitbook/assets/acks.svg | 65 ++++ .gitbook/assets/intro.svg | 58 +++ .gitbook/assets/nats_streaming.svg | 67 ++++ .gitbook/assets/noecho.svg | 68 ++++ .gitbook/assets/pingpong.svg | 39 ++ .gitbook/assets/pubsub.svg | 71 ++++ .gitbook/assets/pubsubtut.svg | 95 +++++ .gitbook/assets/queue.svg | 71 ++++ .gitbook/assets/queues.svg | 71 ++++ .gitbook/assets/reqrepl.svg | 91 +++++ .gitbook/assets/seqno.svg | 59 +++ .gitbook/assets/simple.svg | 76 ++++ .gitbook/assets/subjects1.svg | 58 +++ .gitbook/assets/subjects2.svg | 58 +++ .gitbook/assets/subjects3.svg | 65 ++++ .gitbook/assets/three_gw.svg | 109 ++++++ README.md | 33 +- SUMMARY.md | 340 +++++++++--------- {developer/concepts => concepts}/acks.md | 3 +- {developer/concepts => concepts}/intro.md | 5 +- {developer/concepts => concepts}/pubsub.md | 7 +- {developer/concepts => concepts}/queue.md | 10 +- {developer/concepts => concepts}/reqreply.md | 11 +- {developer/concepts => concepts}/seq_num.md | 9 +- {developer/concepts => concepts}/subjects.md | 13 +- developer/connecting/cluster.md | 20 -- developer/connecting/connect_timeout.md | 5 - developer/connecting/default_server.md | 5 - developer/connecting/specific_server.md | 9 - developer/reconnect/disable.md | 5 - developer/streaming/protocol.md | 265 -------------- developer/tutorials/intro.md | 8 - .../acks.md | 5 +- .../connecting.md | 6 +- .../durables.md | 3 +- developing-with-nats-streaming/protocol.md | 254 +++++++++++++ .../publishing.md | 1 + .../queues.md | 7 +- .../receiving.md | 7 +- .../streaming.md | 93 ++--- .../developer.md | 9 +- .../intro-1/README.md | 3 +- .../intro-1}/buffer.md | 5 +- developing-with-nats/intro-1/disable.md | 6 + .../intro-1}/events.md | 3 +- .../intro-1}/max.md | 3 +- .../intro-1}/random.md | 5 +- .../intro-1}/wait.md | 3 +- .../intro-2/README.md | 1 + .../intro-2}/creds.md | 7 +- .../intro-2}/nkey.md | 3 +- .../intro-2}/tls.md | 10 +- .../intro-2}/token.md | 8 +- .../intro-2}/userpass.md | 9 +- .../intro-3/README.md | 3 +- .../intro-3}/async.md | 3 +- .../intro-3}/drain.md | 21 +- .../intro-3}/queues.md | 5 +- .../intro-3}/reply.md | 3 +- .../intro-3}/structure.md | 5 +- .../intro-3}/sync.md | 4 +- .../intro-3}/unsub_after.md | 5 +- .../intro-3}/unsubscribing.md | 3 +- .../intro-3}/wildcards.md | 9 +- .../intro-4/README.md | 3 +- .../intro-4}/caches.md | 5 +- .../intro-4}/replyto.md | 3 +- .../intro-4}/request_reply.md | 7 +- .../intro-4}/structure.md | 3 +- .../intro-5/README.md | 3 +- .../intro-5}/events.md | 7 +- .../intro-5}/slow.md | 5 +- developing-with-nats/intro-6/README.md | 9 + .../intro-6}/custom_dialer.md | 10 +- .../intro-6}/pubsub.md | 45 +-- .../intro-6}/queues.md | 21 +- .../intro-6}/reqreply.md | 11 +- .../intro/README.md | 3 +- developing-with-nats/intro/cluster.md | 114 ++++++ developing-with-nats/intro/connect_timeout.md | 73 ++++ developing-with-nats/intro/default_server.md | 89 +++++ .../intro}/noecho.md | 5 +- .../intro}/pingpong.md | 7 +- .../intro}/protocol.md | 9 +- developing-with-nats/intro/specific_server.md | 86 +++++ faq.md | 56 +-- .../nats-protocol-demo.md | 42 ++- nats-protocol/nats-protocol/README.md | 319 ++++++++++++++++ .../nats-protocol}/nats-client-dev.md | 57 +-- .../nats-server-protocol.md | 89 +++-- {nats_server => nats-server}/clients.md | 38 +- .../configuration/README.md | 105 +++--- .../configuration/clustering/README.md | 53 +-- .../clustering}/cluster_config.md | 20 +- .../configuration/clustering}/cluster_tls.md | 7 +- .../configuration/gateways}/README.md | 34 +- .../configuration/gateways}/gateway.md | 68 ++-- .../configuration/leafnodes}/README.md | 95 +++-- .../configuration/leafnodes}/leafnode_conf.md | 24 +- .../configuration}/logging.md | 42 ++- .../configuration}/monitoring.md | 208 ++++++----- .../configuration/securing_nats/README.md | 8 + .../securing_nats/auth_intro/README.md | 29 +- .../securing_nats/auth_intro}/accounts.md | 89 +++-- .../securing_nats/auth_intro}/auth_timeout.md | 9 +- .../securing_nats/auth_intro}/jwt_auth.md | 67 ++-- .../securing_nats/auth_intro}/nkey_auth.md | 19 +- .../auth_intro}/tls_mutual_auth.md | 33 +- .../securing_nats/auth_intro}/tokens.md | 28 +- .../auth_intro}/username_password.md | 26 +- .../securing_nats}/authorization.md | 35 +- .../configuration/securing_nats}/tls.md | 29 +- {nats_server => nats-server}/flags.md | 71 ++-- {nats_server => nats-server}/installation.md | 56 ++- nats-server/nats_admin/README.md | 8 + .../nats_admin}/signals.md | 19 +- nats-server/nats_admin/slow_consumers.md | 112 ++++++ .../nats_admin/sys_accounts}/README.md | 18 +- .../nats_admin/sys_accounts}/sys_accounts.md | 83 +++-- .../nats_admin}/upgrading_cluster.md | 36 +- .../nats_docker}/README.md | 64 ++-- .../nats_docker}/docker_swarm.md | 47 +-- .../nats_docker}/nats-docker-tutorial.md | 17 +- .../running/README.md | 16 +- .../running}/windows_srv.md | 11 +- nats-streaming-concepts/channels/README.md | 8 + .../channels/message-log.md | 6 + .../channels/subscriptions/README.md | 3 +- .../channels/subscriptions/durable.md | 5 +- .../channels/subscriptions/queue-group.md | 7 +- .../channels/subscriptions/redelivery.md | 5 +- .../channels/subscriptions/regular.md | 4 + .../client-connections.md | 1 + .../clustering/README.md | 5 +- .../clustering/auto-configuration.md | 3 +- .../clustering/configuration.md | 26 +- .../clustering/containers.md | 7 +- .../clustering/supported-stores.md | 1 + .../ft/README.md | 7 +- .../ft}/active-server.md | 3 +- .../ft}/failover.md | 1 + .../ft}/shared-state.md | 3 +- .../ft}/standby-server.md | 3 +- .../intro.md | 34 +- .../monitoring/README.md | 20 +- .../monitoring/endpoints.md | 63 ++-- .../partitioning.md | 47 +-- .../relation-to-nats.md | 5 +- .../store-encryption.md | 18 +- .../store-interface.md | 7 +- .../changes.md | 96 +++-- nats-streaming-server/configuring/README.md | 10 + nats-streaming-server/configuring/cfgfile.md | 168 +++++++++ .../configuring/cmdline.md | 17 +- .../configuring/persistence/README.md | 3 +- .../persistence/filestore/README.md | 71 ++++ .../persistence/filestore/options.md | 2 + .../persistence/filestore/recovery-errors.md | 2 + .../persistence/sqlstore/README.md | 60 ++-- .../persistence/sqlstore/options.md | 2 + .../sqlstore/read-and-write-timeouts.md | 2 + .../configuring/storelimits/README.md | 55 +-- .../storelimits/limits-inheritance.md | 2 + .../configuring/tls/README.md | 28 +- .../configuring/tls/authenticating-users.md | 2 + nats-streaming-server/configuring/tls/tls.md | 2 + .../embedding.md | 23 +- .../install.md | 30 +- .../process-signaling.md | 17 +- .../run.md | 33 +- .../swarm.md | 28 +- .../windows-service.md | 14 +- {nats_tools => nats-tools}/mkpasswd.md | 19 +- {nats_tools => nats-tools}/nas/README.md | 11 +- {nats_tools => nats-tools}/nas/dir_store.md | 34 +- .../nas/inspecting_jwts.md | 19 +- .../nas/mem_resolver.md | 36 +- {nats_tools => nats-tools}/nas/nas_conf.md | 54 ++- .../nas/notifications.md | 36 +- {nats_tools => nats-tools}/nats_top/README.md | 23 +- .../nats_top/nats-top-tutorial.md | 53 +-- {nats_tools => nats-tools}/natsbench.md | 59 +-- {nats_tools => nats-tools}/nk.md | 15 +- nats-tools/nsc/README.md | 43 +++ {nats_tools => nats-tools}/nsc/managed.md | 7 +- {nats_tools => nats-tools}/nsc/nsc.md | 33 +- {nats_tools => nats-tools}/nsc/revocation.md | 1 + {nats_tools => nats-tools}/nsc/services.md | 26 +- .../nsc/signing_keys.md | 20 +- {nats_tools => nats-tools}/nsc/streams.md | 19 +- nats_admin/README.md | 7 - nats_admin/slow_consumers.md | 111 ------ nats_protocol/nats-protocol.md | 317 ---------------- nats_server/securing_nats.md | 7 - nats_streaming/channels/channels.md | 7 - nats_streaming/channels/message-log.md | 5 - .../channels/subscriptions/regular.md | 3 - nats_streaming/configuring/cfgfile.md | 163 --------- nats_streaming/configuring/configuring.md | 9 - nats_streaming/configuring/filestore.md | 112 ------ nats_tools/nsc/README.md | 43 --- whats_new/whats_new_20.md | 220 ------------ whats_new_20.md | 190 ++++++++++ 203 files changed, 4640 insertions(+), 3107 deletions(-) create mode 100644 .gitbook/assets/acks.svg create mode 100644 .gitbook/assets/intro.svg create mode 100644 .gitbook/assets/nats_streaming.svg create mode 100644 .gitbook/assets/noecho.svg create mode 100644 .gitbook/assets/pingpong.svg create mode 100644 .gitbook/assets/pubsub.svg create mode 100644 .gitbook/assets/pubsubtut.svg create mode 100644 .gitbook/assets/queue.svg create mode 100644 .gitbook/assets/queues.svg create mode 100644 .gitbook/assets/reqrepl.svg create mode 100644 .gitbook/assets/seqno.svg create mode 100644 .gitbook/assets/simple.svg create mode 100644 .gitbook/assets/subjects1.svg create mode 100644 .gitbook/assets/subjects2.svg create mode 100644 .gitbook/assets/subjects3.svg create mode 100644 .gitbook/assets/three_gw.svg rename {developer/concepts => concepts}/acks.md (96%) rename {developer/concepts => concepts}/intro.md (67%) rename {developer/concepts => concepts}/pubsub.md (58%) rename {developer/concepts => concepts}/queue.md (77%) rename {developer/concepts => concepts}/reqreply.md (66%) rename {developer/concepts => concepts}/seq_num.md (57%) rename {developer/concepts => concepts}/subjects.md (75%) delete mode 100644 developer/connecting/cluster.md delete mode 100644 developer/connecting/connect_timeout.md delete mode 100644 developer/connecting/default_server.md delete mode 100644 developer/connecting/specific_server.md delete mode 100644 developer/reconnect/disable.md delete mode 100644 developer/streaming/protocol.md delete mode 100644 developer/tutorials/intro.md rename {developer/streaming => developing-with-nats-streaming}/acks.md (95%) rename {developer/streaming => developing-with-nats-streaming}/connecting.md (91%) rename {developer/streaming => developing-with-nats-streaming}/durables.md (82%) create mode 100644 developing-with-nats-streaming/protocol.md rename {developer/streaming => developing-with-nats-streaming}/publishing.md (99%) rename {developer/streaming => developing-with-nats-streaming}/queues.md (91%) rename {developer/streaming => developing-with-nats-streaming}/receiving.md (90%) rename developer/streaming/README.md => developing-with-nats-streaming/streaming.md (71%) rename developer/README.md => developing-with-nats/developer.md (81%) rename developer/reconnect/intro.md => developing-with-nats/intro-1/README.md (97%) rename {developer/reconnect => developing-with-nats/intro-1}/buffer.md (87%) create mode 100644 developing-with-nats/intro-1/disable.md rename {developer/reconnect => developing-with-nats/intro-1}/events.md (83%) rename {developer/reconnect => developing-with-nats/intro-1}/max.md (90%) rename {developer/reconnect => developing-with-nats/intro-1}/random.md (84%) rename {developer/reconnect => developing-with-nats/intro-1}/wait.md (94%) rename developer/security/intro.md => developing-with-nats/intro-2/README.md (99%) rename {developer/security => developing-with-nats/intro-2}/creds.md (94%) rename {developer/security => developing-with-nats/intro-2}/nkey.md (94%) rename {developer/security => developing-with-nats/intro-2}/tls.md (88%) rename {developer/security => developing-with-nats/intro-2}/token.md (87%) rename {developer/security => developing-with-nats/intro-2}/userpass.md (89%) rename developer/receiving/intro.md => developing-with-nats/intro-3/README.md (99%) rename {developer/receiving => developing-with-nats/intro-3}/async.md (90%) rename {developer/receiving => developing-with-nats/intro-3}/drain.md (80%) rename {developer/receiving => developing-with-nats/intro-3}/queues.md (90%) rename {developer/receiving => developing-with-nats/intro-3}/reply.md (81%) rename {developer/receiving => developing-with-nats/intro-3}/structure.md (84%) rename {developer/receiving => developing-with-nats/intro-3}/sync.md (90%) rename {developer/receiving => developing-with-nats/intro-3}/unsub_after.md (93%) rename {developer/receiving => developing-with-nats/intro-3}/unsubscribing.md (90%) rename {developer/receiving => developing-with-nats/intro-3}/wildcards.md (80%) rename developer/sending/intro.md => developing-with-nats/intro-4/README.md (90%) rename {developer/sending => developing-with-nats/intro-4}/caches.md (94%) rename {developer/sending => developing-with-nats/intro-4}/replyto.md (88%) rename {developer/sending => developing-with-nats/intro-4}/request_reply.md (97%) rename {developer/sending => developing-with-nats/intro-4}/structure.md (91%) rename developer/events/intro.md => developing-with-nats/intro-5/README.md (85%) rename {developer/events => developing-with-nats/intro-5}/events.md (88%) rename {developer/events => developing-with-nats/intro-5}/slow.md (96%) create mode 100644 developing-with-nats/intro-6/README.md rename {developer/tutorials => developing-with-nats/intro-6}/custom_dialer.md (88%) rename {developer/tutorials => developing-with-nats/intro-6}/pubsub.md (84%) rename {developer/tutorials => developing-with-nats/intro-6}/queues.md (88%) rename {developer/tutorials => developing-with-nats/intro-6}/reqreply.md (91%) rename developer/connecting/intro.md => developing-with-nats/intro/README.md (97%) create mode 100644 developing-with-nats/intro/cluster.md create mode 100644 developing-with-nats/intro/connect_timeout.md create mode 100644 developing-with-nats/intro/default_server.md rename {developer/connecting => developing-with-nats/intro}/noecho.md (93%) rename {developer/connecting => developing-with-nats/intro}/pingpong.md (91%) rename {developer/connecting => developing-with-nats/intro}/protocol.md (90%) create mode 100644 developing-with-nats/intro/specific_server.md rename {nats_protocol => nats-protocol}/nats-protocol-demo.md (89%) create mode 100644 nats-protocol/nats-protocol/README.md rename {nats_protocol => nats-protocol/nats-protocol}/nats-client-dev.md (75%) rename {nats_protocol => nats-protocol}/nats-server-protocol.md (58%) rename {nats_server => nats-server}/clients.md (87%) rename nats_server/configuration.md => nats-server/configuration/README.md (58%) rename nats_server/clustering.md => nats-server/configuration/clustering/README.md (89%) rename {nats_server => nats-server/configuration/clustering}/cluster_config.md (53%) rename {nats_server => nats-server/configuration/clustering}/cluster_tls.md (89%) rename {gateways => nats-server/configuration/gateways}/README.md (83%) rename {gateways => nats-server/configuration/gateways}/gateway.md (73%) rename {leafnodes => nats-server/configuration/leafnodes}/README.md (78%) rename {leafnodes => nats-server/configuration/leafnodes}/leafnode_conf.md (75%) rename {nats_server => nats-server/configuration}/logging.md (61%) rename {nats_server => nats-server/configuration}/monitoring.md (62%) create mode 100644 nats-server/configuration/securing_nats/README.md rename nats_server/auth_intro.md => nats-server/configuration/securing_nats/auth_intro/README.md (59%) rename {nats_server => nats-server/configuration/securing_nats/auth_intro}/accounts.md (71%) rename {nats_server => nats-server/configuration/securing_nats/auth_intro}/auth_timeout.md (74%) rename {nats_server => nats-server/configuration/securing_nats/auth_intro}/jwt_auth.md (59%) rename {nats_server => nats-server/configuration/securing_nats/auth_intro}/nkey_auth.md (78%) rename {nats_server => nats-server/configuration/securing_nats/auth_intro}/tls_mutual_auth.md (81%) rename {nats_server => nats-server/configuration/securing_nats/auth_intro}/tokens.md (88%) rename {nats_server => nats-server/configuration/securing_nats/auth_intro}/username_password.md (81%) rename {nats_server => nats-server/configuration/securing_nats}/authorization.md (75%) rename {nats_server => nats-server/configuration/securing_nats}/tls.md (91%) rename {nats_server => nats-server}/flags.md (60%) rename {nats_server => nats-server}/installation.md (77%) create mode 100644 nats-server/nats_admin/README.md rename {nats_admin => nats-server/nats_admin}/signals.md (69%) create mode 100644 nats-server/nats_admin/slow_consumers.md rename {sys_accounts => nats-server/nats_admin/sys_accounts}/README.md (53%) rename {sys_accounts => nats-server/nats_admin/sys_accounts}/sys_accounts.md (78%) rename {nats_admin => nats-server/nats_admin}/upgrading_cluster.md (68%) rename {nats_docker => nats-server/nats_docker}/README.md (84%) rename {nats_docker => nats-server/nats_docker}/docker_swarm.md (82%) rename {nats_docker => nats-server/nats_docker}/nats-docker-tutorial.md (87%) rename nats_server/running.md => nats-server/running/README.md (77%) rename {nats_server => nats-server/running}/windows_srv.md (89%) create mode 100644 nats-streaming-concepts/channels/README.md create mode 100644 nats-streaming-concepts/channels/message-log.md rename nats_streaming/channels/subscriptions/subscriptions.md => nats-streaming-concepts/channels/subscriptions/README.md (95%) rename {nats_streaming => nats-streaming-concepts}/channels/subscriptions/durable.md (84%) rename {nats_streaming => nats-streaming-concepts}/channels/subscriptions/queue-group.md (73%) rename {nats_streaming => nats-streaming-concepts}/channels/subscriptions/redelivery.md (69%) create mode 100644 nats-streaming-concepts/channels/subscriptions/regular.md rename {nats_streaming => nats-streaming-concepts}/client-connections.md (99%) rename nats_streaming/clustering/clustering.md => nats-streaming-concepts/clustering/README.md (77%) rename {nats_streaming => nats-streaming-concepts}/clustering/auto-configuration.md (99%) rename {nats_streaming => nats-streaming-concepts}/clustering/configuration.md (86%) rename {nats_streaming => nats-streaming-concepts}/clustering/containers.md (61%) rename {nats_streaming => nats-streaming-concepts}/clustering/supported-stores.md (99%) rename nats_streaming/fault-tolerance/ft.md => nats-streaming-concepts/ft/README.md (72%) rename {nats_streaming/fault-tolerance => nats-streaming-concepts/ft}/active-server.md (88%) rename {nats_streaming/fault-tolerance => nats-streaming-concepts/ft}/failover.md (99%) rename {nats_streaming/fault-tolerance => nats-streaming-concepts/ft}/shared-state.md (79%) rename {nats_streaming/fault-tolerance => nats-streaming-concepts/ft}/standby-server.md (92%) rename {nats_streaming => nats-streaming-concepts}/intro.md (53%) rename nats_streaming/monitoring/monitoring.md => nats-streaming-concepts/monitoring/README.md (86%) rename {nats_streaming => nats-streaming-concepts}/monitoring/endpoints.md (91%) rename {nats_streaming => nats-streaming-concepts}/partitioning.md (79%) rename {nats_streaming => nats-streaming-concepts}/relation-to-nats.md (85%) rename {nats_streaming => nats-streaming-concepts}/store-encryption.md (82%) rename {nats_streaming => nats-streaming-concepts}/store-interface.md (83%) rename {nats_streaming/gettingstarted => nats-streaming-server}/changes.md (59%) create mode 100644 nats-streaming-server/configuring/README.md create mode 100644 nats-streaming-server/configuring/cfgfile.md rename {nats_streaming => nats-streaming-server}/configuring/cmdline.md (95%) rename nats_streaming/configuring/persistence.md => nats-streaming-server/configuring/persistence/README.md (80%) create mode 100644 nats-streaming-server/configuring/persistence/filestore/README.md create mode 100644 nats-streaming-server/configuring/persistence/filestore/options.md create mode 100644 nats-streaming-server/configuring/persistence/filestore/recovery-errors.md rename nats_streaming/configuring/sqlstore.md => nats-streaming-server/configuring/persistence/sqlstore/README.md (50%) create mode 100644 nats-streaming-server/configuring/persistence/sqlstore/options.md create mode 100644 nats-streaming-server/configuring/persistence/sqlstore/read-and-write-timeouts.md rename nats_streaming/configuring/storelimits.md => nats-streaming-server/configuring/storelimits/README.md (70%) create mode 100644 nats-streaming-server/configuring/storelimits/limits-inheritance.md rename nats_streaming/configuring/tls.md => nats-streaming-server/configuring/tls/README.md (80%) create mode 100644 nats-streaming-server/configuring/tls/authenticating-users.md create mode 100644 nats-streaming-server/configuring/tls/tls.md rename {developer/streaming => nats-streaming-server}/embedding.md (94%) rename {nats_streaming/gettingstarted => nats-streaming-server}/install.md (94%) rename {nats_streaming/gettingstarted => nats-streaming-server}/process-signaling.md (52%) rename {nats_streaming/gettingstarted => nats-streaming-server}/run.md (81%) rename {nats_streaming => nats-streaming-server}/swarm.md (79%) rename {nats_streaming/gettingstarted => nats-streaming-server}/windows-service.md (97%) rename {nats_tools => nats-tools}/mkpasswd.md (83%) rename {nats_tools => nats-tools}/nas/README.md (91%) rename {nats_tools => nats-tools}/nas/dir_store.md (91%) rename {nats_tools => nats-tools}/nas/inspecting_jwts.md (68%) rename {nats_tools => nats-tools}/nas/mem_resolver.md (89%) rename {nats_tools => nats-tools}/nas/nas_conf.md (90%) rename {nats_tools => nats-tools}/nas/notifications.md (85%) rename {nats_tools => nats-tools}/nats_top/README.md (84%) rename {nats_tools => nats-tools}/nats_top/nats-top-tutorial.md (84%) rename {nats_tools => nats-tools}/natsbench.md (85%) rename {nats_tools => nats-tools}/nk.md (70%) create mode 100644 nats-tools/nsc/README.md rename {nats_tools => nats-tools}/nsc/managed.md (92%) rename {nats_tools => nats-tools}/nsc/nsc.md (92%) rename {nats_tools => nats-tools}/nsc/revocation.md (99%) rename {nats_tools => nats-tools}/nsc/services.md (98%) rename {nats_tools => nats-tools}/nsc/signing_keys.md (93%) rename {nats_tools => nats-tools}/nsc/streams.md (98%) delete mode 100644 nats_admin/README.md delete mode 100644 nats_admin/slow_consumers.md delete mode 100644 nats_protocol/nats-protocol.md delete mode 100644 nats_server/securing_nats.md delete mode 100644 nats_streaming/channels/channels.md delete mode 100644 nats_streaming/channels/message-log.md delete mode 100644 nats_streaming/channels/subscriptions/regular.md delete mode 100644 nats_streaming/configuring/cfgfile.md delete mode 100644 nats_streaming/configuring/configuring.md delete mode 100644 nats_streaming/configuring/filestore.md delete mode 100644 nats_tools/nsc/README.md delete mode 100644 whats_new/whats_new_20.md create mode 100644 whats_new_20.md diff --git a/.gitbook/assets/acks.svg b/.gitbook/assets/acks.svg new file mode 100644 index 0000000..4ec4419 --- /dev/null +++ b/.gitbook/assets/acks.svg @@ -0,0 +1,65 @@ + + + + + + +nats_request_reply + + + +publisher + +Publisher + + + +subject + +Subject + + + +publisher->subject + + +msg1 + + + +reply + +Reply + + + + +sub1 + +Subscriber + + + +subject->sub1 + + +msg1 + + + +reply->publisher + + + + + +sub1->reply + + +ack + + + diff --git a/.gitbook/assets/intro.svg b/.gitbook/assets/intro.svg new file mode 100644 index 0000000..19a2ced --- /dev/null +++ b/.gitbook/assets/intro.svg @@ -0,0 +1,58 @@ + + + + + + +nats + + + +publisher + +Application 1 + +NATS Publisher + + + +natsserver + + + + +publisher:nats--natsserver + + + + +application + +Application 3 + + + + + +application:nats--natsserver + + + + +subscriber + +NATS Subscriber + +Application 2 + + + +natsserver--subscriber:nats + + + + + diff --git a/.gitbook/assets/nats_streaming.svg b/.gitbook/assets/nats_streaming.svg new file mode 100644 index 0000000..5cb4913 --- /dev/null +++ b/.gitbook/assets/nats_streaming.svg @@ -0,0 +1,67 @@ + + + + + + +nats_streaming + + +cluster_nats_streaming_server + +NATS Streaming Server + + + +application + +Application Code + +NATS Streaming Client API + +NATS Client API + + + +nats_server + +NATS Server + + + +application:nats->nats_server + + + + + + +streaming_module + +Streaming Module + + + +nats_server->streaming_module + + + + + + +storage + +storage + + + +streaming_module->storage + + + + + + diff --git a/.gitbook/assets/noecho.svg b/.gitbook/assets/noecho.svg new file mode 100644 index 0000000..5a09f42 --- /dev/null +++ b/.gitbook/assets/noecho.svg @@ -0,0 +1,68 @@ + + + + + + +%3 + + +cluster_1 + +Connection #1 + + +cluster_2 + +Connection #2 + + + +publisher + +Publisher + + + +subject + +Subject + + + +publisher->subject + + +msg + + + +subscriber_1 + +Subscriber + + + +subscriber_2 + +Subscriber + + + +subject->subscriber_1 + + +echo'd msg + + + +subject->subscriber_2 + + +msg + + + diff --git a/.gitbook/assets/pingpong.svg b/.gitbook/assets/pingpong.svg new file mode 100644 index 0000000..06ebb70 --- /dev/null +++ b/.gitbook/assets/pingpong.svg @@ -0,0 +1,39 @@ + + + + + + +g + + + +client + +NATS Client + + + +natsserver + +nats-server + + + +client->natsserver + + +PING + + + +natsserver->client + + +PONG + + + diff --git a/.gitbook/assets/pubsub.svg b/.gitbook/assets/pubsub.svg new file mode 100644 index 0000000..22d59af --- /dev/null +++ b/.gitbook/assets/pubsub.svg @@ -0,0 +1,71 @@ + + + + + + +nats_pub_sub + + + +publisher + +Publisher + + + +subject + +Subject + + + +publisher->subject + + +msg1 + + + +sub1 + +Subscriber + + + +subject->sub1 + + +msg1 + + + +sub2 + +Subscriber + + + +subject->sub2 + + +msg1 + + + +sub3 + +Subscriber + + + +subject->sub3 + + +msg1 + + + diff --git a/.gitbook/assets/pubsubtut.svg b/.gitbook/assets/pubsubtut.svg new file mode 100644 index 0000000..a0d442c --- /dev/null +++ b/.gitbook/assets/pubsubtut.svg @@ -0,0 +1,95 @@ + + + + + + +nats_pub_sub + + + +sub1 + +SUB +com.msg.one + + + +pub1 + +PUB +com.msg.one + + + +natsserver + +NATS + + + +pub1->natsserver + + + + + +non_active + +Non-Active +Subscriber + + + +natsserver->sub1 + + + + + +natsserver->non_active + + + + +sub2 + +SUB +com.msg.one + + + +natsserver->sub2 + + + + + +sub3 + +SUB +com.msg.two + + + +natsserver->sub3 + + + + +sub4 + +SUB +com.msg.* + + + +natsserver->sub4 + + + + + diff --git a/.gitbook/assets/queue.svg b/.gitbook/assets/queue.svg new file mode 100644 index 0000000..62652b3 --- /dev/null +++ b/.gitbook/assets/queue.svg @@ -0,0 +1,71 @@ + + + + + + +nats_queues + + + +publisher + +Publisher + + + +subject + +Queue + + + +publisher->subject + + +msgs 1,2,3 + + + +sub1 + +Subscriber + + + +subject->sub1 + + +msg 2 + + + +sub2 + +Subscriber + + + +subject->sub2 + + +msg 1 + + + +sub3 + +Subscriber + + + +subject->sub3 + + +msg 3 + + + diff --git a/.gitbook/assets/queues.svg b/.gitbook/assets/queues.svg new file mode 100644 index 0000000..e4f2a64 --- /dev/null +++ b/.gitbook/assets/queues.svg @@ -0,0 +1,71 @@ + + + + + + +g + + + +publisher + +PUB updates + + + +subject + +nats-server + + + +publisher->subject + + +msgs 1,2,3 + + + +sub1 + +SUB updates workers + + + +subject->sub1 + + +msg 2 + + + +sub2 + +SUB updates workers + + + +subject->sub2 + + +msg 1 + + + +sub3 + +SUB updates workers + + + +subject->sub3 + + +msg 3 + + + diff --git a/.gitbook/assets/reqrepl.svg b/.gitbook/assets/reqrepl.svg new file mode 100644 index 0000000..dc10798 --- /dev/null +++ b/.gitbook/assets/reqrepl.svg @@ -0,0 +1,91 @@ + + + + + + +nats_request_reply + + + +publisher + +Publisher + + + +subject + +Subject + + + +publisher->subject + + +msg1 + + + +reply + +Reply + + + + +sub1 + +Subscriber + + + +subject->sub1 + + +msg1 + + + +sub2 + +Subscriber + + + +subject->sub2 + + +msg1 + + + +sub3 + +Subscriber + + + +subject->sub3 + + +msg1 + + + +reply->publisher + + + + + + +sub3->reply + + + + + diff --git a/.gitbook/assets/seqno.svg b/.gitbook/assets/seqno.svg new file mode 100644 index 0000000..81e8a44 --- /dev/null +++ b/.gitbook/assets/seqno.svg @@ -0,0 +1,59 @@ + + + + + + +nats_pub_sub + + + +publisher + +Publisher + + + +subject + +Subject + + + +publisher->subject + + +updates.1 + + + +publisher->subject + + +updates.2 + + + +publisher->subject + + +updates.3 + + + +sub + +Subscriber + + + +subject->sub + + +updates.* + + + diff --git a/.gitbook/assets/simple.svg b/.gitbook/assets/simple.svg new file mode 100644 index 0000000..1fade1e --- /dev/null +++ b/.gitbook/assets/simple.svg @@ -0,0 +1,76 @@ + + + + + + + + + + + + + + + + Produced by OmniGraffle 7.10.2 + 2019-05-07 16:42:18 +0000 + + + Canvas 1 + + + Layer 1 + + + + + A1 + + + + + + + A2 + + + + + + + A3 + + + + + + + B1 + + + + + + + B2 + + + + + + + + + + + + + + + + + + + + diff --git a/.gitbook/assets/subjects1.svg b/.gitbook/assets/subjects1.svg new file mode 100644 index 0000000..dc7b877 --- /dev/null +++ b/.gitbook/assets/subjects1.svg @@ -0,0 +1,58 @@ + + + + + + +g + + + +publisher + +PUB time.us + + + +subject + +nats-server + + + +publisher->subject + + +msg + + + +sub1 + +SUB time.us + + + +subject->sub1 + + +msg + + + +sub2 + +SUB time.us + + + +subject->sub2 + + +msg + + + diff --git a/.gitbook/assets/subjects2.svg b/.gitbook/assets/subjects2.svg new file mode 100644 index 0000000..b70adb2 --- /dev/null +++ b/.gitbook/assets/subjects2.svg @@ -0,0 +1,58 @@ + + + + + + +g + + + +publisher + +PUB time.us.east + + + +subject + +nats-server + + + +publisher->subject + + +msg + + + +sub1 + +SUB time.*.east + + + +subject->sub1 + + +msg + + + +sub2 + +SUB time.us.east + + + +subject->sub2 + + +msg + + + diff --git a/.gitbook/assets/subjects3.svg b/.gitbook/assets/subjects3.svg new file mode 100644 index 0000000..e73c731 --- /dev/null +++ b/.gitbook/assets/subjects3.svg @@ -0,0 +1,65 @@ + + + + + + +g + + + +publisher + +PUB time.us.east.atlanta + + + +subject + +nats-server + + + +publisher->subject + + +msg + + + +sub1 + +SUB time.us.east.atlanta + + + +subject->sub1 + + +msg + + + +sub2 + +SUB time.us.* + + + + +sub3 + +SUB time.us.> + + + +subject->sub3 + + +msg + + + diff --git a/.gitbook/assets/three_gw.svg b/.gitbook/assets/three_gw.svg new file mode 100644 index 0000000..1fa78b4 --- /dev/null +++ b/.gitbook/assets/three_gw.svg @@ -0,0 +1,109 @@ + + + + + + + + + + + + + + + + + + + + + Produced by OmniGraffle 7.10.2 + 2019-05-07 16:43:34 +0000 + + + Canvas 1 + + + Layer 1 + + + + + A1 + + + + + + + A2 + + + + + + + A3 + + + + + + + B1 + + + + + + + B2 + + + + + + + + + + + + + + + + + + + + + + C1 + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/README.md b/README.md index 1cb2863..78b8851 100644 --- a/README.md +++ b/README.md @@ -1,18 +1,12 @@ +# Introduction - - -# The Importance of Messaging +## The Importance of Messaging -Developing and deploying applications and services that communicate in distributed systems -can be complex and difficult. However there are two basic patterns, request/reply or RPC for services, -and event and data streams. A modern technology should provide -features to make this easier, scalable, secure, location independent and observable. +Developing and deploying applications and services that communicate in distributed systems can be complex and difficult. However there are two basic patterns, request/reply or RPC for services, and event and data streams. A modern technology should provide features to make this easier, scalable, secure, location independent and observable. -## Distributed Computing Needs of Today +### Distributed Computing Needs of Today -A modern messaging system needs to support multiple communication patterns, be -secure by default, support multiple qualities of service, and provide secure -multi-tenancy for a truly shared infrastructure. A modern system needs to include: +A modern messaging system needs to support multiple communication patterns, be secure by default, support multiple qualities of service, and provide secure multi-tenancy for a truly shared infrastructure. A modern system needs to include: * Secure by default communications for microservices, edge platforms and devices * Secure multi-tenancy in a single distributed communication technology @@ -22,12 +16,9 @@ multi-tenancy for a truly shared infrastructure. A modern system needs to includ * Highly scalable and performant with built-in load balancing and dynamic auto-scaling * Consistent identity and security mechanisms from edge devices to backend services -## NATS +### NATS -NATS was built to meet the distributed computing needs of today and tomorrow. -NATS is simple and secure messaging made for developers and operators who want -to spend more time developing modern applications and services than worrying -about a distributed communication system. +NATS was built to meet the distributed computing needs of today and tomorrow. NATS is simple and secure messaging made for developers and operators who want to spend more time developing modern applications and services than worrying about a distributed communication system. * Easy to use for developers and operators * High-Performance @@ -38,15 +29,15 @@ about a distributed communication system. * Client support for over 30 different programming languages * Cloud Native, a CNCF project with Kubernetes and Prometheus integrations -## Use Cases +### Use Cases -NATS can run anywhere, from large servers and cloud instances, through edge -gateways and even IoT devices. Use cases for NATS include: +NATS can run anywhere, from large servers and cloud instances, through edge gateways and even IoT devices. Use cases for NATS include: * Cloud Messaging - * Services (microservices, service mesh) - * Event/Data Streaming (observability, analytics, ML/AI) + * Services \(microservices, service mesh\) + * Event/Data Streaming \(observability, analytics, ML/AI\) * Command and Control * IoT and Edge * Telemetry / Sensor Data / Command and Control * Augmenting or Replacing Legacy Messaging Systems + diff --git a/SUMMARY.md b/SUMMARY.md index d38bc88..2575cd8 100644 --- a/SUMMARY.md +++ b/SUMMARY.md @@ -1,201 +1,195 @@ -# Summary +# Table of contents * [Introduction](README.md) -* [What's New in 2.0](whats_new/whats_new_20.md) +* [What's New in 2.0](whats_new_20.md) * [FAQ](faq.md) * [nats.io](https://nats.io) ## Concepts -* [What is NATS](developer/concepts/intro.md) -* [Subject-Based Messaging](developer/concepts/subjects.md) -* [Publish-Subscribe](developer/concepts/pubsub.md) -* [Request-Reply](developer/concepts/reqreply.md) -* [Queue Groups](developer/concepts/queue.md) -* [Acknowledgements](developer/concepts/acks.md) -* [Sequence Numbers](developer/concepts/seq_num.md) +* [What is NATS](concepts/intro.md) +* [Subject-Based Messaging](concepts/subjects.md) +* [Publish-Subscribe](concepts/pubsub.md) +* [Request-Reply](concepts/reqreply.md) +* [Queue Groups](concepts/queue.md) +* [Acknowledgements](concepts/acks.md) +* [Sequence Numbers](concepts/seq_num.md) ## Developing With NATS -* [Introduction](developer/README.md) - -* [Connecting](developer/connecting/intro.md) - * [Connecting to the Default Server](developer/connecting/default_server.md) - * [Connecting to a Specific Server](developer/connecting/specific_server.md) - * [Connecting to a Cluster](developer/connecting/cluster.md) - * [Setting a Connect Timeout](developer/connecting/connect_timeout.md) - * [Ping/Pong Protocol](developer/connecting/pingpong.md) - * [Controlling the Client/Server Protocol](developer/connecting/protocol.md) - * [Turning Off Echo'd Messages](developer/connecting/noecho.md) - -* [Automatic Reconnections](developer/reconnect/intro.md) - * [Disabling Reconnect](developer/reconnect/disable.md) - * [Set the Number of Reconnect Attempts](developer/reconnect/max.md) - * [Pausing Between Reconnect Attempts](developer/reconnect/wait.md) - * [Avoiding the Thundering Herd](developer/reconnect/random.md) - * [Listening for Reconnect Events](developer/reconnect/events.md) - * [Buffering Messages During Reconnect Attempts](developer/reconnect/buffer.md) - -* [Securing Connections](developer/security/intro.md) - * [Authenticating with a User and Password](developer/security/userpass.md) - * [Authenticating with a Token](developer/security/token.md) - * [Authenticating with an NKey](developer/security/nkey.md) - * [Authenticating with a Credentials File](developer/security/creds.md) - * [Encrypting Connections with TLS](developer/security/tls.md) - -* [Receiving Messages](developer/receiving/intro.md) - * [Synchronous Subscriptions](developer/receiving/sync.md) - * [Asynchronous Subscriptions](developer/receiving/async.md) - * [Unsubscribing](developer/receiving/unsubscribing.md) - * [Unsubscribing After N Messages](developer/receiving/unsub_after.md) - * [Replying to a Message](developer/receiving/reply.md) - * [Wildcard Subscriptions](developer/receiving/wildcards.md) - * [Queue Subscriptions](developer/receiving/queues.md) - * [Draining Messages Before Disconnect](developer/receiving/drain.md) - * [Structured Data](developer/receiving/structure.md) - -* [Sending Messages](developer/sending/intro.md) - * [Including a Reply Subject](developer/sending/replyto.md) - * [Request-Reply Semantics](developer/sending/request_reply.md) - * [Caches, Flush and Ping](developer/sending/caches.md) - * [Sending Structured Data](developer/sending/structure.md) - -* [Monitoring the Connection](developer/events/intro.md) - * [Listen for Connection Events](developer/events/events.md) - * [Slow Consumers](developer/events/slow.md) - -* [Tutorials](developer/tutorials/intro.md) - * [Explore NATS Pub/Sub](developer/tutorials/pubsub.md) - * [Explore NATS Request/Reply](developer/tutorials/reqreply.md) - * [Explore NATS Queueing](developer/tutorials/queues.md) - * [Advanced Connect and Custom Dialer in Go](developer/tutorials/custom_dialer.md) +* [Introduction](developing-with-nats/developer.md) +* [Connecting](developing-with-nats/intro/README.md) + * [Connecting to the Default Server](developing-with-nats/intro/default_server.md) + * [Connecting to a Specific Server](developing-with-nats/intro/specific_server.md) + * [Connecting to a Cluster](developing-with-nats/intro/cluster.md) + * [Setting a Connect Timeout](developing-with-nats/intro/connect_timeout.md) + * [Ping/Pong Protocol](developing-with-nats/intro/pingpong.md) + * [Controlling the Client/Server Protocol](developing-with-nats/intro/protocol.md) + * [Turning Off Echo'd Messages](developing-with-nats/intro/noecho.md) +* [Automatic Reconnections](developing-with-nats/intro-1/README.md) + * [Disabling Reconnect](developing-with-nats/intro-1/disable.md) + * [Set the Number of Reconnect Attempts](developing-with-nats/intro-1/max.md) + * [Pausing Between Reconnect Attempts](developing-with-nats/intro-1/wait.md) + * [Avoiding the Thundering Herd](developing-with-nats/intro-1/random.md) + * [Listening for Reconnect Events](developing-with-nats/intro-1/events.md) + * [Buffering Messages During Reconnect Attempts](developing-with-nats/intro-1/buffer.md) +* [Securing Connections](developing-with-nats/intro-2/README.md) + * [Authenticating with a User and Password](developing-with-nats/intro-2/userpass.md) + * [Authenticating with a Token](developing-with-nats/intro-2/token.md) + * [Authenticating with an NKey](developing-with-nats/intro-2/nkey.md) + * [Authenticating with a Credentials File](developing-with-nats/intro-2/creds.md) + * [Encrypting Connections with TLS](developing-with-nats/intro-2/tls.md) +* [Receiving Messages](developing-with-nats/intro-3/README.md) + * [Synchronous Subscriptions](developing-with-nats/intro-3/sync.md) + * [Asynchronous Subscriptions](developing-with-nats/intro-3/async.md) + * [Unsubscribing](developing-with-nats/intro-3/unsubscribing.md) + * [Unsubscribing After N Messages](developing-with-nats/intro-3/unsub_after.md) + * [Replying to a Message](developing-with-nats/intro-3/reply.md) + * [Wildcard Subscriptions](developing-with-nats/intro-3/wildcards.md) + * [Queue Subscriptions](developing-with-nats/intro-3/queues.md) + * [Draining Messages Before Disconnect](developing-with-nats/intro-3/drain.md) + * [Structured Data](developing-with-nats/intro-3/structure.md) +* [Sending Messages](developing-with-nats/intro-4/README.md) + * [Including a Reply Subject](developing-with-nats/intro-4/replyto.md) + * [Request-Reply Semantics](developing-with-nats/intro-4/request_reply.md) + * [Caches, Flush and Ping](developing-with-nats/intro-4/caches.md) + * [Sending Structured Data](developing-with-nats/intro-4/structure.md) +* [Monitoring the Connection](developing-with-nats/intro-5/README.md) + * [Listen for Connection Events](developing-with-nats/intro-5/events.md) + * [Slow Consumers](developing-with-nats/intro-5/slow.md) +* [Tutorials](developing-with-nats/intro-6/README.md) + * [Explore NATS Pub/Sub](developing-with-nats/intro-6/pubsub.md) + * [Explore NATS Request/Reply](developing-with-nats/intro-6/reqreply.md) + * [Explore NATS Queueing](developing-with-nats/intro-6/queues.md) + * [Advanced Connect and Custom Dialer in Go](developing-with-nats/intro-6/custom_dialer.md) ## NATS Server -* [Installing](nats_server/installation.md) -* [Running](nats_server/running.md) - * [Window Service](nats_server/windows_srv.md) -* [Clients](nats_server/clients.md) -* [Flags](nats_server/flags.md) -* [Configuration](nats_server/configuration.md) - * [Securing NATS](nats_server/securing_nats.md) - * [Enabling TLS](nats_server/tls.md) - * [Authentication](nats_server/auth_intro.md) - * [Tokens](nats_server/tokens.md) - * [Username/Password](nats_server/username_password.md) - * [TLS Authentication](nats_server/tls_mutual_auth.md) - * [NKeys](nats_server/nkey_auth.md) - * [Accounts](nats_server/accounts.md) - * [JWTs](nats_server/jwt_auth.md) - * [Authentication Timeout](nats_server/auth_timeout.md) - * [Authorization](nats_server/authorization.md) - * [Clustering](nats_server/clustering.md) - * [Configuration](nats_server/cluster_config.md) - * [TLS Authentication](nats_server/cluster_tls.md) - * [Gateways](gateways/README.md) - * [Configuration](gateways/gateway.md) - * [Leaf Nodes](leafnodes/README.md) - * [Configuration](leafnodes/leafnode_conf.md) - * [Logging](nats_server/logging.md) - * [Monitoring](nats_server/monitoring.md) -* [Managing A NATS Server](nats_admin/README.md) - * [Upgrading a Cluster](nats_admin/upgrading_cluster.md) - * [Slow Consumers](nats_admin/slow_consumers.md) - * [Signals](nats_admin/signals.md) - * [System Accounts](sys_accounts/README.md) - * [Configuration](sys_accounts/sys_accounts.md) -* [NATS and Docker](nats_docker/README.md) - * [Tutorial](nats_docker/nats-docker-tutorial.md) - * [Docker Swarm](nats_docker/docker_swarm.md) +* [Installing](nats-server/installation.md) +* [Running](nats-server/running/README.md) + * [Window Service](nats-server/running/windows_srv.md) +* [Clients](nats-server/clients.md) +* [Flags](nats-server/flags.md) +* [Configuration](nats-server/configuration/README.md) + * [Securing NATS](nats-server/configuration/securing_nats/README.md) + * [Enabling TLS](nats-server/configuration/securing_nats/tls.md) + * [Authentication](nats-server/configuration/securing_nats/auth_intro/README.md) + * [Tokens](nats-server/configuration/securing_nats/auth_intro/tokens.md) + * [Username/Password](nats-server/configuration/securing_nats/auth_intro/username_password.md) + * [TLS Authentication](nats-server/configuration/securing_nats/auth_intro/tls_mutual_auth.md) + * [NKeys](nats-server/configuration/securing_nats/auth_intro/nkey_auth.md) + * [Accounts](nats-server/configuration/securing_nats/auth_intro/accounts.md) + * [JWTs](nats-server/configuration/securing_nats/auth_intro/jwt_auth.md) + * [Authentication Timeout](nats-server/configuration/securing_nats/auth_intro/auth_timeout.md) + * [Authorization](nats-server/configuration/securing_nats/authorization.md) + * [Clustering](nats-server/configuration/clustering/README.md) + * [Configuration](nats-server/configuration/clustering/cluster_config.md) + * [TLS Authentication](nats-server/configuration/clustering/cluster_tls.md) + * [Gateways](nats-server/configuration/gateways/README.md) + * [Configuration](nats-server/configuration/gateways/gateway.md) + * [Leaf Nodes](nats-server/configuration/leafnodes/README.md) + * [Configuration](nats-server/configuration/leafnodes/leafnode_conf.md) + * [Logging](nats-server/configuration/logging.md) + * [Monitoring](nats-server/configuration/monitoring.md) +* [Managing A NATS Server](nats-server/nats_admin/README.md) + * [Upgrading a Cluster](nats-server/nats_admin/upgrading_cluster.md) + * [Slow Consumers](nats-server/nats_admin/slow_consumers.md) + * [Signals](nats-server/nats_admin/signals.md) + * [System Accounts](nats-server/nats_admin/sys_accounts/README.md) + * [Configuration](nats-server/nats_admin/sys_accounts/sys_accounts.md) +* [NATS and Docker](nats-server/nats_docker/README.md) + * [Tutorial](nats-server/nats_docker/nats-docker-tutorial.md) + * [Docker Swarm](nats-server/nats_docker/docker_swarm.md) ## NATS Tools -* [mkpasswd](nats_tools/mkpasswd.md) -* [nk](nats_tools/nk.md) -* [nsc](nats_tools/nsc/README.md) - * [Basics](nats_tools/nsc/nsc.md) - * [Streams](nats_tools/nsc/streams.md) - * [Services](nats_tools/nsc/services.md) - * [Signing Keys](nats_tools/nsc/signing_keys.md) - * [Revocation](nats_tools/nsc/revocation.md) - * [Managed Operators](nats_tools/nsc/managed.md) -* [nats-account-server](nats_tools/nas/README.md) - * [Basics](nats_tools/nas/nas_conf.md) - * [Inspecting JWTs](nats_tools/nas/inspecting_jwts.md) - * [Directory Store](nats_tools/nas/dir_store.md) - * [Update Notifications](nats_tools/nas/notifications.md) - * [Memory Resolver](nats_tools/nas/mem_resolver.md) -* [nats-top](nats_tools/nats_top/README.md) - * [Tutorial](nats_tools/nats_top/nats-top-tutorial.md) -* [nats-bench](nats_tools/natsbench.md) +* [mkpasswd](nats-tools/mkpasswd.md) +* [nk](nats-tools/nk.md) +* [nsc](nats-tools/nsc/README.md) + * [Basics](nats-tools/nsc/nsc.md) + * [Streams](nats-tools/nsc/streams.md) + * [Services](nats-tools/nsc/services.md) + * [Signing Keys](nats-tools/nsc/signing_keys.md) + * [Revocation](nats-tools/nsc/revocation.md) + * [Managed Operators](nats-tools/nsc/managed.md) +* [nats-account-server](nats-tools/nas/README.md) + * [Basics](nats-tools/nas/nas_conf.md) + * [Inspecting JWTs](nats-tools/nas/inspecting_jwts.md) + * [Directory Store](nats-tools/nas/dir_store.md) + * [Update Notifications](nats-tools/nas/notifications.md) + * [Memory Resolver](nats-tools/nas/mem_resolver.md) +* [nats-top](nats-tools/nats_top/README.md) + * [Tutorial](nats-tools/nats_top/nats-top-tutorial.md) +* [nats-bench](nats-tools/natsbench.md) ## NATS Streaming Concepts -* [Introduction](nats_streaming/intro.md) -* [Relation to NATS](nats_streaming/relation-to-nats.md) -* [Client Connections](nats_streaming/client-connections.md) -* [Channels](nats_streaming/channels/channels.md) - * [Message Log](nats_streaming/channels/message-log.md) - * [Subscriptions](nats_streaming/channels/subscriptions/subscriptions.md) - * [Regular](nats_streaming/channels/subscriptions/regular.md) - * [Durable](nats_streaming/channels/subscriptions/durable.md) - * [Queue Group](nats_streaming/channels/subscriptions/queue-group.md) - * [Redelivery](nats_streaming/channels/subscriptions/redelivery.md) -* [Store Interface](nats_streaming/store-interface.md) -* [Store Encryption](nats_streaming/store-encryption.md) -* [Clustering](nats_streaming/clustering/clustering.md) - * [Supported Stores](nats_streaming/clustering/supported-stores.md) - * [Configuration](nats_streaming/clustering/configuration.md) - * [Auto Configuration](nats_streaming/clustering/auto-configuration.md) - * [Containers](nats_streaming/clustering/containers.md) -* [Fault Tolerance](nats_streaming/fault-tolerance/ft.md) - * [Active Server](nats_streaming/fault-tolerance/active-server.md) - * [Standby Servers](nats_streaming/fault-tolerance/standby-server.md) - * [Shared State](nats_streaming/fault-tolerance/shared-state.md) - * [Failover](nats_streaming/fault-tolerance/failover.md) -* [Partitioning](nats_streaming/partitioning.md) -* [Monitoring](nats_streaming/monitoring/monitoring.md) - * [Endpoints](nats_streaming/monitoring/endpoints.md) +* [Introduction](nats-streaming-concepts/intro.md) +* [Relation to NATS](nats-streaming-concepts/relation-to-nats.md) +* [Client Connections](nats-streaming-concepts/client-connections.md) +* [Channels](nats-streaming-concepts/channels/README.md) + * [Message Log](nats-streaming-concepts/channels/message-log.md) + * [Subscriptions](nats-streaming-concepts/channels/subscriptions/README.md) + * [Regular](nats-streaming-concepts/channels/subscriptions/regular.md) + * [Durable](nats-streaming-concepts/channels/subscriptions/durable.md) + * [Queue Group](nats-streaming-concepts/channels/subscriptions/queue-group.md) + * [Redelivery](nats-streaming-concepts/channels/subscriptions/redelivery.md) +* [Store Interface](nats-streaming-concepts/store-interface.md) +* [Store Encryption](nats-streaming-concepts/store-encryption.md) +* [Clustering](nats-streaming-concepts/clustering/README.md) + * [Supported Stores](nats-streaming-concepts/clustering/supported-stores.md) + * [Configuration](nats-streaming-concepts/clustering/configuration.md) + * [Auto Configuration](nats-streaming-concepts/clustering/auto-configuration.md) + * [Containers](nats-streaming-concepts/clustering/containers.md) +* [Fault Tolerance](nats-streaming-concepts/ft/README.md) + * [Active Server](nats-streaming-concepts/ft/active-server.md) + * [Standby Servers](nats-streaming-concepts/ft/standby-server.md) + * [Shared State](nats-streaming-concepts/ft/shared-state.md) + * [Failover](nats-streaming-concepts/ft/failover.md) +* [Partitioning](nats-streaming-concepts/partitioning.md) +* [Monitoring](nats-streaming-concepts/monitoring/README.md) + * [Endpoints](nats-streaming-concepts/monitoring/endpoints.md) ## Developing With NATS Streaming -* [Introduction](developer/streaming/README.md) -* [Connecting to NATS Streaming](developer/streaming/connecting.md) -* [Publishing to a Channel](developer/streaming/publishing.md) -* [Receiving Messages from a Channel](developer/streaming/receiving.md) -* [Durable Subscriptions](developer/streaming/durables.md) -* [Queue Subscriptions](developer/streaming/queues.md) -* [Acknowledgements](developer/streaming/acks.md) -* [The Streaming Protocol](developer/streaming/protocol.md) +* [Introduction](developing-with-nats-streaming/streaming.md) +* [Connecting to NATS Streaming](developing-with-nats-streaming/connecting.md) +* [Publishing to a Channel](developing-with-nats-streaming/publishing.md) +* [Receiving Messages from a Channel](developing-with-nats-streaming/receiving.md) +* [Durable Subscriptions](developing-with-nats-streaming/durables.md) +* [Queue Subscriptions](developing-with-nats-streaming/queues.md) +* [Acknowledgements](developing-with-nats-streaming/acks.md) +* [The Streaming Protocol](developing-with-nats-streaming/protocol.md) ## NATS Streaming Server -* [Important Changes](nats_streaming/gettingstarted/changes.md) -* [Installing](nats_streaming/gettingstarted/install.md) -* [Running](nats_streaming/gettingstarted/run.md) -* [Configuring](nats_streaming/configuring/configuring.md) - * [Command line arguments](nats_streaming/configuring/cmdline.md) - * [Configuration file](nats_streaming/configuring/cfgfile.md) - * [Store Limits](nats_streaming/configuring/storelimits.md) - * [Limits inheritance](nats_streaming/configuring/storelimits.md#limits-inheritance) - * [Persistence](nats_streaming/configuring/persistence.md) - * [File Store](nats_streaming/configuring/filestore.md) - * [Options](nats_streaming/configuring/filestore.md#options) - * [Recovery Errors](nats_streaming/configuring/filestore.md#recovery-errors) - * [SQL Store](nats_streaming/configuring/sqlstore.md) - * [Read and Write Timeouts](nats_streaming/configuring/sqlstore.md#read-and-write-timeouts) - * [Options](nats_streaming/configuring/sqlstore.md#options) - * [Securing](nats_streaming/configuring/tls.md) - * [Authenticating Users](nats_streaming/configuring/tls.md#authenticating-users) - * [TLS](nats_streaming/configuring/tls.md#using-tls) -* [Process Signaling](nats_streaming/gettingstarted/process-signaling.md) -* [Windows Service](nats_streaming/gettingstarted/windows-service.md) -* [Embedding NATS Streaming Server](developer/streaming/embedding.md) -* [Docker Swarm](nats_streaming/swarm.md) +* [Important Changes](nats-streaming-server/changes.md) +* [Installing](nats-streaming-server/install.md) +* [Running](nats-streaming-server/run.md) +* [Configuring](nats-streaming-server/configuring/README.md) + * [Command line arguments](nats-streaming-server/configuring/cmdline.md) + * [Configuration file](nats-streaming-server/configuring/cfgfile.md) + * [Store Limits](nats-streaming-server/configuring/storelimits/README.md) + * [Limits inheritance](nats-streaming-server/configuring/storelimits/limits-inheritance.md) + * [Persistence](nats-streaming-server/configuring/persistence/README.md) + * [File Store](nats-streaming-server/configuring/persistence/filestore/README.md) + * [Options](nats-streaming-server/configuring/persistence/filestore/options.md) + * [Recovery Errors](nats-streaming-server/configuring/persistence/filestore/recovery-errors.md) + * [SQL Store](nats-streaming-server/configuring/persistence/sqlstore/README.md) + * [Read and Write Timeouts](nats-streaming-server/configuring/persistence/sqlstore/read-and-write-timeouts.md) + * [Options](nats-streaming-server/configuring/persistence/sqlstore/options.md) + * [Securing](nats-streaming-server/configuring/tls/README.md) + * [Authenticating Users](nats-streaming-server/configuring/tls/authenticating-users.md) + * [TLS](nats-streaming-server/configuring/tls/tls.md) +* [Process Signaling](nats-streaming-server/process-signaling.md) +* [Windows Service](nats-streaming-server/windows-service.md) +* [Embedding NATS Streaming Server](nats-streaming-server/embedding.md) +* [Docker Swarm](nats-streaming-server/swarm.md) ## NATS Protocol -* [Protocol Demo](nats_protocol/nats-protocol-demo.md) -* [Client Protocol](nats_protocol/nats-protocol.md) - * [Developing a Client](nats_protocol/nats-client-dev.md) -* [NATS Cluster Protocol](nats_protocol/nats-server-protocol.md) +* [Protocol Demo](nats-protocol/nats-protocol-demo.md) +* [Client Protocol](nats-protocol/nats-protocol/README.md) + * [Developing a Client](nats-protocol/nats-protocol/nats-client-dev.md) +* [NATS Cluster Protocol](nats-protocol/nats-server-protocol.md) + diff --git a/developer/concepts/acks.md b/concepts/acks.md similarity index 96% rename from developer/concepts/acks.md rename to concepts/acks.md index 8b0502c..8fb8c1d 100644 --- a/developer/concepts/acks.md +++ b/concepts/acks.md @@ -2,6 +2,7 @@ In a system with at-most-once semantics, there are times when messages can be lost. If your application is doing request-reply it should use timeouts to handle any network or application failures. It is always a good idea to place a timeout on a requests and have code that deals with timeouts. When you are publishing an event or data stream, one way to ensure message delivery is to turn it into a request-reply with the concept of an acknowledgement message, or ACKs. In NATS an ACK can simply be an empty message, a message with no payload. -![](/assets/images/acks.svg) +![](../.gitbook/assets/acks.svg) Because the ACK can be empty it can take up very little network bandwidth, but the idea of the ACK turns a simple fire-and-forget into a fire-and-know world where the sender can be sure that the message was received by the other side, or with a [scatter-gather pattern](reqreply.md), several other sides. + diff --git a/developer/concepts/intro.md b/concepts/intro.md similarity index 67% rename from developer/concepts/intro.md rename to concepts/intro.md index d1beff5..dc202e9 100644 --- a/developer/concepts/intro.md +++ b/concepts/intro.md @@ -4,6 +4,7 @@ NATS messaging enables the exchange of data that is segmented into messages amon NATS makes it easy for programs to communicate across different environments, languages, cloud providers and on-premise systems. Clients connect to the NATS system, usually via a single URL, and then subscribe or publish messages to subjects. With this simple design, NATS lets programs share common message-handling code, isolate resources and interdependencies, and scale by easily handling an increase in message volume, whether those are service requests or stream data. -![](/assets/images/intro.svg) +![](../.gitbook/assets/intro.svg) + +NATS core offers an **at most once** quality of service. If a subscriber is not listening on the subject \(no subject match\), or is not active when the message is sent, the message is not received. This is the same level of guarantee that TCP/IP provides. By default, NATS is a fire-and-forget messaging system. If you need higher levels of service, you can use [NATS Streaming](../nats-streaming-concepts/intro.md) or build additional reliability into your client applications with proven and scalable reference designs. -NATS core offers an **at most once** quality of service. If a subscriber is not listening on the subject (no subject match), or is not active when the message is sent, the message is not received. This is the same level of guarantee that TCP/IP provides. By default, NATS is a fire-and-forget messaging system. If you need higher levels of service, you can use [NATS Streaming](/nats_streaming/intro.md) or build additional reliability into your client applications with proven and scalable reference designs. diff --git a/developer/concepts/pubsub.md b/concepts/pubsub.md similarity index 58% rename from developer/concepts/pubsub.md rename to concepts/pubsub.md index b5d620c..d8b7c06 100644 --- a/developer/concepts/pubsub.md +++ b/concepts/pubsub.md @@ -1,7 +1,8 @@ # Publish-Subscribe -NATS implements a publish-subscribe message distribution model for one-to-many communication. A publisher sends a message on a subject and any active subscriber listening on that subject receives the message. Subscribers can also register interest in wildcard subjects that work a bit like a regular expression (but only a bit). This one-to-many pattern is sometimes called fan-out. +NATS implements a publish-subscribe message distribution model for one-to-many communication. A publisher sends a message on a subject and any active subscriber listening on that subject receives the message. Subscribers can also register interest in wildcard subjects that work a bit like a regular expression \(but only a bit\). This one-to-many pattern is sometimes called fan-out. -![](/assets/images/pubsub.svg) +![](../.gitbook/assets/pubsub.svg) + +Try NATS publish subscribe on your own, using a live server by walking through the [pub-sub tutorial](../developing-with-nats/intro-6/pubsub.md). -Try NATS publish subscribe on your own, using a live server by walking through the [pub-sub tutorial](../tutorials/pubsub.md). diff --git a/developer/concepts/queue.md b/concepts/queue.md similarity index 77% rename from developer/concepts/queue.md rename to concepts/queue.md index eaadd2e..28ad135 100644 --- a/developer/concepts/queue.md +++ b/concepts/queue.md @@ -1,4 +1,4 @@ -# Queue Subscribers & Scalability +# Queue Groups NATS provides a built-in load balancing feature called distributed queues. Using queue subscribers will balance message delivery across a group of subscribers which can be used to provide application fault tolerance and scale workload processing. @@ -6,9 +6,9 @@ To create a queue subscription, subscribers register a queue name. All subscribe One of the great features of NATS is that queue groups are defined by the application and their queue subscribers, not on the server configuration. -Queue subscribers are ideal for scaling services. Scale up is as simple as running another application, scale down is terminating the application with a signal that drains the in flight requests. -This flexibility and lack of any configuration changes makes NATS an excellent service communication technology that can work with all platform technologies. +Queue subscribers are ideal for scaling services. Scale up is as simple as running another application, scale down is terminating the application with a signal that drains the in flight requests. This flexibility and lack of any configuration changes makes NATS an excellent service communication technology that can work with all platform technologies. -![](/assets/images/queue.svg) +![](../.gitbook/assets/queue.svg) + +Try NATS queue subscriptions on your own, using a live server by walking through the [queueing tutorial](../developing-with-nats/intro-6/queues.md). -Try NATS queue subscriptions on your own, using a live server by walking through the [queueing tutorial](../tutorials/queues.md). diff --git a/developer/concepts/reqreply.md b/concepts/reqreply.md similarity index 66% rename from developer/concepts/reqreply.md rename to concepts/reqreply.md index 2eb7f48..963ddad 100644 --- a/developer/concepts/reqreply.md +++ b/concepts/reqreply.md @@ -1,15 +1,14 @@ # Request-Reply -Request-Reply is a common pattern in modern distributed systems. A request is sent and the application either waits on the response with a certain timeout or receives a response asynchronously. -The increased complexity of modern systems requires features such as location transparency, scale up and scale down, observability and more. Many technologies need additional components, sidecars and proxies to accomplish the complete feature set. +Request-Reply is a common pattern in modern distributed systems. A request is sent and the application either waits on the response with a certain timeout or receives a response asynchronously. The increased complexity of modern systems requires features such as location transparency, scale up and scale down, observability and more. Many technologies need additional components, sidecars and proxies to accomplish the complete feature set. -NATS supports this pattern with its core communication mechanism, publish and subscribe. A request is published on a given subject with a reply subject, and responders listen on that subject and send responses to the reply subject. Reply subjects -are usually a subject called an \_INBOX that will be directed back to the requestor dynamically, regardless of location of either party. +NATS supports this pattern with its core communication mechanism, publish and subscribe. A request is published on a given subject with a reply subject, and responders listen on that subject and send responses to the reply subject. Reply subjects are usually a subject called an \_INBOX that will be directed back to the requestor dynamically, regardless of location of either party. NATS allows multiple responders to run and form dynamic queue groups for transparent scale up. The ability for NATS applications to drain before exiting allows scale down with no requests being dropped. And since NATS is based on publish-subscribe, observability is as simple as running another application that can view requests and responses to measure latency, watch for anomalies, direct scalability and more. The power of NATS even allows multiple responses where the first response is utilized and the system efficiently discards the additional ones. This allows for a sophisticated pattern to have multiple responders reduce response latency and jitter. -![](/assets/images/reqrepl.svg) +![](../.gitbook/assets/reqrepl.svg) + +Try NATS request reply on your own, using a live server by walking through the [request/reply tutorial](../developing-with-nats/intro-6/reqreply.md). -Try NATS request reply on your own, using a live server by walking through the [request/reply tutorial](../tutorials/reqreply.md). diff --git a/developer/concepts/seq_num.md b/concepts/seq_num.md similarity index 57% rename from developer/concepts/seq_num.md rename to concepts/seq_num.md index bc19f9f..166c748 100644 --- a/developer/concepts/seq_num.md +++ b/concepts/seq_num.md @@ -1,14 +1,13 @@ # Sequence Numbers -A common problem for one-to-many messages is that a message can get lost or dropped due to a network failure. A simple pattern for resolving this situation is to include a sequence id with the message. Receivers can check the sequence id to see if they have missed anything. -Sequence numbers combined with heartbeats in the absence of new data form a powerful and resilient pattern to detect loss. Systems that store and persist messages can also solve this problem, but sometimes are overkill for the problem at hand and usually cause additional management and operational cost. +A common problem for one-to-many messages is that a message can get lost or dropped due to a network failure. A simple pattern for resolving this situation is to include a sequence id with the message. Receivers can check the sequence id to see if they have missed anything. Sequence numbers combined with heartbeats in the absence of new data form a powerful and resilient pattern to detect loss. Systems that store and persist messages can also solve this problem, but sometimes are overkill for the problem at hand and usually cause additional management and operational cost. -![](/assets/images/seqno.svg) +![](../.gitbook/assets/seqno.svg) In order to really leverage sequence ids there are a few things to keep in mind: * Each sender will have to use their own sequence * If possible, receivers should be able to ask for missing messages by id -With NATS you can embed sequence ids in the message or include them as a token in the subject. For example, a sender can send messages to `updates.1`, `updates.2`, etc... and the subscribers can listen to `updates.*` and parse the subject to determine the sequence id. -Placing a sequence token into the subject may be desireable if the payload is unknown or embedding additional data such as a sequence number in the payload is not possible. +With NATS you can embed sequence ids in the message or include them as a token in the subject. For example, a sender can send messages to `updates.1`, `updates.2`, etc... and the subscribers can listen to `updates.*` and parse the subject to determine the sequence id. Placing a sequence token into the subject may be desireable if the payload is unknown or embedding additional data such as a sequence number in the payload is not possible. + diff --git a/developer/concepts/subjects.md b/concepts/subjects.md similarity index 75% rename from developer/concepts/subjects.md rename to concepts/subjects.md index 78d947a..57dfbeb 100644 --- a/developer/concepts/subjects.md +++ b/concepts/subjects.md @@ -1,10 +1,10 @@ -# Subject-based Messaging +# Subject-Based Messaging Fundamentally NATS is about publishing and listening for messages. Both of these depend heavily on _Subjects_ which scope messages into streams or topics. At its simplest, a subject is just a string of characters that form a name the publisher and subscriber can use to find each other. -![](/assets/images/subjects1.svg) +![](../.gitbook/assets/subjects1.svg) - The NATS server reserves a few characters as special, and the specification says that only "alpha-numeric" characters plus the "." should be used in subject names. Subjects are case-sensitive and cannot contain whitespace. For safety across clients, ASCII characters should be used, although this is subject to change in the future. +The NATS server reserves a few characters as special, and the specification says that only "alpha-numeric" characters plus the "." should be used in subject names. Subjects are case-sensitive and cannot contain whitespace. For safety across clients, ASCII characters should be used, although this is subject to change in the future. ## Subject Hierarchies @@ -26,14 +26,15 @@ NATS provides two _wildcards_ that can take the place of one or more elements in The first wildcard is `*` which will match a single token. For example, if an application wanted to listen for eastern time zones, they could subscribe to `time.*.east`, which would match `time.us.east` and `time.eu.east`. -![](/assets/images/subjects2.svg) +![](../.gitbook/assets/subjects2.svg) ### Matching Multiple Tokens The second wildcard is `>` which will match one or more tokens, and can only appear at the end of the subject. For example, `time.us.>` will match `time.us.east` and `time.us.east.atlanta`, while `time.us.*` would only match `time.us.east` since it can't match more than one token. -![](/assets/images/subjects3.svg) +![](../.gitbook/assets/subjects3.svg) ### Monitoring and Wire Taps -Subject to your security configuration, wildcards can be used for monitoring by creating something sometimes called a *wire tap*. In the simplest case you can create a subscriber for `>`. This application will receive all messages -- again, subject to security settings -- sent on your NATS cluster. +Subject to your security configuration, wildcards can be used for monitoring by creating something sometimes called a _wire tap_. In the simplest case you can create a subscriber for `>`. This application will receive all messages -- again, subject to security settings -- sent on your NATS cluster. + diff --git a/developer/connecting/cluster.md b/developer/connecting/cluster.md deleted file mode 100644 index 4adf482..0000000 --- a/developer/connecting/cluster.md +++ /dev/null @@ -1,20 +0,0 @@ -# Connecting to a Cluster - -When connecting to a cluster, there are a few things to think about. - -* Passing a URL for each cluster member (semi-optional) -* The connection algorithm -* The reconnect algorithm (discussed later) -* Server provided URLs - -When a client library first tries to connect it will use the list of URLs provided to the connection options or function. These URLs are checked, usually in order, and the first successful connection is used. - -After a client connects to the server, the server may provide a list of URLs for additional known servers. This allows a client to connect to one server and still have other servers available during reconnect. - -To insure the initial connection, your code should include a list of reasonable _front line_ servers. Those servers may know about other members of the cluster, and may tell the client about those members. But you don't have to configure the client to pass every valid member of the cluster in the connect method. - -By providing the ability to pass multiple connect options NATS can handle the possibility of a machine going down or being unavailable to a client. By adding the ability of the server to feed clients a list of known servers as part of the client-server protocol the mesh created by a cluster can grow and change organically while the clients are running. - -*Note, failure behavior is library dependent, please check the documentation for your client library on information about what happens if the connect fails.* - -!INCLUDE "../../_examples/connect_multiple.html" \ No newline at end of file diff --git a/developer/connecting/connect_timeout.md b/developer/connecting/connect_timeout.md deleted file mode 100644 index ea2ebb1..0000000 --- a/developer/connecting/connect_timeout.md +++ /dev/null @@ -1,5 +0,0 @@ -# Setting a Connect Timeout - -Each library has its own, language preferred way, to pass connection options. One of the most common options is a connection timeout. To set the maximum time to connect to a server to 10 seconds: - -!INCLUDE "../../_examples/connect_options.html" diff --git a/developer/connecting/default_server.md b/developer/connecting/default_server.md deleted file mode 100644 index 52bb4c1..0000000 --- a/developer/connecting/default_server.md +++ /dev/null @@ -1,5 +0,0 @@ -# Connecting to the Default Server - -Some libraries also provide a special way to connect to a *default* url, which is generally `nats://localhost:4222`: - -!INCLUDE "../../_examples/connect_default.html" \ No newline at end of file diff --git a/developer/connecting/specific_server.md b/developer/connecting/specific_server.md deleted file mode 100644 index 39923fa..0000000 --- a/developer/connecting/specific_server.md +++ /dev/null @@ -1,9 +0,0 @@ -# Connecting to a Specific Server - -The NATS client libraries can take a full URL, `nats://demo.nats.io:4222`, to specify a specific server host and port to connect to. - -Libraries are removing the requirement for an explicit protocol and may allow `nats://demo.nats.io:4222` or just `demo.nats.io:4222`. Check with your specific client library's documentation to see what URL formats are supported. - -For example, to connect to the demo server with a URL you can use: - -!INCLUDE "../../_examples/connect_url.html" \ No newline at end of file diff --git a/developer/reconnect/disable.md b/developer/reconnect/disable.md deleted file mode 100644 index 33d328f..0000000 --- a/developer/reconnect/disable.md +++ /dev/null @@ -1,5 +0,0 @@ -# Disable Reconnect - -You can disable automatic reconnect with connection options: - -!INCLUDE "../../_examples/reconnect_none.html" \ No newline at end of file diff --git a/developer/streaming/protocol.md b/developer/streaming/protocol.md deleted file mode 100644 index 61e689e..0000000 --- a/developer/streaming/protocol.md +++ /dev/null @@ -1,265 +0,0 @@ -# Writing your own client library - -You can find a list of all supported client libraries [here](https://nats.io/download/). There are also links to community contributed clients. - -In the event you would want to write your own NATS Streaming library, you could have a look at existing libraries to understand the flow. But you need to use [Google Protocol Buffers](https://developers.google.com/protocol-buffers/) to exchange protocols between the client and the server. - -## NATS Streaming Protocol - -The NATS streaming protocol sits atop the core NATS protocol and uses [Google's Protocol Buffers](https://developers.google.com/protocol-buffers/). Protocol buffer messages are marshaled into bytes and published as NATS messages on specific subjects described below. In communicating with the NATS Streaming Server, the NATS request/reply pattern is used for all protocol messages that have a corresponding reply. - -### NATS streaming protocol conventions - -**Subject names**: Subject names, including reply subject (INBOX) names, are case-sensitive and must be non-empty alphanumeric strings with no embedded whitespace, and optionally token-delimited using the dot character (`.`), e.g.: - -`FOO`, `BAR`, `foo.bar`, `foo.BAR`, `FOO.BAR` and `FOO.BAR.BAZ` are all valid subject names - -`FOO. BAR`, `foo. .bar` and`foo..bar` are *not- valid subject names - -**Wildcards**: NATS streaming does **not** support wildcards in subject subscriptions - -**Protocol definition**: The fields of NATS streaming protocol messages are defined in the NATS streaming client [protocol file](https://github.com/nats-io/stan.go/blob/master/pb/protocol.proto). - -### NATS streaming protocol messages - -The following table briefly describes the NATS streaming protocol messages. - -Click the name to see more detailed information, including usage: - -#### Protocols - -| Message Name | Sent By | Description -| ------------------------------------------------- |:--------|:-------------------------------------------- -| [`ConnectRequest`](#connectrequest) | Client | Request to connect to the NATS Streaming Server -| [`ConnectResponse`](#connectresponse) | Server | Result of a connection request -| [`SubscriptionRequest`](#subscriptionrequest) | Client | Request sent to subscribe and retrieve data -| [`SubscriptionResponse`](#subscriptionresponse) | Server | Result of a subscription request -| [`UnsubscribeRequest`](#unsubscriberequest) | Client | Unsubscribe from a subject -| [`PubMsg`](#pubmsg) | Client | Publish a message to a subject -| [`PubAck`](#puback) | Server | An acknowledgement that a published message has been processed on the server -| [`MsgProto`](#msgproto) | Server | A message from the NATS Streaming Server to a subscribing client -| [`Ack`](#ack) | Client | Acknowledges that a message has been received -| [`Ping`](#ping) | Client | Ping sent to server to detect connection loss -| [`PingResponse`](#pingresponse) | Server | Result of a Ping -| [`CloseRequest`](#closerequest) | Client | Request sent to close the connection to the NATS Streaming Server -| [`CloseResp`](#closeresponse) | Server | Result of the close request - -The following sections explain each protocol message. - -#### ConnectRequest - -##### Description - -A connection request is sent when a streaming client connects to the NATS Streaming Server. The connection request contains a unique identifier representing the client, and an inbox subject the client will listen on for incoming heartbeats. The identifier **must** be unique; a connection attempt with an identifier currently in use will fail. The inbox subject is the subject where the client receives incoming heartbeats, and responds by publishing an empty NATS message to the reply subject, indicating it is alive. The NATS Streaming Server will return a [ConnectResponse](#connectresponse) message to the reply subject specified in the NATS request message. - -More advanced libraries can set the protocol to 1 and send a connection ID which in combination with ping interval and ping max out allows the library to detect that the connection to the server is lost. - -This request is published to a subject comprised of the `.cluster-id`. For example, if a NATS Streaming Server was started with a cluster-id of `mycluster`, and the default prefix was used, the client publishes to `_STAN.discover.mycluster` - -##### Message Structure - -- `clientID`: A unique identifier for a client -- `heartbeatInbox`: An inbox to which the NATS Streaming Server will send heartbeats for the client to process -- `protocol`: Protocol the client is at -- `connID`: Connection ID, a way to uniquely identify a connection (no connection should ever have the same) -- `pingInterval`: Interval at which client wishes to send PINGs (expressed in seconds) -- `pingMaxOut`: Maximum number of PINGs without a response after which the connection can be considered lost - -[Back to table](#protocols) - - -#### ConnectResponse - -##### Description - -After a `ConnectRequest` is published, the NATS Streaming Server responds with this message on the reply subject of the underlying NATS request. The NATS Streaming Server requires the client to make requests and publish messages on certain subjects (described above), and when a connection is successful, the client saves the information returned to be used in sending other NATS streaming protocol messages. In the event the connection was not successful, an error is returned in the `error` field. - -##### Message Structure - -- `pubPrefix`: Prefix to use when publishing -- `subRequests`: Subject used for subscription requests -- `unsubRequests`: Subject used for unsubscribe requests -- `closeRequests`: Subject for closing a connection -- `error`: An error string, which will be empty/omitted upon success -- `subCloseRequests`: Subject to use for subscription close requests -- `pingRequests`: Subject to use for PING requests -- `pingInterval`: Interval at which client should send PINGs (expressed in seconds). -- `pingMaxOut`: Maximum number of PINGs without a response after which the connection can be considered lost -- `protocol`: Protocol version the server is at -- `publicKey`: Reserved for future use - -[Back to table](#protocols) - - -#### SubscriptionRequest - -##### Description - -A `SubscriptionRequest` is published on the subject returned in the `subRequests` field of a [ConnectResponse](#connectresponse), and creates a subscription to a subject on the NATS Streaming Server. This will return a [SubscriptionResponse](#subscriptionresponse) message to the reply subject specified in the NATS protocol request message. - -##### Message Structure - -- `clientID`: Client ID originally provided in the [ConnectRequest](#connectrequest) -- `subject`: Formal subject to subscribe to, e.g. foo.bar -- `qGroup`: Optional queue group -- `inbox`: Inbox subject to deliver messages on -- `maxInFlight`: Maximum inflight messages without an acknowledgement allowed -- `ackWaitInSecs`: Timeout for receiving an acknowledgement from the client -- `durableName`: Optional durable name which survives client restarts -- `startPosition`: An enumerated type specifying the point in history to start replaying data -- `startSequence`: Optional start sequence number -- `startTimeDelta`: Optional start time - -##### StartPosition enumeration - -- `NewOnly`: Send only new messages -- `LastReceived`: Send only the last received message -- `TimeDeltaStart`: Send messages from duration specified in the `startTimeDelta` field. -- `SequenceStart`: Send messages starting from the sequence in the `startSequence` field. -- `First`: Send all available messages - -[Back to table](#protocols) - - -#### SubscriptionResponse - -##### Description - -The `SubscriptionResponse` message is the response from the `SubscriptionRequest`. After a client has processed an incoming [MsgProto](#msgproto) message, it must send an acknowledgement to the `ackInbox` subject provided here. - -##### Message Structure - -- `ackInbox`: subject the client sends message acknowledgements to the NATS Streaming Server -- `error`: error string, empty/omitted if no error - -[Back to table](#protocols) - - -#### UnsubscribeRequest - -##### Description - -The `UnsubscribeRequest` closes or unsubcribes the subscription from the specified subject. The inbox specified is the `inbox` returned from the NATS Streaming Server in the `SubscriptionResponse`. Depending on which subject this request is sent, the action will result in close (if sent to subject `subCloseRequests`) or unsubscribe (if sent to subject `unsubRequests`) - -##### Message Structure - -- `clientID`: Client ID originally provided in the [ConnectRequest](#connectrequest) -- `subject`: Subject for the subscription -- `inbox`: Inbox subject to identify subscription -- `durableName`: Optional durable name which survives client restarts - -[Back to table](#protocols) - - -#### PubMsg - -##### Description - -The `PubMsg` protocol message is published from a client to the NATS Streaming Server. The GUID must be unique, and is returned in the [PubAck](#puback) message to correlate the success or failure of storing this particular message. - -##### Message Structure - -- `clientID`: Client ID originally provided in the [ConnectRequest](#connectrequest) -- `guid`: a guid generated for this particular message -- `subject`: subject -- `data`: payload -- `connID`: Connection ID. For servers that know about this field, clientID can be omitted - -[Back to table](#protocols) - - -#### PubAck - -##### Description - -The `PubAck` message is an acknowledgement from the NATS Streaming Server that a message has been processed. The message arrives on the subject specified on the reply subject of the NATS message the `PubMsg` was published on. The GUID is the same GUID used in the `PubMsg` being acknowledged. If an error string is present, the message was not persisted by the NATS Streaming Server and no guarantees regarding persistence are honored. `PubAck` messages may be handled asynchronously from their corresponding `PubMsg` in the client. - -##### Message Structure - -- `guid`: GUID of the message being acknowledged by the NATS Streaming Server -- `error`: An error string, empty/omitted if no error - -[Back to table](#protocols) - - -#### MsgProto - -##### Description - -The `MsgProto` message is received by client from the NATS Streaming Server, containing the payload of messages sent by a publisher. A `MsgProto` message that is not acknowledged with an [Ack](#ack) message within the duration specified by the `ackWaitInSecs` field of the subscription request will be redelivered. - -##### Message Structure - -- `sequence`: Globally ordered sequence number for the subject's channel -- `subject`: Subject -- `data`: Payload -- `timestamp`: Time the message was stored in the server. -- `redelivered`: Flag specifying if the message is being redelivered - -[Back to table](#protocols) - - -#### Ack - -##### Description - -An `Ack` message is an acknowledgement from the client that a [MsgProto](#msgproto) message has been considered received. It is published to the `ackInbox` field of the [SubscriptionResponse](#subscriptionresponse). - -##### Message Structure - -- `subject`: Subject of the message being acknowledged -- `sequence`: Sequence of the message being acknowledged - -[Back to table](#protocols) - - -#### Ping - -##### Description - -A `Ping` message is sent to the server at configured interval to check that the connection ID is still valid. This should be used only if client is at protocol 1, and has sent a `connID` in the [ConnectRequest](#connectrequest) protocol. - -##### Message Structure - -- `connID`: The connection ID - -[Back to table](#protocols) - - -#### PingResponse - -##### Description - -This is a response from the server to a `Ping` from the client. If the content is not empty, it will be the error indicating to the client why the connection is no longer valid. - -##### Message Structure - -- `error`: Error string, empty/omitted if no error - -[Back to table](#protocols) - - -#### CloseRequest - -##### Description - -A `CloseRequest` message is published on the `closeRequests` subject from the [ConnectResponse](#connectresponse), and notifies the NATS Streaming Server that the client connection is closing, allowing the server to free up resources. This message should **always** be sent when a client is finished using a connection. - -##### Message Structure - -- `clientID`: Client ID originally provided in the [ConnectRequest](#connectrequest) - -[Back to table](#protocols) - - -#### CloseResponse - -##### Description - -The `CloseResponse` is sent by the NATS Streaming Server on the reply subject of the `CloseRequest` NATS message. This response contains any error that may have occurred with the corresponding close call. - -##### Message Structure - -- `error`: error string, empty/omitted if no error - -[Back to table](#protocols) diff --git a/developer/tutorials/intro.md b/developer/tutorials/intro.md deleted file mode 100644 index 95db231..0000000 --- a/developer/tutorials/intro.md +++ /dev/null @@ -1,8 +0,0 @@ -# Tutorials - -Tutorials are provided to give guidance on commonly used aspects of NATS. - - * [Explore NATS Publish/Subscribe](pubsub.md) - * [Explore NATS Request/Reply](reqreply.md) - * [Explore NATS Queueing](queues.md) - * [Advanced Connect and Custom Dialer in Go](custom_dialer.md) \ No newline at end of file diff --git a/developer/streaming/acks.md b/developing-with-nats-streaming/acks.md similarity index 95% rename from developer/streaming/acks.md rename to developing-with-nats-streaming/acks.md index c753258..92b1968 100644 --- a/developer/streaming/acks.md +++ b/developing-with-nats-streaming/acks.md @@ -1,5 +1,7 @@ # Acknowledgements +## Acknowledgements + Subscribers can use auto-ack or manual-ack. Auto-ack is the default for most clients and is sent by the library when the message callback returns. Manual ack provides more control. The subscription options provide flags to: * Set manual acks to true @@ -14,7 +16,7 @@ sub, err := sc.Subscribe("foo", }, stan.SetManualAckMode(), stan.AckWait(aw)) ``` -# Max In Flight +## Max In Flight Subscribers can set max in flight to rate limit incoming messages. The server will send at most “max in flight” messages before receiving an acknowledgement. Setting max in flight to 1 insures every message is processed in order. @@ -23,3 +25,4 @@ sc.Subscribe("foo", func(m *stan.Msg) {...}, stan.SetManualAckMode(), stan.MaxInflight(25)) ``` + diff --git a/developer/streaming/connecting.md b/developing-with-nats-streaming/connecting.md similarity index 91% rename from developer/streaming/connecting.md rename to developing-with-nats-streaming/connecting.md index 62268dc..d8f460c 100644 --- a/developer/streaming/connecting.md +++ b/developing-with-nats-streaming/connecting.md @@ -1,12 +1,12 @@ # Connecting to NATS Streaming -First, it is recommended to understand the relation between Streaming and core NATS. You should familiarize yourself with the [concept](/nats_streaming/relation-to-nats.md). +First, it is recommended to understand the relation between Streaming and core NATS. You should familiarize yourself with the [concept](../nats-streaming-concepts/relation-to-nats.md). NATS Streaming is a service on top of NATS. To connect to the service you first connect to NATS and then use the client library to communicate with the server over your NATS connection. Most of the libraries provide a convenience mechanism for connecting in a single step. These convenience methods will take some NATS options, like the cluster ID, and perform the NATS connection first, then run the protocol to connect to the streaming server. Connecting to a streaming server requires a cluster id, defined by the server configuration, and a client ID defined by the client. -*Client ID should contain only alphanumeric characters, `-` or `_`* +_Client ID should contain only alphanumeric characters, `-` or `_`_ Connecting to a server running locally on the default port is as simple as this: @@ -15,6 +15,7 @@ sc, err := stan.Connect(clusterID, clientID) ``` If the server runs on port `1234`: + ```go sc, err := stan.Connect(clusterID, clientID, stan.NatsURL(“nats://localhost:1234)) ``` @@ -24,3 +25,4 @@ Sometimes you may want to provide NATS settings that aren't available in the str ```go sc, err := stan.Connect(clusterID, clientID, stan.NatsConn(nc)) ``` + diff --git a/developer/streaming/durables.md b/developing-with-nats-streaming/durables.md similarity index 82% rename from developer/streaming/durables.md rename to developing-with-nats-streaming/durables.md index c5d2550..6ec7de6 100644 --- a/developer/streaming/durables.md +++ b/developing-with-nats-streaming/durables.md @@ -10,4 +10,5 @@ sc.Subscribe("foo", func(m *stan.Msg) {...}, stan.DurableName("my-durable")) Unsubscribe will cause the server to completely remove the durable subscription. -Check the [concepts](/nats_streaming/channels/subscriptions/durable.md) section for more information. \ No newline at end of file +Check the [concepts](../nats-streaming-concepts/channels/subscriptions/durable.md) section for more information. + diff --git a/developing-with-nats-streaming/protocol.md b/developing-with-nats-streaming/protocol.md new file mode 100644 index 0000000..a54dfac --- /dev/null +++ b/developing-with-nats-streaming/protocol.md @@ -0,0 +1,254 @@ +# The Streaming Protocol + +You can find a list of all supported client libraries [here](https://nats.io/download/). There are also links to community contributed clients. + +In the event you would want to write your own NATS Streaming library, you could have a look at existing libraries to understand the flow. But you need to use [Google Protocol Buffers](https://developers.google.com/protocol-buffers/) to exchange protocols between the client and the server. + +## NATS Streaming Protocol + +The NATS streaming protocol sits atop the core NATS protocol and uses [Google's Protocol Buffers](https://developers.google.com/protocol-buffers/). Protocol buffer messages are marshaled into bytes and published as NATS messages on specific subjects described below. In communicating with the NATS Streaming Server, the NATS request/reply pattern is used for all protocol messages that have a corresponding reply. + +### NATS streaming protocol conventions + +**Subject names**: Subject names, including reply subject \(INBOX\) names, are case-sensitive and must be non-empty alphanumeric strings with no embedded whitespace, and optionally token-delimited using the dot character \(`.`\), e.g.: + +`FOO`, `BAR`, `foo.bar`, `foo.BAR`, `FOO.BAR` and `FOO.BAR.BAZ` are all valid subject names + +`FOO. BAR`, `foo. .bar` and`foo..bar` are \*not- valid subject names + +**Wildcards**: NATS streaming does **not** support wildcards in subject subscriptions + +**Protocol definition**: The fields of NATS streaming protocol messages are defined in the NATS streaming client [protocol file](https://github.com/nats-io/stan.go/blob/master/pb/protocol.proto). + +### NATS streaming protocol messages + +The following table briefly describes the NATS streaming protocol messages. + +Click the name to see more detailed information, including usage: + +#### Protocols + +| Message Name | Sent By | Description | +| :--- | :--- | :--- | +| [`ConnectRequest`](protocol.md#connectrequest) | Client | Request to connect to the NATS Streaming Server | +| [`ConnectResponse`](protocol.md#connectresponse) | Server | Result of a connection request | +| [`SubscriptionRequest`](protocol.md#subscriptionrequest) | Client | Request sent to subscribe and retrieve data | +| [`SubscriptionResponse`](protocol.md#subscriptionresponse) | Server | Result of a subscription request | +| [`UnsubscribeRequest`](protocol.md#unsubscriberequest) | Client | Unsubscribe from a subject | +| [`PubMsg`](protocol.md#pubmsg) | Client | Publish a message to a subject | +| [`PubAck`](protocol.md#puback) | Server | An acknowledgement that a published message has been processed on the server | +| [`MsgProto`](protocol.md#msgproto) | Server | A message from the NATS Streaming Server to a subscribing client | +| [`Ack`](protocol.md#ack) | Client | Acknowledges that a message has been received | +| [`Ping`](protocol.md#ping) | Client | Ping sent to server to detect connection loss | +| [`PingResponse`](protocol.md#pingresponse) | Server | Result of a Ping | +| [`CloseRequest`](protocol.md#closerequest) | Client | Request sent to close the connection to the NATS Streaming Server | +| [`CloseResp`](protocol.md#closeresponse) | Server | Result of the close request | + +The following sections explain each protocol message. + +#### ConnectRequest + +**Description** + +A connection request is sent when a streaming client connects to the NATS Streaming Server. The connection request contains a unique identifier representing the client, and an inbox subject the client will listen on for incoming heartbeats. The identifier **must** be unique; a connection attempt with an identifier currently in use will fail. The inbox subject is the subject where the client receives incoming heartbeats, and responds by publishing an empty NATS message to the reply subject, indicating it is alive. The NATS Streaming Server will return a [ConnectResponse](protocol.md#connectresponse) message to the reply subject specified in the NATS request message. + +More advanced libraries can set the protocol to 1 and send a connection ID which in combination with ping interval and ping max out allows the library to detect that the connection to the server is lost. + +This request is published to a subject comprised of the `.cluster-id`. For example, if a NATS Streaming Server was started with a cluster-id of `mycluster`, and the default prefix was used, the client publishes to `_STAN.discover.mycluster` + +**Message Structure** + +* `clientID`: A unique identifier for a client +* `heartbeatInbox`: An inbox to which the NATS Streaming Server will send heartbeats for the client to process +* `protocol`: Protocol the client is at +* `connID`: Connection ID, a way to uniquely identify a connection \(no connection should ever have the same\) +* `pingInterval`: Interval at which client wishes to send PINGs \(expressed in seconds\) +* `pingMaxOut`: Maximum number of PINGs without a response after which the connection can be considered lost + +[Back to table](protocol.md#protocols) + +#### ConnectResponse + +**Description** + +After a `ConnectRequest` is published, the NATS Streaming Server responds with this message on the reply subject of the underlying NATS request. The NATS Streaming Server requires the client to make requests and publish messages on certain subjects \(described above\), and when a connection is successful, the client saves the information returned to be used in sending other NATS streaming protocol messages. In the event the connection was not successful, an error is returned in the `error` field. + +**Message Structure** + +* `pubPrefix`: Prefix to use when publishing +* `subRequests`: Subject used for subscription requests +* `unsubRequests`: Subject used for unsubscribe requests +* `closeRequests`: Subject for closing a connection +* `error`: An error string, which will be empty/omitted upon success +* `subCloseRequests`: Subject to use for subscription close requests +* `pingRequests`: Subject to use for PING requests +* `pingInterval`: Interval at which client should send PINGs \(expressed in seconds\). +* `pingMaxOut`: Maximum number of PINGs without a response after which the connection can be considered lost +* `protocol`: Protocol version the server is at +* `publicKey`: Reserved for future use + +[Back to table](protocol.md#protocols) + +#### SubscriptionRequest + +**Description** + +A `SubscriptionRequest` is published on the subject returned in the `subRequests` field of a [ConnectResponse](protocol.md#connectresponse), and creates a subscription to a subject on the NATS Streaming Server. This will return a [SubscriptionResponse](protocol.md#subscriptionresponse) message to the reply subject specified in the NATS protocol request message. + +**Message Structure** + +* `clientID`: Client ID originally provided in the [ConnectRequest](protocol.md#connectrequest) +* `subject`: Formal subject to subscribe to, e.g. foo.bar +* `qGroup`: Optional queue group +* `inbox`: Inbox subject to deliver messages on +* `maxInFlight`: Maximum inflight messages without an acknowledgement allowed +* `ackWaitInSecs`: Timeout for receiving an acknowledgement from the client +* `durableName`: Optional durable name which survives client restarts +* `startPosition`: An enumerated type specifying the point in history to start replaying data +* `startSequence`: Optional start sequence number +* `startTimeDelta`: Optional start time + +**StartPosition enumeration** + +* `NewOnly`: Send only new messages +* `LastReceived`: Send only the last received message +* `TimeDeltaStart`: Send messages from duration specified in the `startTimeDelta` field. +* `SequenceStart`: Send messages starting from the sequence in the `startSequence` field. +* `First`: Send all available messages + +[Back to table](protocol.md#protocols) + +#### SubscriptionResponse + +**Description** + +The `SubscriptionResponse` message is the response from the `SubscriptionRequest`. After a client has processed an incoming [MsgProto](protocol.md#msgproto) message, it must send an acknowledgement to the `ackInbox` subject provided here. + +**Message Structure** + +* `ackInbox`: subject the client sends message acknowledgements to the NATS Streaming Server +* `error`: error string, empty/omitted if no error + +[Back to table](protocol.md#protocols) + +#### UnsubscribeRequest + +**Description** + +The `UnsubscribeRequest` closes or unsubcribes the subscription from the specified subject. The inbox specified is the `inbox` returned from the NATS Streaming Server in the `SubscriptionResponse`. Depending on which subject this request is sent, the action will result in close \(if sent to subject `subCloseRequests`\) or unsubscribe \(if sent to subject `unsubRequests`\) + +**Message Structure** + +* `clientID`: Client ID originally provided in the [ConnectRequest](protocol.md#connectrequest) +* `subject`: Subject for the subscription +* `inbox`: Inbox subject to identify subscription +* `durableName`: Optional durable name which survives client restarts + +[Back to table](protocol.md#protocols) + +#### PubMsg + +**Description** + +The `PubMsg` protocol message is published from a client to the NATS Streaming Server. The GUID must be unique, and is returned in the [PubAck](protocol.md#puback) message to correlate the success or failure of storing this particular message. + +**Message Structure** + +* `clientID`: Client ID originally provided in the [ConnectRequest](protocol.md#connectrequest) +* `guid`: a guid generated for this particular message +* `subject`: subject +* `data`: payload +* `connID`: Connection ID. For servers that know about this field, clientID can be omitted + +[Back to table](protocol.md#protocols) + +#### PubAck + +**Description** + +The `PubAck` message is an acknowledgement from the NATS Streaming Server that a message has been processed. The message arrives on the subject specified on the reply subject of the NATS message the `PubMsg` was published on. The GUID is the same GUID used in the `PubMsg` being acknowledged. If an error string is present, the message was not persisted by the NATS Streaming Server and no guarantees regarding persistence are honored. `PubAck` messages may be handled asynchronously from their corresponding `PubMsg` in the client. + +**Message Structure** + +* `guid`: GUID of the message being acknowledged by the NATS Streaming Server +* `error`: An error string, empty/omitted if no error + +[Back to table](protocol.md#protocols) + +#### MsgProto + +**Description** + +The `MsgProto` message is received by client from the NATS Streaming Server, containing the payload of messages sent by a publisher. A `MsgProto` message that is not acknowledged with an [Ack](protocol.md#ack) message within the duration specified by the `ackWaitInSecs` field of the subscription request will be redelivered. + +**Message Structure** + +* `sequence`: Globally ordered sequence number for the subject's channel +* `subject`: Subject +* `data`: Payload +* `timestamp`: Time the message was stored in the server. +* `redelivered`: Flag specifying if the message is being redelivered + +[Back to table](protocol.md#protocols) + +#### Ack + +**Description** + +An `Ack` message is an acknowledgement from the client that a [MsgProto](protocol.md#msgproto) message has been considered received. It is published to the `ackInbox` field of the [SubscriptionResponse](protocol.md#subscriptionresponse). + +**Message Structure** + +* `subject`: Subject of the message being acknowledged +* `sequence`: Sequence of the message being acknowledged + +[Back to table](protocol.md#protocols) + +#### Ping + +**Description** + +A `Ping` message is sent to the server at configured interval to check that the connection ID is still valid. This should be used only if client is at protocol 1, and has sent a `connID` in the [ConnectRequest](protocol.md#connectrequest) protocol. + +**Message Structure** + +* `connID`: The connection ID + +[Back to table](protocol.md#protocols) + +#### PingResponse + +**Description** + +This is a response from the server to a `Ping` from the client. If the content is not empty, it will be the error indicating to the client why the connection is no longer valid. + +**Message Structure** + +* `error`: Error string, empty/omitted if no error + +[Back to table](protocol.md#protocols) + +#### CloseRequest + +**Description** + +A `CloseRequest` message is published on the `closeRequests` subject from the [ConnectResponse](protocol.md#connectresponse), and notifies the NATS Streaming Server that the client connection is closing, allowing the server to free up resources. This message should **always** be sent when a client is finished using a connection. + +**Message Structure** + +* `clientID`: Client ID originally provided in the [ConnectRequest](protocol.md#connectrequest) + +[Back to table](protocol.md#protocols) + +#### CloseResponse + +**Description** + +The `CloseResponse` is sent by the NATS Streaming Server on the reply subject of the `CloseRequest` NATS message. This response contains any error that may have occurred with the corresponding close call. + +**Message Structure** + +* `error`: error string, empty/omitted if no error + +[Back to table](protocol.md#protocols) + diff --git a/developer/streaming/publishing.md b/developing-with-nats-streaming/publishing.md similarity index 99% rename from developer/streaming/publishing.md rename to developing-with-nats-streaming/publishing.md index bc140fa..ecc9e4e 100644 --- a/developer/streaming/publishing.md +++ b/developing-with-nats-streaming/publishing.md @@ -19,3 +19,4 @@ Even in this mode, the call will still block if the library has a number of publ ```go sc, err := sc.Connect(clusterID, clientName, stan.MaxPubAcksInflight(1000)) ``` + diff --git a/developer/streaming/queues.md b/developing-with-nats-streaming/queues.md similarity index 91% rename from developer/streaming/queues.md rename to developing-with-nats-streaming/queues.md index 6808423..120e538 100644 --- a/developer/streaming/queues.md +++ b/developing-with-nats-streaming/queues.md @@ -1,4 +1,4 @@ -# Queue Subscriptions in NATS Streaming +# Queue Subscriptions Queue subscriptions are created like other subscriptions with the addition of a queue name. @@ -13,6 +13,7 @@ qsub2, _ := sc.QueueSubscribe(channelName, Multiple subscriptions using the same channel and queue name are members of the same queue group. That means that if a message is published on that channel, only one member of the group receives the message. Other subscriptions receive messages independently of the queue groups, that is, a message is delivered to all subscriptions and one member of each queue group. To create a durable queue subscription, simply add a durable name: + ```go qsub, err := sc.QueueSubscribe(channelName, queueName, func(m *stan.Msg) {...}, @@ -20,6 +21,7 @@ qsub, err := sc.QueueSubscribe(channelName, ``` Subscriptions options apply to each member independently, notably, the `AckWait` and `MaxInflight`. Those two members of the same queue group use different options for redelivery and max inflight. + ```go qsub1, _ := sc.QueueSubscribe(channelName, queueName, func(m *stan.Msg) {...}, @@ -34,4 +36,5 @@ qsub2, _ := sc.QueueSubscribe(channelName, If the queue subscription is durable, only the last member calling `Unsubscribe()` will cause the durable queue group to be removed from the server. -Check the [concepts](/nats_streaming/channels/subscriptions/queue-group.md) section for more information. +Check the [concepts](../nats-streaming-concepts/channels/subscriptions/queue-group.md) section for more information. + diff --git a/developer/streaming/receiving.md b/developing-with-nats-streaming/receiving.md similarity index 90% rename from developer/streaming/receiving.md rename to developing-with-nats-streaming/receiving.md index d311e99..556b6f2 100644 --- a/developer/streaming/receiving.md +++ b/developing-with-nats-streaming/receiving.md @@ -9,9 +9,9 @@ Subscriptions come in several forms: * Queue * Queue/Durable -For more details on the various types, check the [concepts](/nats_streaming/channels/subscriptions/subscriptions.md) section. +For more details on the various types, check the [concepts](../nats-streaming-concepts/channels/subscriptions/) section. -***Note: message callbacks are invoked serially, one message at a time. If your application does not care about processing ordering and would prefer the messages to be dispatched concurrently, it is the application's responsibility to move them to some internal queue to be picked up by threads/go routines.*** +_**Note: message callbacks are invoked serially, one message at a time. If your application does not care about processing ordering and would prefer the messages to be dispatched concurrently, it is the application's responsibility to move them to some internal queue to be picked up by threads/go routines.**_ Subscriptions set their starting position on creation using position or time. For example, in Go you can start at: @@ -60,13 +60,16 @@ sub, err := sc.Subscribe("foo", When an application wishes to stop receiving, but wants to maintain the connection opened, the subscription should be closed. There are two ways to stop a subscription, either "close" it, or "unsubscribe" it. For non durable subscriptions, this is equivalent since the subscription will be completely removed. For durable subscriptions, close means that the server will stop delivering, but remember the durable subscription. Unsubscribe, however, means that the server will remove the state of this subscription. To simply close: + ```go err := sub.Close() ``` To unsubscribe: + ```go err := sub.Unsubscribe() ``` _Note: If a connection is closed without explicitly closing the subscriptions, the subscriptions are implicitly closed, not unsubscribed._ + diff --git a/developer/streaming/README.md b/developing-with-nats-streaming/streaming.md similarity index 71% rename from developer/streaming/README.md rename to developing-with-nats-streaming/streaming.md index 161911b..bdc34dc 100644 --- a/developer/streaming/README.md +++ b/developing-with-nats-streaming/streaming.md @@ -1,68 +1,72 @@ -# NATS Streaming +# Introduction ## Deciding to Use At-Least-Once Delivery -The decision to use the at least once delivery through NATS streaming is -important. It will affect your deployment, usage, performance, and total -cost of ownership. +The decision to use the at least once delivery through NATS streaming is important. It will affect your deployment, usage, performance, and total cost of ownership. -In modern systems applications can expose services or produce and consume data -streams. At a high level, if observability is required, applications need to -consume messages in the future, need to come consume at their own pace, or -need all messages, then at-least-once semantics (NATS streaming) makes sense. If -observation needs to be realtime and the most recent message is the most important, -the use _At-Most-Once_ delivery semantics with core NATS. +In modern systems applications can expose services or produce and consume data streams. At a high level, if observability is required, applications need to consume messages in the future, need to come consume at their own pace, or need all messages, then at-least-once semantics \(NATS streaming\) makes sense. If observation needs to be realtime and the most recent message is the most important, the use _At-Most-Once_ delivery semantics with core NATS. -Just be aware that using an a least once guarantee is the facet of messaging with the highest cost in terms of compute and storage. The NATS Maintainers highly recommend -a strategy of defaulting to core NATS using a service pattern (request/reply) -to guarantee delivery at the application level and using streaming only when necessary. This ultimately results in a more stable distributed system. Entire systems such as Cloud -Foundry have been built upon core NATS with no messaging persistence involved. +Just be aware that using an a least once guarantee is the facet of messaging with the highest cost in terms of compute and storage. The NATS Maintainers highly recommend a strategy of defaulting to core NATS using a service pattern \(request/reply\) to guarantee delivery at the application level and using streaming only when necessary. This ultimately results in a more stable distributed system. Entire systems such as Cloud Foundry have been built upon core NATS with no messaging persistence involved. ### When to use NATS Streaming NATS streaming is ideal when: * A historical record of a stream is required. This is when a replay of data -is required by a consumer. + + is required by a consumer. + * The last message produced on a stream is required for initialization and -the producer may be offline. + + the producer may be offline. + * A-priori knowledge of consumers is not available, but consumers must receive -messages. This is often a false assumption. + + messages. This is often a false assumption. + * Data producers and consumers are highly decoupled. They may be online at -different times and consumers must receive messages. + + different times and consumers must receive messages. + * The data in messages being sent have a lifespan beyond that of the -intended application lifespan. + + intended application lifespan. + * Applications need to consume data at their own pace. -Note that no assumptions should ever be made of who will receive and process -data in the future, or for what purpose. +Note that no assumptions should ever be made of who will receive and process data in the future, or for what purpose. ### When to use Core NATS -Using core NATS is ideal for the fast request path for scalable services -where there is tolerance for message loss or when applications themselves handle -message delivery guarantees. +Using core NATS is ideal for the fast request path for scalable services where there is tolerance for message loss or when applications themselves handle message delivery guarantees. These include: * Service patterns where there is a tightly coupled request/reply * A request is made, and the application handles error cases upon timeout -(resends, errors, etc). __Relying on a messaging system to resend here is -considered an anti-pattern.__ -* Where only the last message received is important and new messages will -be received frequently enough for applications to tolerate a lost message. -This might be a stock ticker stream, frequent exchange of messages in a -service control plane, or device telemetry. -* Message TTL is low, where the value of the data being transmitted degrades -or expires quickly. -* The expected consumer set for a message is available a-priori and consumers -are expected to be live. The request/reply pattern works well here or -consumers can send an application level acknowledgement. -We've found that core NATS is sufficient for most use cases. Also note -that nothing precludes the use of both core NATS and NATS streaming side -by side, leveraging the strengths of each to build a highly resilient -distributed system. + \(resends, errors, etc\). \_\_Relying on a messaging system to resend here is + + considered an anti-pattern.\_\_ +* Where only the last message received is important and new messages will + + be received frequently enough for applications to tolerate a lost message. + + This might be a stock ticker stream, frequent exchange of messages in a + + service control plane, or device telemetry. + +* Message TTL is low, where the value of the data being transmitted degrades + + or expires quickly. + +* The expected consumer set for a message is available a-priori and consumers + + are expected to be live. The request/reply pattern works well here or + + consumers can send an application level acknowledgement. + +We've found that core NATS is sufficient for most use cases. Also note that nothing precludes the use of both core NATS and NATS streaming side by side, leveraging the strengths of each to build a highly resilient distributed system. ## NATS Streaming Overview @@ -74,15 +78,15 @@ Messages to the streaming service are opaque byte arrays, just as they are with NATS streaming uses the concept of a channel to represent an ordered collection of messages. Clients send to and receive from channels instead of subjects. The subjects used by the streaming libraries and server are managed internally. Channels do not currently support wildcards. Channels aren’t raw subjects. Streaming isn’t raw NATS. The streaming libraries hide some of the differences. -Think of channels as a First In First Out (FIFO) queue. Messages are added until the configured limit is reached. Old messages can be set to expire based on configuration, making room for new messages. Subscriptions don’t affect channel content, that is, when a message is acknowledged, it is not removed from the channel. +Think of channels as a First In First Out \(FIFO\) queue. Messages are added until the configured limit is reached. Old messages can be set to expire based on configuration, making room for new messages. Subscriptions don’t affect channel content, that is, when a message is acknowledged, it is not removed from the channel. Positions in the channel are specified in multiple ways: * Sequence number - counting from 1 * Time -* Time delta (converted to time on client) +* Time delta \(converted to time on client\) -New subscriptions can also specify last received to indicate they only want new messages. Sequence numbers are persistent so when message #1 goes away, the oldest message is then message #2. If you try to go to a position before the oldest message, you will be moved to the oldest message. +New subscriptions can also specify last received to indicate they only want new messages. Sequence numbers are persistent so when message \#1 goes away, the oldest message is then message \#2. If you try to go to a position before the oldest message, you will be moved to the oldest message. ## Subscription Types @@ -111,9 +115,9 @@ Messages are sent in order, when they are available: * Send msg 1 and msg 2 * ACK 2 * Message 3 arrives at the server -* Send message 3 (since it is available) +* Send message 3 \(since it is available\) * When Ack wait expires, msg 1 is available -* Send msg 1 (1 and 3 are in flight) +* Send msg 1 \(1 and 3 are in flight\) The streaming server sends available messages in order, but 1 isn’t available until its Ack wait expires. If max in flight = 1 then only 1 message is on the wire at a time, it will be re-sent until it is acknowledged. Re-delivered messages will not come out of order in this situation. @@ -122,3 +126,4 @@ Setting max in flight to a number greater than 1 requires some thought and fores Max in flight is a per-subscription setting. In the case of queue subscribers, each client can set the value. Normally, each client will use the same value but this is not a requirement. NATS streaming uses acknowledgements on the sending side as well as the subscribing side. The streaming server acknowledges messages it receives and has persisted. A maximum in flight setting is used for publishers. No more than max in flight can be on their way to the server at one time. The library may provide various mechanisms to handle publisher ACKs. **The application must manage redelivery to the server**. + diff --git a/developer/README.md b/developing-with-nats/developer.md similarity index 81% rename from developer/README.md rename to developing-with-nats/developer.md index 0e9f3e5..69e6280 100644 --- a/developer/README.md +++ b/developing-with-nats/developer.md @@ -1,13 +1,14 @@ -# Developing with NATS +# Introduction Developing with NATS is a combination of distributed application techniques, common NATS features and library specific syntax. As well as using this book for guidance, some of the libraries contain language-familiar formats of their API. For example, the Go library has godoc, and the Java library has javadoc. | Library | Doc Link | -| ------------- | ------------- | +| :--- | :--- | | [nats.go](https://github.com/nats-io/nats.go) | [godoc](http://godoc.org/github.com/nats-io/nats.go) | -| [nats.java](https://github.com/nats-io/nats.java) | [javadoc](https://javadoc.io/doc/io.nats/jnats) | +| [nats.java](https://github.com/nats-io/nats.java) | [javadoc](https://javadoc.io/doc/io.nats/jnats) | | [nats.net](https://github.com/nats-io/nats.net) | [doxygen](http://nats-io.github.io/nats.net/) | | [nats.rb](https://github.com/nats-io/nats.rb) | [yard](https://www.rubydoc.info/gems/nats) | | [nats.ts](https://github.com/nats-io/nats.ts) | [ts-doc](https://nats-io.github.io/nats.ts) | -Not all libraries contain this separate doc, depending on the language community, but be sure to check out the client libraries README for more information. \ No newline at end of file +Not all libraries contain this separate doc, depending on the language community, but be sure to check out the client libraries README for more information. + diff --git a/developer/reconnect/intro.md b/developing-with-nats/intro-1/README.md similarity index 97% rename from developer/reconnect/intro.md rename to developing-with-nats/intro-1/README.md index 7f8964f..de13b62 100644 --- a/developer/reconnect/intro.md +++ b/developing-with-nats/intro-1/README.md @@ -1,7 +1,8 @@ -# Reconnecting +# Automatic Reconnections Most, if not all, of the client libraries will reconnect to the NATS system if they are disconnected for any reason. The reconnect logic can differ by library, so check your client library's documentation. In general, the client will try to connect to all of the servers it knows about, either through the URLs provided in the `connect` call or the URLs provided by the NATS system itself. The NATS system will inform clients of new endpoints that can be used to reconnect. The library may have several options to help control reconnect behavior. The list of servers used during reconnect is library dependent, but generally is constructed from connect function/options and the list of servers provided by the NATS system itself. This feature allows NATS applications and the NATS system itself to self heal and reconfigure itself with no additional configuration or intervention. + diff --git a/developer/reconnect/buffer.md b/developing-with-nats/intro-1/buffer.md similarity index 87% rename from developer/reconnect/buffer.md rename to developing-with-nats/intro-1/buffer.md index 70230db..62b460a 100644 --- a/developer/reconnect/buffer.md +++ b/developing-with-nats/intro-1/buffer.md @@ -8,6 +8,7 @@ Be aware, while the message appears to be sent to the application it is possible For clients that support this feature, you are able to configure the size of this buffer with bytes, messages or both. -!INCLUDE "../../_examples/reconnect_5mb.html" +!INCLUDE "../../\_examples/reconnect\_5mb.html" + +> _As mentioned throughout this document, each client library may behave slightly differently. Please check the documentation for the library you are using._ -> *As mentioned throughout this document, each client library may behave slightly differently. Please check the documentation for the library you are using.* diff --git a/developing-with-nats/intro-1/disable.md b/developing-with-nats/intro-1/disable.md new file mode 100644 index 0000000..4665723 --- /dev/null +++ b/developing-with-nats/intro-1/disable.md @@ -0,0 +1,6 @@ +# Disabling Reconnect + +You can disable automatic reconnect with connection options: + +!INCLUDE "../../\_examples/reconnect\_none.html" + diff --git a/developer/reconnect/events.md b/developing-with-nats/intro-1/events.md similarity index 83% rename from developer/reconnect/events.md rename to developing-with-nats/intro-1/events.md index 5d1b701..b0c268d 100644 --- a/developer/reconnect/events.md +++ b/developing-with-nats/intro-1/events.md @@ -2,4 +2,5 @@ Because reconnect is primarily under the covers many libraries provide an event listener you can use to be notified of reconnect events. This event can be especially important for applications sending a lot of messages. -!INCLUDE "../../_examples/reconnect_event.html" \ No newline at end of file +!INCLUDE "../../\_examples/reconnect\_event.html" + diff --git a/developer/reconnect/max.md b/developing-with-nats/intro-1/max.md similarity index 90% rename from developer/reconnect/max.md rename to developing-with-nats/intro-1/max.md index 6259215..6828ee9 100644 --- a/developer/reconnect/max.md +++ b/developing-with-nats/intro-1/max.md @@ -2,4 +2,5 @@ Applications can set the maximum reconnect attempts. Generally, this will limit the actual number of attempts total, but check your library documentation. For example, in Java, if the client knows about 3 servers and the maximum reconnects is set to 2, it will not try all of the servers. On the other hand, if the maximum is set to 6 it will try all of the servers twice before considering the reconnect a failure and closing. -!INCLUDE "../../_examples/reconnect_10x.html" \ No newline at end of file +!INCLUDE "../../\_examples/reconnect\_10x.html" + diff --git a/developer/reconnect/random.md b/developing-with-nats/intro-1/random.md similarity index 84% rename from developer/reconnect/random.md rename to developing-with-nats/intro-1/random.md index 9452256..6d67ff1 100644 --- a/developer/reconnect/random.md +++ b/developing-with-nats/intro-1/random.md @@ -1,7 +1,8 @@ # Avoiding the Thundering Herd -When a server goes down, there is a possible anti-pattern called the *Thundering Herd* where all of the clients try to reconnect immediately, thus creating a denial of service attack. In order to prevent this, most NATS client libraries randomize the servers they attempt to connect to. This setting has no effect if only a single server is used, but in the case of a cluster, randomization, or shuffling, will ensure that no one server bears the brunt of the client reconnect attempts. +When a server goes down, there is a possible anti-pattern called the _Thundering Herd_ where all of the clients try to reconnect immediately, thus creating a denial of service attack. In order to prevent this, most NATS client libraries randomize the servers they attempt to connect to. This setting has no effect if only a single server is used, but in the case of a cluster, randomization, or shuffling, will ensure that no one server bears the brunt of the client reconnect attempts. However, if you want to disable the randomization process, so that servers are always checked in the same order, you can do that in most libraries with a connection options: -!INCLUDE "../../_examples/reconnect_no_random.html" +!INCLUDE "../../\_examples/reconnect\_no\_random.html" + diff --git a/developer/reconnect/wait.md b/developing-with-nats/intro-1/wait.md similarity index 94% rename from developer/reconnect/wait.md rename to developing-with-nats/intro-1/wait.md index 5aaee1a..57830ba 100644 --- a/developer/reconnect/wait.md +++ b/developing-with-nats/intro-1/wait.md @@ -2,4 +2,5 @@ It doesn’t make much sense to try to connect to the same server over and over. To prevent this sort of thrashing, and wasted reconnect attempts, libraries provide a wait setting. This setting will pause the reconnect logic if the same server is being tried multiple times **in a row**. In the previous example, if you have 3 servers and 6 attempts, the Java library would loop over the three servers. If none were connectable, it will then try all three again. However, the Java client doesn’t wait between each attempt, only when trying the same server again, so in that example the library may never wait. If on the other hand, you only provide a single server URL and 6 attempts, the library will wait between each attempt. -!INCLUDE "../../_examples/reconnect_10s.html" \ No newline at end of file +!INCLUDE "../../\_examples/reconnect\_10s.html" + diff --git a/developer/security/intro.md b/developing-with-nats/intro-2/README.md similarity index 99% rename from developer/security/intro.md rename to developing-with-nats/intro-2/README.md index 526850a..0ec5572 100644 --- a/developer/security/intro.md +++ b/developing-with-nats/intro-2/README.md @@ -3,3 +3,4 @@ NATS provides several forms of security, authentication, authorization and isolation. You can turn on authentication which limits access to the NATS system. Accounts allow for isolation of a subject space and groups of applications. Authorization can be used to limit individual users access to specific subjects for publish and subscribe operations. TLS can be used to encrypt all traffic between clients and the NATS system. Finally, TLS can be used to verify client identities using client certificates. By combining all of these methods you can protect access to the system and to all message flows. The client doesn't have control over access controls, but clients do provide the configurations required to authenticate with the system, bind to an account, and to require TLS. + diff --git a/developer/security/creds.md b/developing-with-nats/intro-2/creds.md similarity index 94% rename from developer/security/creds.md rename to developing-with-nats/intro-2/creds.md index aa46b88..0733f01 100644 --- a/developer/security/creds.md +++ b/developing-with-nats/intro-2/creds.md @@ -1,8 +1,8 @@ -# Authenticating with User Credentials File +# Authenticating with a Credentials File The 2.0 version of NATS server introduced the idea of JWT-based authentication. Clients interact with this new scheme using a user JWT and the private key from an NKey pair. To help make connecting with a JWT easier, the client libraries support the concept of a credentials file. This file contains both the private key and the JWT and can be generated with the `nsc` tool. The contents will look like the following and should be protected because it contains a private key. This creds file is unused and only for example purposes. -```ascii +```text -----BEGIN NATS USER JWT----- eyJ0eXAiOiJqd3QiLCJhbGciOiJlZDI1NTE5In0.eyJqdGkiOiJUVlNNTEtTWkJBN01VWDNYQUxNUVQzTjRISUw1UkZGQU9YNUtaUFhEU0oyWlAzNkVMNVJBIiwiaWF0IjoxNTU4MDQ1NTYyLCJpc3MiOiJBQlZTQk0zVTQ1REdZRVVFQ0tYUVM3QkVOSFdHN0tGUVVEUlRFSEFKQVNPUlBWV0JaNEhPSUtDSCIsIm5hbWUiOiJvbWVnYSIsInN1YiI6IlVEWEIyVk1MWFBBU0FKN1pEVEtZTlE3UU9DRldTR0I0Rk9NWVFRMjVIUVdTQUY3WlFKRUJTUVNXIiwidHlwZSI6InVzZXIiLCJuYXRzIjp7InB1YiI6e30sInN1YiI6e319fQ.6TQ2ilCDb6m2ZDiJuj_D_OePGXFyN3Ap2DEm3ipcU5AhrWrNvneJryWrpgi_yuVWKo1UoD5s8bxlmwypWVGFAA ------END NATS USER JWT------ @@ -20,4 +20,5 @@ SUAOY5JZ2WJKVR4UO2KJ2P3SW6FZFNWEOIMAXF4WZEUNVQXXUOKGM55CYE Given a creds file, a client can authenticate as a specific user belonging to a specific account: -!INCLUDE "../../_examples/connect_creds.html" \ No newline at end of file +!INCLUDE "../../\_examples/connect\_creds.html" + diff --git a/developer/security/nkey.md b/developing-with-nats/intro-2/nkey.md similarity index 94% rename from developer/security/nkey.md rename to developing-with-nats/intro-2/nkey.md index fc1b09f..f122882 100644 --- a/developer/security/nkey.md +++ b/developing-with-nats/intro-2/nkey.md @@ -4,4 +4,5 @@ The 2.0 version of NATS server introduces a new challenge response authenticatio Handling challenge response may require more than just a setting in the connection options, depending on the client library. -!INCLUDE "../../_examples/connect_nkey.html" +!INCLUDE "../../\_examples/connect\_nkey.html" + diff --git a/developer/security/tls.md b/developing-with-nats/intro-2/tls.md similarity index 88% rename from developer/security/tls.md rename to developing-with-nats/intro-2/tls.md index e71ca9f..7eafedd 100644 --- a/developer/security/tls.md +++ b/developing-with-nats/intro-2/tls.md @@ -4,7 +4,7 @@ While authentication limits which clients can connect, TLS can be used to check The [Java examples repository](https://github.com/nats-io/java-nats-examples/tree/master/src/main/resources) contains certificates for starting the server in TLS mode. -```sh +```bash > nats-server -c /src/main/resources/tls.conf or > nats-server -c /src/main/resources/tls_verify.conf @@ -12,13 +12,13 @@ The [Java examples repository](https://github.com/nats-io/java-nats-examples/tre ## Connecting with TLS -Connecting to a server with TLS is straightforward. Most clients will automatically use TLS when connected to a NATS system using TLS. Setting up a NATS system to use TLS is primarily an exercise in setting up the certificate and trust managers. -Clients may also need additional information, for example: +Connecting to a server with TLS is straightforward. Most clients will automatically use TLS when connected to a NATS system using TLS. Setting up a NATS system to use TLS is primarily an exercise in setting up the certificate and trust managers. Clients may also need additional information, for example: -!INCLUDE "../../_examples/connect_tls.html" +!INCLUDE "../../\_examples/connect\_tls.html" ## Connecting with the TLS Protocol Some clients may support the `tls` protocol as well as a manual setting to turn on TLS. However, in that case there is likely some form of default or environmental settings to allow the TLS libraries to find certificate and trust stores. -!INCLUDE "../../_examples/connect_tls_url.html" +!INCLUDE "../../\_examples/connect\_tls\_url.html" + diff --git a/developer/security/token.md b/developing-with-nats/intro-2/token.md similarity index 87% rename from developer/security/token.md rename to developing-with-nats/intro-2/token.md index fc6acc7..b6b6824 100644 --- a/developer/security/token.md +++ b/developing-with-nats/intro-2/token.md @@ -1,11 +1,10 @@ - # Authenticating with a Token Tokens are basically random strings, much like a password, and can provide a simple authentication mechanism in some situations. However, tokens are only as safe as they are secret so other authentication schemes can provide more security in large installations. For this example, start the server using: -```sh +```bash > nats-server --auth mytoken ``` @@ -13,7 +12,7 @@ The code uses localhost:4222 so that you can start the server on your machine to ## Connecting with a Token -!INCLUDE "../../_examples/connect_token.html" +!INCLUDE "../../\_examples/connect\_token.html" ## Connecting with a Token in the URL @@ -23,4 +22,5 @@ Some client libraries will allow you to pass the token as part of the server URL Again, once you construct this URL you can connect as if this was a normal URL. -!INCLUDE "../../_examples/connect_token_url.html" \ No newline at end of file +!INCLUDE "../../\_examples/connect\_token\_url.html" + diff --git a/developer/security/userpass.md b/developing-with-nats/intro-2/userpass.md similarity index 89% rename from developer/security/userpass.md rename to developing-with-nats/intro-2/userpass.md index 1e14c8f..bfe8ad5 100644 --- a/developer/security/userpass.md +++ b/developing-with-nats/intro-2/userpass.md @@ -2,13 +2,13 @@ For this example, start the server using: -```sh +```bash > nats-server --user myname --pass password ``` You can encrypt passwords to pass to `nats-server` using a simple tool provided by the server: -```sh +```bash > go run mkpasswd.go -p > password: password > bcrypt hash: $2a$11$1oJy/wZYNTxr9jNwMNwS3eUGhBpHT3On8CL9o7ey89mpgo88VG6ba @@ -22,7 +22,7 @@ The code uses localhost:4222 so that you can start the server on your machine to When logging in with a password `nats-server` will take either a plain text password or an encrypted password. -!INCLUDE "../../_examples/connect_userpass.html" +!INCLUDE "../../\_examples/connect\_userpass.html" ## Connecting with a User/Password in the URL @@ -32,4 +32,5 @@ Most clients make it easy to pass the user name and password by accepting them i Using this format, you can connect to a server using authentication as easily as you connected with a URL: -!INCLUDE "../../_examples/connect_userpass_url.html" \ No newline at end of file +!INCLUDE "../../\_examples/connect\_userpass\_url.html" + diff --git a/developer/receiving/intro.md b/developing-with-nats/intro-3/README.md similarity index 99% rename from developer/receiving/intro.md rename to developing-with-nats/intro-3/README.md index 8c37158..9582fb5 100644 --- a/developer/receiving/intro.md +++ b/developing-with-nats/intro-3/README.md @@ -6,4 +6,5 @@ Some languages, like Go or Java, provide synchronous and asynchronous APIs, whil In all cases, the process of subscribing involves having the client library tell the NATS system that an application is interested in a particular subject. -Under the covers, the client library will assign a unique id to each subscription. This id is used as a closure when the server sends messages to a specific subscription. Each subscription gets a unique id, so if the same connection is used multiple times for the same subject, the server will send multiple copies of the same message. When an application is done with a subscription it unsubscribes which tells the server to stop sending messages. \ No newline at end of file +Under the covers, the client library will assign a unique id to each subscription. This id is used as a closure when the server sends messages to a specific subscription. Each subscription gets a unique id, so if the same connection is used multiple times for the same subject, the server will send multiple copies of the same message. When an application is done with a subscription it unsubscribes which tells the server to stop sending messages. + diff --git a/developer/receiving/async.md b/developing-with-nats/intro-3/async.md similarity index 90% rename from developer/receiving/async.md rename to developing-with-nats/intro-3/async.md index 005fb18..c9545d9 100644 --- a/developer/receiving/async.md +++ b/developing-with-nats/intro-3/async.md @@ -4,4 +4,5 @@ Asynchronous subscriptions use callbacks of some form to notify an application w The following example subscribes to the subject `updates` and handles the incoming messages: -!INCLUDE "../../_examples/subscribe_async.html" \ No newline at end of file +!INCLUDE "../../\_examples/subscribe\_async.html" + diff --git a/developer/receiving/drain.md b/developing-with-nats/intro-3/drain.md similarity index 80% rename from developer/receiving/drain.md rename to developing-with-nats/intro-3/drain.md index 49b5404..d748436 100644 --- a/developer/receiving/drain.md +++ b/developing-with-nats/intro-3/drain.md @@ -1,4 +1,4 @@ -# Draining Connections and Subscriptions +# Draining Messages Before Disconnect A feature recently added across the NATS client libraries is the ability to drain connections or subscriptions. Closing a connection, or unsubscribing from a subscription, are generally considered immediate requests. When you close or unsubscribe the library will halt messages in any pending queue or cache for subscribers. When you drain a subscription or connection, it will process any inflight and cached/pending messages before closing. @@ -8,25 +8,26 @@ The libraries can provide drain on a connection or on a subscriber, or both. For a connection the process is essentially: - 1. Drain all subscriptions - 2. Stop new messages from being published - 3. Flush any remaining published messages - 4. Close +1. Drain all subscriptions +2. Stop new messages from being published +3. Flush any remaining published messages +4. Close The API for drain can generally be used instead of close: As an example of draining a connection: -!INCLUDE "../../_examples/drain_conn.html" +!INCLUDE "../../\_examples/drain\_conn.html" The mechanics of drain for a subscription are simpler: - 1. Unsubscribe - 2. Process all cached or inflight messages - 3. Clean up +1. Unsubscribe +2. Process all cached or inflight messages +3. Clean up The API for drain can generally be used instead of unsubscribe: -!INCLUDE "../../_examples/drain_sub.html" +!INCLUDE "../../\_examples/drain\_sub.html" Because draining can involve messages flowing to the server, for a flush and asynchronous message processing, the timeout for drain should generally be higher than the timeout for a simple message request/reply or similar. + diff --git a/developer/receiving/queues.md b/developing-with-nats/intro-3/queues.md similarity index 90% rename from developer/receiving/queues.md rename to developing-with-nats/intro-3/queues.md index 029bdec..9e0db62 100644 --- a/developer/receiving/queues.md +++ b/developing-with-nats/intro-3/queues.md @@ -4,10 +4,11 @@ Subscribing to a queue group is only slightly different than subscribing to a su Keep in mind that the queue groups in NATS are dynamic and do not require any server configuration. You can almost think of a regular subscription as a queue group of 1, but it is probably not worth thinking too much about that. -![](/assets/images/queues.svg) +![](../../.gitbook/assets/queues.svg) As an example, to subscribe to the queue `workers` with the subject `updates`: -!INCLUDE "../../_examples/subscribe_queue.html" +!INCLUDE "../../\_examples/subscribe\_queue.html" If you run this example with the publish examples that send to `updates`, you will see that one of the instances gets a message while the others you run won't. But the instance that receives the message will change. + diff --git a/developer/receiving/reply.md b/developing-with-nats/intro-3/reply.md similarity index 81% rename from developer/receiving/reply.md rename to developing-with-nats/intro-3/reply.md index 66925d7..82b0009 100644 --- a/developer/receiving/reply.md +++ b/developing-with-nats/intro-3/reply.md @@ -4,4 +4,5 @@ Incoming messages have an optional reply-to field. If that field is set, it will For example, the following code will listen for that request and respond with the time. -!INCLUDE "../../_examples/subscribe_w_reply.html" \ No newline at end of file +!INCLUDE "../../\_examples/subscribe\_w\_reply.html" + diff --git a/developer/receiving/structure.md b/developing-with-nats/intro-3/structure.md similarity index 84% rename from developer/receiving/structure.md rename to developing-with-nats/intro-3/structure.md index d36aab4..dbda8c9 100644 --- a/developer/receiving/structure.md +++ b/developing-with-nats/intro-3/structure.md @@ -1,7 +1,8 @@ -# Receiving Structured Data +# Structured Data Client libraries may provide tools to help receive structured data, like JSON. The core traffic to the NATS server will always be opaque byte arrays. The server does not process message payloads in any form. For libraries that don't provide helpers, you can always encode and decode data before sending the associated bytes to the NATS client. For example, to receive JSON you could do: -!INCLUDE "../../_examples/subscribe_json.html" \ No newline at end of file +!INCLUDE "../../\_examples/subscribe\_json.html" + diff --git a/developer/receiving/sync.md b/developing-with-nats/intro-3/sync.md similarity index 90% rename from developer/receiving/sync.md rename to developing-with-nats/intro-3/sync.md index 192de90..4d1e267 100644 --- a/developer/receiving/sync.md +++ b/developing-with-nats/intro-3/sync.md @@ -1,8 +1,8 @@ - # Synchronous Subscriptions Synchronous subscriptions require the application to wait for messages. This type of subscription is easy to set-up and use, but requires the application to deal with looping if multiple messages are expected. For situations where a single message is expected, synchronous subscriptions are sometimes easier to manage, depending on the language. For example, to subscribe to the subject `updates` and receive a single message you could do: -!INCLUDE "../../_examples/subscribe_sync.html" \ No newline at end of file +!INCLUDE "../../\_examples/subscribe\_sync.html" + diff --git a/developer/receiving/unsub_after.md b/developing-with-nats/intro-3/unsub_after.md similarity index 93% rename from developer/receiving/unsub_after.md rename to developing-with-nats/intro-3/unsub_after.md index c5b1aa2..6737db6 100644 --- a/developer/receiving/unsub_after.md +++ b/developing-with-nats/intro-3/unsub_after.md @@ -1,4 +1,4 @@ -# Unsubscribing After a Specified Number of Messages +# Unsubscribing After N Messages NATS provides a special form of unsubscribe that is configured with a message count and takes effect when that many messages are sent to a subscriber. This mechanism is very useful if only a single message is expected. @@ -12,4 +12,5 @@ Finally, most of the client libraries also track the max message count after an The following example shows unsubscribe after a single message: -!INCLUDE "../../_examples/unsubscribe_auto.html" \ No newline at end of file +!INCLUDE "../../\_examples/unsubscribe\_auto.html" + diff --git a/developer/receiving/unsubscribing.md b/developing-with-nats/intro-3/unsubscribing.md similarity index 90% rename from developer/receiving/unsubscribing.md rename to developing-with-nats/intro-3/unsubscribing.md index 950bf00..578599d 100644 --- a/developer/receiving/unsubscribing.md +++ b/developing-with-nats/intro-3/unsubscribing.md @@ -4,4 +4,5 @@ The client libraries provide a means to unsubscribe a previous subscription requ This process requires an interaction with the server, so for an asynchronous subscription there may be a small window of time where a message comes through as the unsubscribe is processed by the library. Ignoring that slight edge case, the client library will clean up any outstanding messages and tell the server that the subscription is no longer used. -!INCLUDE "../../_examples/unsubscribe.html" \ No newline at end of file +!INCLUDE "../../\_examples/unsubscribe.html" + diff --git a/developer/receiving/wildcards.md b/developing-with-nats/intro-3/wildcards.md similarity index 80% rename from developer/receiving/wildcards.md rename to developing-with-nats/intro-3/wildcards.md index 8cf0e36..e483354 100644 --- a/developer/receiving/wildcards.md +++ b/developing-with-nats/intro-3/wildcards.md @@ -1,4 +1,4 @@ -# Wildcards +# Wildcard Subscriptions There is no special code to subscribe with a wildcard subject. Wildcards are a normal part of the subject name. @@ -6,12 +6,13 @@ However, there is a common technique that may come in to play when you use wildc For example, you can subscribe using `*` and then act based on the actual subject. -!INCLUDE "../../_examples/subscribe_star.html" +!INCLUDE "../../\_examples/subscribe\_star.html" or do something similar with `>`: -!INCLUDE "../../_examples/subscribe_arrow.html" +!INCLUDE "../../\_examples/subscribe\_arrow.html" The following example can be used to test these two subscribers. The `*` subscriber should receive at most 2 messages, while the `>` subscriber receives 4. More importantly the `time.*.east` subscriber won't receive on `time.us.east.atlanta` because that won't match. -!INCLUDE "../../_examples/wildcard_tester.html" \ No newline at end of file +!INCLUDE "../../\_examples/wildcard\_tester.html" + diff --git a/developer/sending/intro.md b/developing-with-nats/intro-4/README.md similarity index 90% rename from developer/sending/intro.md rename to developing-with-nats/intro-4/README.md index 622ccf5..70bc43b 100644 --- a/developer/sending/intro.md +++ b/developing-with-nats/intro-4/README.md @@ -4,4 +4,5 @@ NATS sends and receives messages using a protocol that includes a target subject All of the NATS clients are designed to make sending a message simple. For example, to send the string “All is Well” to the “updates” subject as a UTF-8 string of bytes you would do: -!INCLUDE "../../_examples/publish_bytes.html" \ No newline at end of file +!INCLUDE "../../\_examples/publish\_bytes.html" + diff --git a/developer/sending/caches.md b/developing-with-nats/intro-4/caches.md similarity index 94% rename from developer/sending/caches.md rename to developing-with-nats/intro-4/caches.md index 2926838..538ae7c 100644 --- a/developer/sending/caches.md +++ b/developing-with-nats/intro-4/caches.md @@ -6,8 +6,9 @@ These buffers do not hold messages forever, generally they are designed to hold It is the libraries job to make sure messages flow in a high performance manner. But there may be times when an application needs to know that a message has "hit the wire." In this case, applications can use a flush call to tell the library to move data through the system. -!INCLUDE "../../_examples/flush.html" +!INCLUDE "../../\_examples/flush.html" ## Flush and Ping/Pong -Many of the client libraries use the PING/PONG interaction built into the NATS protocol to insure that flush pushed all of the cached messages to the server. When an application calls flush most libraries will put a PING on the outgoing queue of messages, and wait for the server to send PONG before saying that the flush was successful. \ No newline at end of file +Many of the client libraries use the PING/PONG interaction built into the NATS protocol to insure that flush pushed all of the cached messages to the server. When an application calls flush most libraries will put a PING on the outgoing queue of messages, and wait for the server to send PONG before saying that the flush was successful. + diff --git a/developer/sending/replyto.md b/developing-with-nats/intro-4/replyto.md similarity index 88% rename from developer/sending/replyto.md rename to developing-with-nats/intro-4/replyto.md index ee0d093..5058ac6 100644 --- a/developer/sending/replyto.md +++ b/developing-with-nats/intro-4/replyto.md @@ -2,4 +2,5 @@ The optional reply-to field when publishing a message can be used on the receiving side to respond. The reply-to subject is often called an _inbox_, and most libraries may provide a method for generating unique inbox subjects. Most libraries also provide for the request-reply pattern with a single call. For example to send a request to the subject `time`, with no content for the messages, you might: -!INCLUDE "../../_examples/publish_with_reply.html" \ No newline at end of file +!INCLUDE "../../\_examples/publish\_with\_reply.html" + diff --git a/developer/sending/request_reply.md b/developing-with-nats/intro-4/request_reply.md similarity index 97% rename from developer/sending/request_reply.md rename to developing-with-nats/intro-4/request_reply.md index 133f483..a18eab2 100644 --- a/developer/sending/request_reply.md +++ b/developing-with-nats/intro-4/request_reply.md @@ -1,4 +1,4 @@ -# Request-Reply +# Request-Reply Semantics The pattern of sending a message and receiving a response is encapsulated in most client libraries into a request method. Under the covers this method will publish a message with a unique reply-to subject and wait for the response before returning. @@ -8,7 +8,7 @@ The primary difference between the request method and publishing with a reply-to For example, updating the previous publish example we may request `time` with a one second timeout: -!INCLUDE "../../_examples/request_reply.html" +!INCLUDE "../../\_examples/request\_reply.html" You can think of request-reply in the library as a subscribe, get one message, unsubscribe pattern. In Go this might look something like: @@ -91,4 +91,5 @@ for time.Now().Sub(start) < max { } } sub.Unsubscribe() -``` \ No newline at end of file +``` + diff --git a/developer/sending/structure.md b/developing-with-nats/intro-4/structure.md similarity index 91% rename from developer/sending/structure.md rename to developing-with-nats/intro-4/structure.md index a229186..5e4b2a5 100644 --- a/developer/sending/structure.md +++ b/developing-with-nats/intro-4/structure.md @@ -4,4 +4,5 @@ Some client libraries provide helpers to send structured data while others depen Take a simple _stock ticker_ that sends the symbol and price of each stock: -!INCLUDE "../../_examples/publish_json.html" \ No newline at end of file +!INCLUDE "../../\_examples/publish\_json.html" + diff --git a/developer/events/intro.md b/developing-with-nats/intro-5/README.md similarity index 85% rename from developer/events/intro.md rename to developing-with-nats/intro-5/README.md index c652766..7e111e6 100644 --- a/developer/events/intro.md +++ b/developing-with-nats/intro-5/README.md @@ -4,4 +4,5 @@ Managing the interaction with the server is primarily the job of the client libr For example, the client library may provide a mechanism to get the connection's current status: -!INCLUDE "../../_examples/connect_status.html" \ No newline at end of file +!INCLUDE "../../\_examples/connect\_status.html" + diff --git a/developer/events/events.md b/developing-with-nats/intro-5/events.md similarity index 88% rename from developer/events/events.md rename to developing-with-nats/intro-5/events.md index eab4d3f..c46ac27 100644 --- a/developer/events/events.md +++ b/developing-with-nats/intro-5/events.md @@ -6,16 +6,17 @@ The actual API for these listeners is language dependent, but the following exam Connection events may include the connection being closed, disconnected or reconnected. Reconnecting involves a disconnect and connect, but depending on the library implementation may also include multiple disconnects as the client tries to find a server, or the server is rebooted. -!INCLUDE "../../_examples/connection_listener.html" +!INCLUDE "../../\_examples/connection\_listener.html" ## Listen for New Servers When working with a cluster, servers may be added or changed. Some of the clients allow you to listen for this notification: -!INCLUDE "../../_examples/servers_added.html" +!INCLUDE "../../\_examples/servers\_added.html" ## Listen for Errors The client library may separate server-to-client errors from events. Many server events are not handled by application code and result in the connection being closed. Listening for the errors can be very useful for debugging problems. -!INCLUDE "../../_examples/error_listener.html" \ No newline at end of file +!INCLUDE "../../\_examples/error\_listener.html" + diff --git a/developer/events/slow.md b/developing-with-nats/intro-5/slow.md similarity index 96% rename from developer/events/slow.md rename to developing-with-nats/intro-5/slow.md index a5fbf72..174787f 100644 --- a/developer/events/slow.md +++ b/developing-with-nats/intro-5/slow.md @@ -20,7 +20,7 @@ The incoming cache is usually per subscriber, but again, check the specific docu The first way that the incoming queue can be limited is by message count. The second way to limit the incoming queue is by total size. For example, to limit the incoming cache to 1,000 messages or 5mb whichever comes first: -!INCLUDE "../../_examples/slow_pending_limits.html" +!INCLUDE "../../\_examples/slow\_pending\_limits.html" ## Detect a Slow Consumer and Check for Dropped Messages @@ -28,4 +28,5 @@ When a slow consumer is detected and messages are about to be dropped, the libra Some libraries, like Java, will not send this notification on every dropped message because that could be noisy. Rather the notification may be sent once per time the subscriber gets behind. Libraries may also provide a way to get a count of dropped messages so that applications can at least detect a problem is occurring. -!INCLUDE "../../_examples/slow_listener.html" \ No newline at end of file +!INCLUDE "../../\_examples/slow\_listener.html" + diff --git a/developing-with-nats/intro-6/README.md b/developing-with-nats/intro-6/README.md new file mode 100644 index 0000000..3b68f6e --- /dev/null +++ b/developing-with-nats/intro-6/README.md @@ -0,0 +1,9 @@ +# Tutorials + +Tutorials are provided to give guidance on commonly used aspects of NATS. + +* [Explore NATS Publish/Subscribe](pubsub.md) +* [Explore NATS Request/Reply](reqreply.md) +* [Explore NATS Queueing](queues.md) +* [Advanced Connect and Custom Dialer in Go](custom_dialer.md) + diff --git a/developer/tutorials/custom_dialer.md b/developing-with-nats/intro-6/custom_dialer.md similarity index 88% rename from developer/tutorials/custom_dialer.md rename to developing-with-nats/intro-6/custom_dialer.md index 590f93f..73d3ea2 100644 --- a/developer/tutorials/custom_dialer.md +++ b/developing-with-nats/intro-6/custom_dialer.md @@ -1,10 +1,6 @@ # Advanced Connect and Custom Dialer in Go -The Go NATS client features a [CustomDialer](https://godoc.org/github.com/nats-io/go-nats#CustomDialer) option which allows you to customize -the connection logic against the NATS server without having to modify the internals -of the client. For example, let's say that you want to make the client use the `context` -package to use `DialContext` and be able to cancel connecting to NATS altogether with a deadline, -you could then do define a Dialer implementation as follows: +The Go NATS client features a [CustomDialer](https://godoc.org/github.com/nats-io/go-nats#CustomDialer) option which allows you to customize the connection logic against the NATS server without having to modify the internals of the client. For example, let's say that you want to make the client use the `context` package to use `DialContext` and be able to cancel connecting to NATS altogether with a deadline, you could then do define a Dialer implementation as follows: ```go package main @@ -51,8 +47,7 @@ func (cd *customDialer) Dial(network, address string) (net.Conn, error) { } ``` -With the dialer implementation above, the NATS client will retry a number of times to connect -to the NATS server until the context is no longer valid: +With the dialer implementation above, the NATS client will retry a number of times to connect to the NATS server until the context is no longer valid: ```go func main() { @@ -130,3 +125,4 @@ WaitForEstablishedConnection: log.Println("Disconnected") } ``` + diff --git a/developer/tutorials/pubsub.md b/developing-with-nats/intro-6/pubsub.md similarity index 84% rename from developer/tutorials/pubsub.md rename to developing-with-nats/intro-6/pubsub.md index 5930eeb..d4c6790 100644 --- a/developer/tutorials/pubsub.md +++ b/developing-with-nats/intro-6/pubsub.md @@ -1,8 +1,8 @@ # Explore NATS Pub/Sub -NATS is a publish subscribe messaging system. Subscribers listening on a subject receive messages on that subject. If the subscriber is not actively listening on the subject, the message is not received. Subscribers can use the wildcard tokens such as `*` and `>` to match a single token or to match the tail of a subject. +NATS is a publish subscribe messaging system. Subscribers listening on a subject receive messages on that subject. If the subscriber is not actively listening on the subject, the message is not received. Subscribers can use the wildcard tokens such as `*` and `>` to match a single token or to match the tail of a subject. -![](/assets/images/pubsubtut.svg) +![](../../.gitbook/assets/pubsubtut.svg) ## Prerequisites @@ -10,13 +10,13 @@ Go and the NATS server should be installed. Optionally you can use the demo serv ### 1. Start the NATS server -```sh +```bash % nats-server ``` When the server starts successfully, you will see the following messages: -```sh +```bash [1] 2019/31/05 15:18:22.301550 [INF] Starting nats-server version 2.0.0 [1] 2019/31/05 15:18:22.301762 [INF] Listening for client connections on 0.0.0.0:4222 [1] 2019/31/05 15:18:22.301769 [INF] nats-server is ready @@ -30,13 +30,13 @@ You will use this session to run an example NATS client subscriber program. ### 3. CD to the Go client examples directory -```sh +```bash % cd $GOPATH/src/github.com/nats-io/nats.go/examples ``` ### 4. Run the client subscriber program -```sh +```bash % go run nats-sub/main.go ``` @@ -44,11 +44,11 @@ Where `` is a subject to listen on. A valid subject is a string that is For example: -```sh +```bash % go run nats-sub/main.go msg.test ``` -You should see the message: *Listening on [msg.test]* +You should see the message: _Listening on \[msg.test\]_ ### 5. Start another shell or command prompt session @@ -56,13 +56,13 @@ You will use this session to run a NATS publisher client. ## 6. CD to the examples directory -```sh +```bash % cd $GOPATH/src/github.com/nats-io/nats.go/examples ``` ### 7. Publish a NATS message -```sh +```bash % go run nats-pub/main.go ``` @@ -70,27 +70,27 @@ Where `` is the subject name and `` is the text to publish. For example: -```sh +```bash % go run nats-pub/main.go msg.test hello ``` or -```sh +```bash % go run nats-pub/main.go msg.test "NATS MESSAGE" ``` ### 8. Verify message publication and receipt -You should see that the publisher sends the message: *Published [msg.test] : 'NATS MESSAGE'* +You should see that the publisher sends the message: _Published \[msg.test\] : 'NATS MESSAGE'_ -And that the subscriber receives the message: *[#1] Received on [msg.test]: 'NATS MESSAGE'* +And that the subscriber receives the message: _\[\#1\] Received on \[msg.test\]: 'NATS MESSAGE'_ Note that if the receiver does not get the message, check that you are using the same subject name for the publisher and the subscriber. ### 9. Publish another message -```sh +```bash % go run nats-pub/main.go msg.test "NATS MESSAGE 2" ``` @@ -102,19 +102,19 @@ You will use this session to run a second NATS subscriber. ### 11. CD to the examples directory -```sh +```bash % cd $GOPATH/src/github.com/nats-io/nats.go/examples ``` ### 12. Subscribe to the message -```sh +```bash % go run nats-sub/main.go msg.test ``` ### 13. Publish another message using the publisher client -```sh +```bash % go run nats-pub/main.go msg.test "NATS MESSAGE 3" ``` @@ -126,13 +126,13 @@ You will use this session to run a third NATS subscriber. ### 15. CD to the examples directory -```sh +```bash % cd $GOPATH/src/github.com/nats-io/nats.go/examples ``` ### 16. Subscribe to a different message -```sh +```bash % go run nats-sub/main.go msg.test.new ``` @@ -142,12 +142,13 @@ All the but last subscriber receives the message. Why? Because that subscriber i NATS supports the use of wildcard characters for message subscribers. You cannot publish a message using a wildcard subject. -Change the last subscriber the listen on msg.* and run it: +Change the last subscriber the listen on msg.\* and run it: -```sh +```bash % go run nats-sub/main.go msg.* ``` ### 18. Publish another message This time, all three subscribing clients should receive the message. + diff --git a/developer/tutorials/queues.md b/developing-with-nats/intro-6/queues.md similarity index 88% rename from developer/tutorials/queues.md rename to developing-with-nats/intro-6/queues.md index 215ed21..6a3170b 100644 --- a/developer/tutorials/queues.md +++ b/developing-with-nats/intro-6/queues.md @@ -8,13 +8,13 @@ Go and the NATS server should be installed. ### 1. Start the NATS server -```sh +```bash nats-server ``` ### 2. Clone the repositories for each client examples -```sh +```bash go get github.com/nats-io/nats.go git clone https://github.com/nats-io/nats.js.git git clone https://github.com/nats-io/nats.rb.git @@ -22,14 +22,14 @@ git clone https://github.com/nats-io/nats.rb.git ### 3. Run the Go client subscriber with queue group name -```sh +```bash cd $GOPATH/src/github.com/nats-io/nats.go/examples go run nats-qsub/main.go foo my-queue ``` ### 4. Install and run the Node client subscriber with queue group name -```sh +```bash npm install nats cd nats.js/examples node node-sub --queue=my-queue foo @@ -37,35 +37,36 @@ node node-sub --queue=my-queue foo ### 5. Install and run the Ruby client subscriber with queue group name -```sh +```bash gem install nats nats-queue foo my-queue & ``` -### 6. Run another Go client subscriber *without* the queue group. +### 6. Run another Go client subscriber _without_ the queue group. -```sh +```bash cd $GOPATH/src/github.com/nats-io/nats.go/examples go run nats-sub/main.go foo ``` ### 7. Publish a NATS message using the Go client -```sh +```bash cd $GOPATH/src/github.com/nats-io/nats.go/examples go run nats-pub/main.go foo "Hello NATS!" ``` ### 8. Verify message publication and receipt -You should see that the publisher sends the message: *Published [foo] : 'Hello NATS!'* +You should see that the publisher sends the message: _Published \[foo\] : 'Hello NATS!'_ You should see that only one of the my-queue group subscribers receives the message. In addition, the Go client subscriber not in the my-queue group should also receive the message. ### 9. Publish another message -```sh +```bash go run nats-pub/main.go foo "Hello NATS Again!" ``` You should see that a different queue group subscriber receives the message this time, chosen at random among the 3 queue group members. + diff --git a/developer/tutorials/reqreply.md b/developing-with-nats/intro-6/reqreply.md similarity index 91% rename from developer/tutorials/reqreply.md rename to developing-with-nats/intro-6/reqreply.md index 31cfe57..91f0954 100644 --- a/developer/tutorials/reqreply.md +++ b/developing-with-nats/intro-6/reqreply.md @@ -8,7 +8,7 @@ Go and the NATS server should be installed. ### 1. Start the NATS server -```sh +```bash % nats-server ``` @@ -18,13 +18,13 @@ You will use these sessions to run the NATS request and reply clients. ### 3. Change to the examples directory -```sh +```bash % cd $GOPATH/src/github.com/nats-io/nats.go/examples ``` ### 4. In one terminal, run the reply client listener -```sh +```bash % go run nats-rply/main.go foo "this is my response" ``` @@ -32,10 +32,11 @@ You should see the message `Receiver is listening`, and that the NATS receiver c ### 5. In the other terminal, run the request client -```sh +```bash % go run nats-req/main.go foo "request payload" ``` The NATS requestor client makes a request by sending the message "some message" on the “help.please” subject. -The NATS receiver client receives the message, formulates the reply ("OK, I CAN HELP!!!), and sends it to the inbox of the requester. +The NATS receiver client receives the message, formulates the reply \("OK, I CAN HELP!!!\), and sends it to the inbox of the requester. + diff --git a/developer/connecting/intro.md b/developing-with-nats/intro/README.md similarity index 97% rename from developer/connecting/intro.md rename to developing-with-nats/intro/README.md index 34576e3..f6be54d 100644 --- a/developer/connecting/intro.md +++ b/developing-with-nats/intro/README.md @@ -1,7 +1,8 @@ -# Connecting to NATS +# Connecting A NATS system is usually identified by a standard URL with the `nats` or `tls` protocol, e.g. nats://demo.nats.io. A NATS system can be a single server, a small cluster or a global super cluster. Throughout these examples we will rely on a single test server, provided by [nats.io](https://nats.io), at `nats://demo.nats.io`, where `4222` is the default port for NATS. NATS also supports secure connectivity using TLS via the `tls` protocol. Most clients support auto-detection of a secure connection using the URL protocol `tls`. There is also a demo server running TLS at `tls://demo.nats.io:4443`. The protocol requirement is being made optional for many client libraries, so that you can use `demo.nats.io:4222` as the URL and let the client and server resolve whether or not TLS is required. There are numerous options for a NATS connection ranging from timeouts to reconnect settings. + diff --git a/developing-with-nats/intro/cluster.md b/developing-with-nats/intro/cluster.md new file mode 100644 index 0000000..92dd3fc --- /dev/null +++ b/developing-with-nats/intro/cluster.md @@ -0,0 +1,114 @@ +# Connecting to a Cluster + +When connecting to a cluster, there are a few things to think about. + +* Passing a URL for each cluster member \(semi-optional\) +* The connection algorithm +* The reconnect algorithm \(discussed later\) +* Server provided URLs + +When a client library first tries to connect it will use the list of URLs provided to the connection options or function. These URLs are checked, usually in order, and the first successful connection is used. + +After a client connects to the server, the server may provide a list of URLs for additional known servers. This allows a client to connect to one server and still have other servers available during reconnect. + +To insure the initial connection, your code should include a list of reasonable _front line_ servers. Those servers may know about other members of the cluster, and may tell the client about those members. But you don't have to configure the client to pass every valid member of the cluster in the connect method. + +By providing the ability to pass multiple connect options NATS can handle the possibility of a machine going down or being unavailable to a client. By adding the ability of the server to feed clients a list of known servers as part of the client-server protocol the mesh created by a cluster can grow and change organically while the clients are running. + +_Note, failure behavior is library dependent, please check the documentation for your client library on information about what happens if the connect fails._ + +{% tabs %} +{% tab title="Go" %} +```go +servers := []string{"nats://127.0.0.1:1222", "nats://127.0.0.1:1223", "nats://127.0.0.1:1224"} + +nc, err := nats.Connect(strings.Join(servers, ",")) +if err != nil { + log.Fatal(err) +} +defer nc.Close() + +// Do something with the connection +``` +{% endtab %} + +{% tab title="Java" %} +```java +Options options = new Options.Builder(). + server("nats://localhost:1222"). + server("nats://localhost:1223"). + server("nats://localhost:1224"). + build(); +Connection nc = Nats.connect(options); + +// Do something with the connection + +nc.close(); +``` +{% endtab %} + +{% tab title="JavaScript" %} +```javascript +let nc = NATS.connect({ + servers: [ + "nats://demo.nats.io:4222", + "nats://localhost:4222" + ]} +); +nc.on('connect', (c) => { + // Do something with the connection + doSomething(); + // When done close it + nc.close(); +}); +nc.on('error', (err) => { + failed(err); +}); +``` +{% endtab %} + +{% tab title="Python" %} +```python +nc = NATS() +await nc.connect(servers=[ + "nats://127.0.0.1:1222", + "nats://127.0.0.1:1223", + "nats://127.0.0.1:1224" + ]) + +# Do something with the connection + +await nc.close() +``` +{% endtab %} + +{% tab title="Ruby" %} +```ruby +require 'nats/client' + +NATS.start(servers: ["nats://127.0.0.1:1222", "nats://127.0.0.1:1223", "nats://127.0.0.1:1224"]) do |nc| + # Do something with the connection + + # Close the connection + nc.close +end +``` +{% endtab %} + +{% tab title="TypeScript" %} +```typescript +// will throw an exception if connection fails +let nc = await connect({ + servers: [ + "nats://demo.nats.io:4222", + "nats://localhost:4222" + ] +}); +// Do something with the connection + +// When done close it +nc.close(); +``` +{% endtab %} +{% endtabs %} + diff --git a/developing-with-nats/intro/connect_timeout.md b/developing-with-nats/intro/connect_timeout.md new file mode 100644 index 0000000..13c3f28 --- /dev/null +++ b/developing-with-nats/intro/connect_timeout.md @@ -0,0 +1,73 @@ +# Setting a Connect Timeout + +Each library has its own, language preferred way, to pass connection options. One of the most common options is a connection timeout. To set the maximum time to connect to a server to 10 seconds: + +{% tabs %} +{% tab title="Go" %} +```go +nc, err := nats.Connect("demo.nats.io", nats.Name("API Options Example"), nats.Timeout(10*time.Second)) +if err != nil { + log.Fatal(err) +} +defer nc.Close() + +// Do something with the connection +``` +{% endtab %} + +{% tab title="Java" %} +```java +Options options = new Options.Builder(). + server("nats://demo.nats.io:4222"). + connectionTimeout(Duration.ofSeconds(10)). // Set timeout + build(); +Connection nc = Nats.connect(options); + +// Do something with the connection + +nc.close(); +``` +{% endtab %} + +{% tab title="JavaScript" %} + +{% endtab %} + +{% tab title="Python" %} +```python +nc = NATS() +await nc.connect(connect_timeout=2) + +# Do something with the connection + +await nc.close() +``` +{% endtab %} + +{% tab title="Ruby" %} +```ruby +# There is currently no connect timeout as part of the Ruby NATS client API, but you can use a timer to mimic it. +require 'nats/client' + +timer = EM.add_timer(5) do + NATS.connect do |nc| + # Do something with the connection + + # Close the connection + nc.close + end +end +EM.cancel_timer(timer) +``` +{% endtab %} + +{% tab title="TypeScript" %} +```typescript +let nc = await connect({ + url: "nats://demo.nats.io:4222", + timeout: 1000 +}); +``` +{% endtab %} +{% endtabs %} + diff --git a/developing-with-nats/intro/default_server.md b/developing-with-nats/intro/default_server.md new file mode 100644 index 0000000..1e88129 --- /dev/null +++ b/developing-with-nats/intro/default_server.md @@ -0,0 +1,89 @@ +# Connecting to the Default Server + +Some libraries also provide a special way to connect to a _default_ url, which is generally `nats://localhost:4222`: + +{% tabs %} +{% tab title="Go" %} +```go +nc, err := nats.Connect(nats.DefaultURL) +if err != nil { + log.Fatal(err) +} +defer nc.Close() + +// Do something with the connection +``` +{% endtab %} + +{% tab title="Java" %} +```java +Connection nc = Nats.connect(); + +// Do something with the connection + +nc.close(); +``` +{% endtab %} + +{% tab title="JavaScript" %} +```javascript +let nc = NATS.connect(); +nc.on('connect', (c) => { + // Do something with the connection + doSomething(); + // When done close it + nc.close(); +}); +nc.on('error', (err) => { + failed(err); +}); +``` +{% endtab %} + +{% tab title="Python" %} +```python +nc = NATS() +await nc.connect() + +# Do something with the connection + +await nc.close() +``` +{% endtab %} + +{% tab title="Ruby" %} +```ruby +require 'nats/client' + +NATS.start do |nc| + # Do something with the connection + + # Close the connection + nc.close +end +``` +{% endtab %} + +{% tab title="TypeScript" %} +```typescript +// will throw an exception if connection fails +let nc = await connect(); +// Do something with the connection + +// When done close it +nc.close(); + + +// alternatively, you can use the Promise pattern +let nc1: Client; +connect() + .then((c) => { + nc1 = c; + // Do something with the connection + nc1.close(); + }); + // add a .catch/.finally +``` +{% endtab %} +{% endtabs %} + diff --git a/developer/connecting/noecho.md b/developing-with-nats/intro/noecho.md similarity index 93% rename from developer/connecting/noecho.md rename to developing-with-nats/intro/noecho.md index 571d895..8871f43 100644 --- a/developer/connecting/noecho.md +++ b/developing-with-nats/intro/noecho.md @@ -4,8 +4,9 @@ By default a NATS connection will echo messages if the connection also has inter The NoEcho option can be useful in BUS patterns where all applications subscribe and publish to the same subject. Usually a publish represents a state change that the application already knows about, so in the case where the application publishes an update it does not need to process the update itself. -![](/assets/images/noecho.svg) +![](../../.gitbook/assets/noecho.svg) Keep in mind that each connection will have to turn off echo, and that it is per connection, not per application. Also, turning echo on and off can result in a major change to your applications communications protocol since messages will flow or stop flowing based on this setting and the subscribing code won't have any indication as to why. -!INCLUDE "../../_examples/no_echo.html" +!INCLUDE "../../\_examples/no\_echo.html" + diff --git a/developer/connecting/pingpong.md b/developing-with-nats/intro/pingpong.md similarity index 91% rename from developer/connecting/pingpong.md rename to developing-with-nats/intro/pingpong.md index 5076025..226a88e 100644 --- a/developer/connecting/pingpong.md +++ b/developing-with-nats/intro/pingpong.md @@ -2,13 +2,13 @@ The client and server use a simple PING/PONG protocol to check that they are both still connected. The client will ping the server on a regular, configured interval so that the server usually doesn't have to initiate the PING/PONG interaction. -![](/assets/images/pingpong.svg) +![](../../.gitbook/assets/pingpong.svg) ## Set the Ping Interval If you have a connection that is going to be open a long time with few messages traveling on it, setting this PING interval can control how quickly the client will be notified of a problem. However on connections with a lot of traffic, the client will often figure out there is a problem between PINGS, and as a result the default PING interval is often on the order of minutes. To set the interval to 20s: -!INCLUDE "../../_examples/ping_20s.html" +!INCLUDE "../../\_examples/ping\_20s.html" ## Limit Outgoing Pings @@ -16,4 +16,5 @@ The PING/PONG interaction is also used by most of the clients as a way to flush For example, to set the maximum number of outgoing pings to 5: -!INCLUDE "../../_examples/ping_5.html" +!INCLUDE "../../\_examples/ping\_5.html" + diff --git a/developer/connecting/protocol.md b/developing-with-nats/intro/protocol.md similarity index 90% rename from developer/connecting/protocol.md rename to developing-with-nats/intro/protocol.md index dfabdc6..c65a509 100644 --- a/developer/connecting/protocol.md +++ b/developing-with-nats/intro/protocol.md @@ -8,22 +8,23 @@ Some clients will try to limit the control line size internally to prevent an er For example, to set the maximum control line size to 2k: -!INCLUDE "../../_examples/control_2k.html" +!INCLUDE "../../\_examples/control\_2k.html" ## Get the Maximum Payload Size While the client can't control the maximum payload size, clients may provide a way for applications to get the size after the connection is made. This will allow the application to chunk or limit data as needed to pass through the server. -!INCLUDE "../../_examples/max_payload.html" +!INCLUDE "../../\_examples/max\_payload.html" ## Turn On Pedantic Mode The NATS server provides a _pedantic_ mode that does extra checks on the protocol. By default, this setting is off but you can turn it on: -!INCLUDE "../../_examples/connect_pedantic.html" +!INCLUDE "../../\_examples/connect\_pedantic.html" ## Turn On/Off Verbose Mode The NATS server also provide a _verbose_ mode. By default, verbose mode is enabled and the server will reply to every message from the client with either a +OK or a -ERR. Most clients turn off verbose mode, which disables all of the +OK traffic. Errors are rarely subject to verbose mode and client libraries handle them as documented. To turn on verbose mode, likely for testing: -!INCLUDE "../../_examples/connect_verbose.html" \ No newline at end of file +!INCLUDE "../../\_examples/connect\_verbose.html" + diff --git a/developing-with-nats/intro/specific_server.md b/developing-with-nats/intro/specific_server.md new file mode 100644 index 0000000..677d01c --- /dev/null +++ b/developing-with-nats/intro/specific_server.md @@ -0,0 +1,86 @@ +# Connecting to a Specific Server + +The NATS client libraries can take a full URL, `nats://demo.nats.io:4222`, to specify a specific server host and port to connect to. + +Libraries are removing the requirement for an explicit protocol and may allow `nats://demo.nats.io:4222` or just `demo.nats.io:4222`. Check with your specific client library's documentation to see what URL formats are supported. + +For example, to connect to the demo server with a URL you can use: + +{% tabs %} +{% tab title="Go" %} +```java +// If connecting to the default port, the URL can be simplified +// to just the hostname/IP. +// That is, the connect below is equivalent to: +// nats.Connect("nats://demo.nats.io:4222") +nc, err := nats.Connect("demo.nats.io") +if err != nil { + log.Fatal(err) +} +defer nc.Close() + +// Do something with the connectioConnection nc = Nats.connect("nats://demo.nats.io:4222"); +``` +{% endtab %} + +{% tab title="Java" %} +```text +Connection nc = Nats.connect("nats://demo.nats.io:4222"); + +// Do something with the connection + +nc.close(); +``` +{% endtab %} + +{% tab title="JavaScript" %} +```javascript +let nc = NATS.connect("nats://demo.nats.io:4222"); +nc.on('connect', (c) => { + // Do something with the connection + doSomething(); + // When done close it + nc.close(); +}); +nc.on('error', (err) => { + failed(err); +}); +``` +{% endtab %} + +{% tab title="Python" %} +```python +nc = NATS() +await nc.connect(servers=["nats://demo.nats.io:4222"]) + +# Do something with the connection + +await nc.close() +``` +{% endtab %} + +{% tab title="Ruby" %} +```ruby +require 'nats/client' + +NATS.start(servers: ["nats://demo.nats.io:4222"]) do |nc| + # Do something with the connection + + # Close the connection + nc.close +end +``` +{% endtab %} + +{% tab title="TypeScript" %} +```typescript +// will throw an exception if connection fails + let nc = await connect("nats://demo.nats.io:4222"); + // Do something with the connection + + // Close the connection + nc.close(); +``` +{% endtab %} +{% endtabs %} + diff --git a/faq.md b/faq.md index 12698e1..d580db1 100644 --- a/faq.md +++ b/faq.md @@ -1,30 +1,29 @@ # FAQ - ### General -* [What is NATS?](#what-is-nats) -* [What language is NATS written in?](#what-language-is-nats-written-in) -* [Who maintains NATS?](#who-maintains-nats) -* [What clients does NATS support?](#what-client-support-exists-for-nats) -* [What does the NATS acronym stand for?](#what-does-the-nats-acronym-stand-for) +* [What is NATS?](faq.md#what-is-nats) +* [What language is NATS written in?](faq.md#what-language-is-nats-written-in) +* [Who maintains NATS?](faq.md#who-maintains-nats) +* [What clients does NATS support?](faq.md#what-client-support-exists-for-nats) +* [What does the NATS acronym stand for?](faq.md#what-does-the-nats-acronym-stand-for) ### Technical Questions -* [What is the difference between Request() and Publish()?](#what-is-the-difference-between-request-and-publish) -* [Can multiple subscribers receive a Request?](#can-multiple-subscribers-receive-a-request) -* [How can I monitor my NATS cluster?](#how-can-i-monitor-my-nats-cluster) -* [Does NATS do queuing? Does NATS do load balancing?](#does-nats-do-queuing-does-nats-do-load-balancing) -* [Can I list the subjects that exist in my NATS cluster?](#can-i-list-the-subjects-that-exist-in-my-nats-cluster) -* [Does NATS support subject wildcards?](#does-nats-support-subject-wildcards) -* [What do ‘verbose’ and ‘pedantic’ mean when using CONNECT?](#what-do-verbose-and-pedantic-mean-when-using-connect) -* [Does NATS offer any guarantee of message ordering?](#does-nats-offer-any-guarantee-of-message-ordering) -* [Is there a message size limitation in NATS?](#is-there-a-message-size-limitation-in-nats) -* [Does NATS impose any limits on the # of subjects?](#does-nats-impose-any-limits-on-the--of-subjects) -* [Does NATS guarantee message delivery?](#does-nats-guarantee-message-delivery) -* [Does NATS support replay/redelivery of historical data?](#does-nats-support-replayredelivery-of-historical-data) -* [How do I gracefully shut down an asynchronous subscriber?](#how-do-i-gracefully-shut-down-an-asynchronous-subscriber) -* [How do I create subjects?](#how-do-i-create-subjects) +* [What is the difference between Request\(\) and Publish\(\)?](faq.md#what-is-the-difference-between-request-and-publish) +* [Can multiple subscribers receive a Request?](faq.md#can-multiple-subscribers-receive-a-request) +* [How can I monitor my NATS cluster?](faq.md#how-can-i-monitor-my-nats-cluster) +* [Does NATS do queuing? Does NATS do load balancing?](faq.md#does-nats-do-queuing-does-nats-do-load-balancing) +* [Can I list the subjects that exist in my NATS cluster?](faq.md#can-i-list-the-subjects-that-exist-in-my-nats-cluster) +* [Does NATS support subject wildcards?](faq.md#does-nats-support-subject-wildcards) +* [What do ‘verbose’ and ‘pedantic’ mean when using CONNECT?](faq.md#what-do-verbose-and-pedantic-mean-when-using-connect) +* [Does NATS offer any guarantee of message ordering?](faq.md#does-nats-offer-any-guarantee-of-message-ordering) +* [Is there a message size limitation in NATS?](faq.md#is-there-a-message-size-limitation-in-nats) +* [Does NATS impose any limits on the \# of subjects?](faq.md#does-nats-impose-any-limits-on-the--of-subjects) +* [Does NATS guarantee message delivery?](faq.md#does-nats-guarantee-message-delivery) +* [Does NATS support replay/redelivery of historical data?](faq.md#does-nats-support-replayredelivery-of-historical-data) +* [How do I gracefully shut down an asynchronous subscriber?](faq.md#how-do-i-gracefully-shut-down-an-asynchronous-subscriber) +* [How do I create subjects?](faq.md#how-do-i-create-subjects) ## General @@ -32,7 +31,7 @@ NATS is an open source, lightweight, high-performance cloud native infrastructure messaging system. It implements a highly scalable and elegant publish-subscribe \(pub/sub\) distribution model. The performant nature of NATS make it an ideal base for building modern, reliable, scalable cloud native distributed systems. -NATS is offered in two interoperable modules: core NATS \(referred to simply as "NATS" or "NATS Server" throughout this site\), and [NATS Streaming](/nats_streaming/intro.md), an event streaming service that can be employed to add event streaming, delivery guarantees, and historical data replay to NATS. +NATS is offered in two interoperable modules: core NATS \(referred to simply as "NATS" or "NATS Server" throughout this site\), and [NATS Streaming](nats-streaming-concepts/intro.md), an event streaming service that can be employed to add event streaming, delivery guarantees, and historical data replay to NATS. NATS was created by Derek Collison, who has over 25 years of experience designing, building, and using publish-subscribe messaging systems. NATS is maintained by an amazing OpenSource Ecosystem, find more at [GitHub](https://www.github.com/nats-io). @@ -64,16 +63,16 @@ Request\(\) is simply a convenience API that does this for you in a pseudo-synch Yes. NATS is a publish and subscribe system that also has distributed queueing functionality on a per subscriber basis. When you publish a message, for instance at the beginning of a request, every subscriber will receive the message. If subscribers form a queue group, only one subscriber will be picked at random to receive the message. However, note that the requestor does not know or control this information. What the requestor does control is that it only wants one answer to the request, and NATS handles this very well by actively pruning the interest graph. -### How can I monitor my NATS cluster? +### How can I monitor my NATS cluster? -NATS can be deployed to have an HTTP(s) monitoring port - see the demo server here: [http://demo.nats.io:8222/](https://demo.nats.io:8222/). Alternately, there are several options available, including some from the active NATS community: +NATS can be deployed to have an HTTP\(s\) monitoring port - see the demo server here: [http://demo.nats.io:8222/](https://demo.nats.io:8222/). Alternately, there are several options available, including some from the active NATS community: * [Prometheus NATS Exporter](https://github.com/nats-io/prometheus-nats-exporter) Use Prometheus to configure metrics and Grafana to create a visual display. * [nats-top](https://github.com/nats-io/nats-top) A top-like monitoring tool developed by Wally Quevedo of Synadia. * [natsboard](https://github.com/cmfatih/natsboard) A monitoring tool developed by Fatih Cetinkaya. * [nats-mon](https://github.com/repejota/nats-mon) A monitoring tool developed by Raül Pérez and Adrià Cidre. -A more detailed overview of monitoring is available under [NATS Server Monitoring](/nats_server/monitoring.md/). +A more detailed overview of monitoring is available under [NATS Server Monitoring](nats-server/configuration/monitoring.md). ### Does NATS do queuing? Does NATS do load balancing? @@ -85,7 +84,7 @@ This form of distributed queueing is done in real time, and messages are not per NATS maintains and constantly updates the interest graph \(subjects and their subscribers\) in real time. Do not think of it as a "directory" that is aggregated over time. The interest graph dynamic, and will change constantly as publishers and subscribers come and go. -If you are determined to gather this information, it can be indirectly derived at any instant in time by polling the monitoring endpoint for /connz and /routez. See [Server Monitoring](nats_server/monitoring.md) for more information. +If you are determined to gather this information, it can be indirectly derived at any instant in time by polling the monitoring endpoint for /connz and /routez. See [Server Monitoring](nats-server/configuration/monitoring.md) for more information. ### Does NATS support subject wildcards? @@ -123,14 +122,14 @@ No. As of `nats-server` v0.8.0, there is no hard limit on the maximum number of ### Does NATS guarantee message delivery? -NATS is offered as two components: the core server \(referred to simply as "NATS" or "NATS Server"\) and [NATS Streaming](/nats_streaming/intro.md/), which is a data streaming service that sits atop NATS core like a client. +NATS is offered as two components: the core server \(referred to simply as "NATS" or "NATS Server"\) and [NATS Streaming](nats-streaming-concepts/intro.md), which is a data streaming service that sits atop NATS core like a client. * **NATS** implements what is commonly referred to as "at-most-once" delivery. This means that messages are guaranteed to arrive intact, in order from a given publisher, but not across different publishers. NATS does everything required to remain on and provide a dial-tone. However, if a subscriber is problematic or goes offline it will not receive messages, as the basic NATS platform is a simple pub-sub transport system that offers only TCP reliability. -* [**NATS Streaming**](/nats_streaming/intro.md) offers _at-least-once_ delivery guarantees by implementing publish and delivery acknowledgements, and persisting messages to memory or a secondary store until messages have been successfully delivered, or until resource limits or other administrator-defined limits have been reached. +* [**NATS Streaming**](nats-streaming-concepts/intro.md) offers _at-least-once_ delivery guarantees by implementing publish and delivery acknowledgements, and persisting messages to memory or a secondary store until messages have been successfully delivered, or until resource limits or other administrator-defined limits have been reached. ### Does NATS support replay/redelivery of historical data? -Yes, historical data may be persisted to memory or secondary storage and replayed using [NATS Streaming](/nats_streaming/intro.md), an event streaming service based on \(and compatible with\) NATS. +Yes, historical data may be persisted to memory or secondary storage and replayed using [NATS Streaming](nats-streaming-concepts/intro.md), an event streaming service based on \(and compatible with\) NATS. ### How do I gracefully shut down an asynchronous subscriber? @@ -139,3 +138,4 @@ To gracefully shutdown an asynchronous subscriber so that any outstanding MsgHan ### How do I create subjects? Subjects are created and pruned \(deleted\) dynamically based on interest \(subscriptions\). This means that a subject does not exist in a NATS cluster until a client subscribes to it, and the subject goes away after the last subscribing client unsubscribes from that subject. + diff --git a/nats_protocol/nats-protocol-demo.md b/nats-protocol/nats-protocol-demo.md similarity index 89% rename from nats_protocol/nats-protocol-demo.md rename to nats-protocol/nats-protocol-demo.md index 9c38e7b..9d14812 100644 --- a/nats_protocol/nats-protocol-demo.md +++ b/nats-protocol/nats-protocol-demo.md @@ -1,8 +1,10 @@ +# Protocol Demo + ## Protocol Demo The virtues of the NATS protocol manifest quickly when you experience how easy it is to use NATS. Because the NATS protocol is text-based, you can use NATS across virtually any platform or language. In the following demo we use [Telnet](https://en.wikipedia.org/wiki/Telnet). -On the wire you can publish and subscribe using a simple [set of protocol commands](nats-protocol.md). +On the wire you can publish and subscribe using a simple [set of protocol commands](nats-protocol/). ## Instructions @@ -12,13 +14,13 @@ You'll use this terminal as the subscriber. **2. Connect to NATS.** -``` +```text telnet demo.nats.io 4222 ``` Expected result: -``` +```text $ telnet demo.nats.io 4222 Trying 107.170.221.32... Connected to demo.nats.io. @@ -30,13 +32,13 @@ INFO {"server_id":"NCXMJZYQEWUDJFLYLSTTE745I2WUNCVG3LJJ3NRKSFJXEG6RGK7753DJ","ve Subscribe to the wildcard subject `foo.*` with subject ID of `90`. -``` +```text sub foo.* 90 ``` Subscriber result: `+OK` indicating successful interest registration. -``` +```text sub foo.* 90 +OK ``` @@ -47,31 +49,32 @@ You'll use this terminal for the publisher. **5. Connect to NATS.** -``` +```text telnet demo.nats.io 4222 ``` Expected result: -``` +```text $ telnet demo.nats.io 4222 Trying 107.170.221.32... Connected to demo.nats.io. Escape character is '^]'. INFO {"server_id":"NCXMJZYQEWUDJFLYLSTTE745I2WUNCVG3LJJ3NRKSFJXEG6RGK7753DJ","version":"2.0.0","proto":1,"go":"go1.11.10","host":"0.0.0.0","port":4222,"max_payload":1048576,"client_id":5089} ``` + **6. Publish a message.** -The message includes the command (`pub`), subject (`foo.bar`), and length of the payload (`5`). Press enter and provide the payload (`hello`), then press enter again. +The message includes the command \(`pub`\), subject \(`foo.bar`\), and length of the payload \(`5`\). Press enter and provide the payload \(`hello`\), then press enter again. -``` +```text pub foo.bar 5 hello ``` Publisher result: `+OK` indicating message publication. -``` +```text pub foo.bar 5 hello +OK @@ -79,7 +82,7 @@ hello Subscriber result: `MSG` + subject name + subscription ID + message payload size + message payload `hello`. -``` +```text sub foo.* 90 +OK MSG foo.bar 90 5 @@ -88,7 +91,7 @@ hello **7. Publish another message with reply subject.** -``` +```text pub foo.bar optional.reply.subject 5 hello +OK @@ -96,7 +99,7 @@ hello Subscriber result: `MSG` indicating message receipt. -``` +```text MSG foo.bar 90 optional.reply.subject 5 hello ``` @@ -107,24 +110,24 @@ You can use the `UNSUB` command to unsubscribe from a message. Run the subscriber to unsubscribe: -``` -unsub 90 +```text +unsub 90 ``` Subscriber result: `+OK` indicating successful deregistration of interest. -``` +```text unsub 90 +OK ``` **9. Reconnect to server and subscribe.** -``` +```text telnet demo.nats.io 4222 ``` -``` +```text sub foo.* 90 ``` @@ -134,7 +137,7 @@ If you leave your telnet session open for a few minutes, you may notice that you You can send a `ping` request to the serve and receive a `PONG` reply. For example: -``` +```text $ telnet demo.nats.io 4222 Trying 107.170.221.32... Connected to demo.nats.io. @@ -144,3 +147,4 @@ INFO {"server_id":"NCXMJZYQEWUDJFLYLSTTE745I2WUNCVG3LJJ3NRKSFJXEG6RGK7753DJ","ve ping PONG ``` + diff --git a/nats-protocol/nats-protocol/README.md b/nats-protocol/nats-protocol/README.md new file mode 100644 index 0000000..29f7d69 --- /dev/null +++ b/nats-protocol/nats-protocol/README.md @@ -0,0 +1,319 @@ +# Client Protocol + +## Client Protocol + +The wire protocol used to communicate between the NATS server and clients is a simple, text-based publish/subscribe style protocol. Clients connect to and communicate with `nats-server` \(the NATS server\) through a regular TCP/IP socket using a small set of protocol operations that are terminated by a new line. + +Unlike traditional messaging systems that use a binary message format that require an API to consume, the text-based NATS protocol makes it easy to implement clients in a wide variety of programming and scripting languages. In fact, refer to the topic [NATS Protocol Demo](../nats-protocol-demo.md) to play with the NATS protocol for yourself using telnet. + +The NATS server implements a [zero allocation byte parser](https://youtu.be/ylRKac5kSOk?t=10m46s) that is fast and efficient. + +## Protocol conventions + +**Control line w/Optional Content**: Each interaction between the client and server consists of a control, or protocol, line of text followed, optionally by message content. Most of the protocol messages don't require content, only `PUB` and `MSG` include payloads. + +**Field Delimiters**: The fields of NATS protocol messages are delimited by whitespace characters '```' (space) or``\t\` \(tab\). Multiple whitespace characters will be treated as a single field delimiter. + +**Newlines**: NATS uses `CR` followed by `LF` \(`CR+LF`, `\r\n`, `0x0D0A`\) to terminate protocol messages. This newline sequence is also used to mark the end of the message payload in a `PUB` or `MSG` protocol message. + +**Subject names**: Subject names, including reply subject \(INBOX\) names, are case-sensitive and must be non-empty alphanumeric strings with no embedded whitespace. All ascii alphanumeric characters except spaces/tabs and separators which are "." and ">" are allowed. Subject names can be optionally token-delimited using the dot character \(`.`\), e.g.: + +`FOO`, `BAR`, `foo.bar`, `foo.BAR`, `FOO.BAR` and `FOO.BAR.BAZ` are all valid subject names + +`FOO. BAR`, `foo. .bar` and`foo..bar` are _not_ valid subject names + +A subject is comprised of 1 or more tokens. Tokens are separated by "." and can be any non space ascii alphanumeric character. The full wildcard token ">" is only valid as the last token and matches all tokens past that point. A token wildcard, "\*" matches any token in the position it was listed. Wildcard tokens should only be used in a wildcard capacity and not part of a literal token. + +**Character Encoding**: Subject names should be ascii characters for maximum interoperability. Due to language constraints and performance, some clients may support UTF-8 subject names, as may the server. No guarantees of non-ASCII support are provided. + +**Wildcards**: NATS supports the use of wildcards in subject subscriptions. + +* The asterisk character \(`*`\) matches a single token at any level of the subject. +* The greater than symbol \(`>`\), also known as the _full wildcard_, matches one or more tokens at the tail of a subject, and must be the last token. The wildcarded subject `foo.>` will match `foo.bar` or `foo.bar.baz.1`, but not `foo`. +* Wildcards must be a separate token \(`foo.*.baz` or `foo.>` are syntactically valid; `foo*.bar`, `f*o.b*r` and `foo>` are not\) + +For example, the wildcard subscriptions `foo.*.quux` and `foo.>` both match `foo.bar.quux`, but only the latter matches `foo.bar.baz`. With the full wildcard, it is also possible to express interest in every subject that may exist in NATS: `sub > 1`, limited of course by authorization settings. + +## Protocol messages + +The following table briefly describes the NATS protocol messages. NATS protocol operation names are case insensitive, thus `SUB foo 1\r\n` and `sub foo 1\r\n` are equivalent. + +Click the name to see more detailed information, including syntax: + +| OP Name | Sent By | Description | +| :--- | :--- | :--- | +| [`INFO`](./#info) | Server | Sent to client after initial TCP/IP connection | +| [`CONNECT`](./#connect) | Client | Sent to server to specify connection information | +| [`PUB`](./#pub) | Client | Publish a message to a subject, with optional reply subject | +| [`SUB`](./#sub) | Client | Subscribe to a subject \(or subject wildcard\) | +| [`UNSUB`](./#unsub) | Client | Unsubscribe \(or auto-unsubscribe\) from subject | +| [`MSG`](./#msg) | Server | Delivers a message payload to a subscriber | +| [`PING`](./#pingpong) | Both | PING keep-alive message | +| [`PONG`](./#pingpong) | Both | PONG keep-alive response | +| [`+OK`](./#okerr) | Server | Acknowledges well-formed protocol message in `verbose` mode | +| [`-ERR`](./#okerr) | Server | Indicates a protocol error. May cause client disconnect. | + +The following sections explain each protocol message. + +## INFO + +### Description + +As soon as the server accepts a connection from the client, it will send information about itself and the configuration and security requirements that are necessary for the client to successfully authenticate with the server and exchange messages. + +When using the updated client protocol \(see [`CONNECT`](./#connect) below\), `INFO` messages can be sent anytime by the server. This means clients with that protocol level need to be able to asynchronously handle `INFO` messages. + +### Syntax + +`INFO {["option_name":option_value],...}` + +The valid options are as follows: + +* `server_id`: The unique identifier of the NATS server +* `version`: The version of the NATS server +* `go`: The version of golang the NATS server was built with +* `host`: The IP address used to start the NATS server, by default this will be `0.0.0.0` and can be configured with `-client_advertise host:port` +* `port`: The port number the NATS server is configured to listen on +* `max_payload`: Maximum payload size, in bytes, that the server will accept from the client. +* `proto`: An integer indicating the protocol version of the server. The server version 1.2.0 sets this to `1` to indicate that it supports the "Echo" feature. +* `client_id`: An optional unsigned integer \(64 bits\) representing the internal client identifier in the server. This can be used to filter client connections in monitoring, correlate with error logs, etc... +* `auth_required`: If this is set, then the client should try to authenticate upon connect. +* `tls_required`: If this is set, then the client must perform the TLS/1.2 handshake. Note, this used to be `ssl_required` and has been updated along with the protocol from SSL to TLS. +* `tls_verify`: If this is set, the client must provide a valid certificate during the TLS handshake. +* `connect_urls` : An optional list of server urls that a client can connect to. + +#### connect\_urls + +The `connect_urls` field is a list of urls the server may send when a client first connects, and when there are changes to server cluster topology. This field is considered optional, and may be omitted based on server configuration and client protocol level. + +When a NATS server cluster expands, an `INFO` message is sent to the client with an updated `connect_urls` list. This cloud-friendly feature asynchronously notifies a client of known servers, allowing it to connect to servers not originally configured. + +The `connect_urls` will contain a list of strings with an IP and port, looking like this: `"connect_urls":["10.0.0.184:4333","192.168.129.1:4333","192.168.192.1:4333"]` + +### Example + +Below you can see a sample connection string from a telnet connection to the `demo.nats.io` site. + +```bash +% telnet demo.nats.io 4222 + +Trying 107.170.221.32... +Connected to demo.nats.io. +Escape character is '^]'. +INFO {"server_id":"Zk0GQ3JBSrg3oyxCRRlE09","version":"1.2.0","proto":1,"go":"go1.10.3","host":"0.0.0.0","port":4222,"max_payload":1048576,"client_id":2392} +``` + +## CONNECT + +### Description + +The `CONNECT` message is the client version of the [`INFO`](./#info) message. Once the client has established a TCP/IP socket connection with the NATS server, and an [`INFO`](./#info) message has been received from the server, the client may send a `CONNECT` message to the NATS server to provide more information about the current connection as well as security information. + +### Syntax + +`CONNECT {["option_name":option_value],...}` + +The valid options are as follows: + +* `verbose`: Turns on [`+OK`](./#okerr) protocol acknowledgements. +* `pedantic`: Turns on additional strict format checking, e.g. for properly formed subjects +* `tls_required`: Indicates whether the client requires an SSL connection. +* `auth_token`: Client authorization token \(if `auth_required` is set\) +* `user`: Connection username \(if `auth_required` is set\) +* `pass`: Connection password \(if `auth_required` is set\) +* `name`: Optional client name +* `lang`: The implementation language of the client. +* `version`: The version of the client. +* `protocol`: _optional int_. Sending `0` \(or absent\) indicates client supports original protocol. Sending `1` indicates that the client supports dynamic reconfiguration of cluster topology changes by asynchronously receiving [`INFO`](./#info) messages with known servers it can reconnect to. +* `echo`: Optional boolean. If set to `true`, the server \(version 1.2.0+\) will not send originating messages from this connection to its own subscriptions. Clients should set this to `true` only for server supporting this feature, which is when `proto` in the `INFO` protocol is set to at least `1`. + +### Example + +Here is an example from the default string of the Go client: + +```text +[CONNECT {"verbose":false,"pedantic":false,"tls_required":false,"name":"","lang":"go","version":"1.2.2","protocol":1}]\r\n +``` + +Most clients set `verbose` to `false` by default. This means that the server should not confirm each message it receives on this connection with a [`+OK`](./#okerr) back to the client. + +## PUB + +### Description + +The `PUB` message publishes the message payload to the given subject name, optionally supplying a reply subject. If a reply subject is supplied, it will be delivered to eligible subscribers along with the supplied payload. Note that the payload itself is optional. To omit the payload, set the payload size to 0, but the second CRLF is still required. + +### Syntax + +`PUB [reply-to] <#bytes>\r\n[payload]\r\n` + +where: + +* `subject`: The destination subject to publish to +* `reply-to`: The optional reply inbox subject that subscribers can use to send a response back to the publisher/requestor +* `#bytes`: The payload size in bytes +* `payload`: The message payload data + +### Example + +To publish the ASCII string message payload "Hello NATS!" to subject FOO: + +`PUB FOO 11\r\nHello NATS!\r\n` + +To publish a request message "Knock Knock" to subject FRONT.DOOR with reply subject INBOX.22: + +`PUB FRONT.DOOR INBOX.22 11\r\nKnock Knock\r\n` + +To publish an empty message to subject NOTIFY: + +`PUB NOTIFY 0\r\n\r\n` + +## SUB + +### Description + +`SUB` initiates a subscription to a subject, optionally joining a distributed queue group. + +### Syntax + +`SUB [queue group] \r\n` + +where: + +* `subject`: The subject name to subscribe to +* `queue group`: If specified, the subscriber will join this queue group +* `sid`: A unique alphanumeric subscription ID, generated by the client + +### Example + +To subscribe to the subject `FOO` with the connection-unique subscription identifier \(sid\) `1`: + +`SUB FOO 1\r\n` + +To subscribe the current connection to the subject `BAR` as part of distribution queue group `G1` with sid `44`: + +`SUB BAR G1 44\r\n` + +## UNSUB + +### Description + +`UNSUB` unsubcribes the connection from the specified subject, or auto-unsubscribes after the specified number of messages has been received. + +### Syntax + +`UNSUB [max_msgs]` + +where: + +* `sid`: The unique alphanumeric subscription ID of the subject to unsubscribe from +* `max_msgs`: An optional number of messages to wait for before automatically unsubscribing + +### Example + +The following examples concern subject `FOO` which has been assigned sid `1`. To unsubscribe from `FOO`: + +`UNSUB 1\r\n` + +To auto-unsubscribe from `FOO` after 5 messages have been received: + +`UNSUB 1 5\r\n` + +## MSG + +### Description + +The `MSG` protocol message is used to deliver an application message to the client. + +### Syntax + +`MSG [reply-to] <#bytes>\r\n[payload]\r\n` + +where: + +* `subject`: Subject name this message was received on +* `sid`: The unique alphanumeric subscription ID of the subject +* `reply-to`: The inbox subject on which the publisher is listening for responses +* `#bytes`: Size of the payload in bytes +* `payload`: The message payload data + +### Example + +The following message delivers an application message from subject `FOO.BAR`: + +`MSG FOO.BAR 9 11\r\nHello World\r\n` + +To deliver the same message along with a reply inbox: + +`MSG FOO.BAR 9 INBOX.34 11\r\nHello World\r\n` + +## PING/PONG + +### Description + +`PING` and `PONG` implement a simple keep-alive mechanism between client and server. Once a client establishes a connection to the NATS server, the server will continuously send `PING` messages to the client at a configurable interval. If the client fails to respond with a `PONG` message within the configured response interval, the server will terminate its connection. If your connection stays idle for too long, it is cut off. + +If the server sends a ping request, you can reply with a pong message to notify the server that you are still interested. You can also ping the server and will receive a pong reply. The ping/pong interval is configurable. + +The server uses normal traffic as a ping/pong proxy, so a client that has messages flowing may not receive a ping from the server. + +### Syntax + +`PING\r\n` + +`PONG\r\n` + +### Example + +The following example shows the demo server pinging the client and finally shutting it down. + +```text +telnet demo.nats.io 4222 + +Trying 107.170.221.32... +Connected to demo.nats.io. +Escape character is '^]'. +INFO {"server_id":"Zk0GQ3JBSrg3oyxCRRlE09","version":"1.2.0","proto":1,"go":"go1.10.3","host":"0.0.0.0","port":4222,"max_payload":1048576,"client_id":2392} +PING +PING +-ERR 'Stale Connection' +Connection closed by foreign host. +``` + +## +OK/ERR + +### Description + +When the `verbose` connection option is set to `true` \(the default value\), the server acknowledges each well-formed protocol message from the client with a `+OK` message. Most NATS clients set the `verbose` option to `false` using the [`CONNECT`](./#connect) message + +The `-ERR` message is used by the server indicate a protocol, authorization, or other runtime connection error to the client. Most of these errors result in the server closing the connection. + +Handling of these errors usually has to be done asynchronously. + +### Syntax + +`+OK` + +`-ERR ` + +Some protocol errors result in the server closing the connection. Upon receiving these errors, the connection is no longer valid and the client should clean up relevant resources. These errors include: + +* `-ERR 'Unknown Protocol Operation'`: Unknown protocol error +* `-ERR 'Attempted To Connect To Route Port'`: Client attempted to connect to a route port instead of the client port +* `-ERR 'Authorization Violation'`: Client failed to authenticate to the server with credentials specified in the [`CONNECT`](./#connect) message +* `-ERR 'Authorization Timeout'`: Client took too long to authenticate to the server after establishing a connection \(default 1 second\) +* `-ERR 'Invalid Client Protocol'`: Client specified an invalid protocol version in the [`CONNECT`](./#connect) message +* `-ERR 'Maximum Control Line Exceeded'`: Message destination subject and reply subject length exceeded the maximum control line value specified by the `max_control_line` server option. The default is 1024 bytes. +* `-ERR 'Parser Error'`: Cannot parse the protocol message sent by the client +* `-ERR 'Secure Connection - TLS Required'`: The server requires TLS and the client does not have TLS enabled. +* `-ERR 'Stale Connection'`: The server hasn't received a message from the client, including a `PONG` in too long. +* `-ERR 'Maximum Connections Exceeded`': This error is sent by the server when creating a new connection and the server has exceeded the maximum number of connections specified by the `max_connections` server option. The default is 64k. +* `-ERR 'Slow Consumer'`: The server pending data size for the connection has reached the maximum size \(default 10MB\). +* `-ERR 'Maximum Payload Violation'`: Client attempted to publish a message with a payload size that exceeds the `max_payload` size configured on the server. This value is supplied to the client upon connection in the initial [`INFO`](./#info) message. The client is expected to do proper accounting of byte size to be sent to the server in order to handle this error synchronously. + +Protocol error messages where the connection remains open are listed below. The client should not close the connection in these cases. + +* `-ERR 'Invalid Subject'`: Client sent a malformed subject \(e.g. `sub foo. 90`\) +* `-ERR 'Permissions Violation for Subscription to '`: The user specified in the [`CONNECT`](./#connect) message does not have permission to subscribe to the subject. +* `-ERR 'Permissions Violation for Publish to '`: The user specified in the [`CONNECT`](./#connect) message does not have permissions to publish to the subject. + diff --git a/nats_protocol/nats-client-dev.md b/nats-protocol/nats-protocol/nats-client-dev.md similarity index 75% rename from nats_protocol/nats-client-dev.md rename to nats-protocol/nats-protocol/nats-client-dev.md index 2847f1c..405263c 100644 --- a/nats_protocol/nats-client-dev.md +++ b/nats-protocol/nats-protocol/nats-client-dev.md @@ -1,34 +1,36 @@ +# Developing a Client + ## NATS Client Development Guide This guide provides you with considerations for developing NATS clients, including: -- CONNECT handling -- Authorization -- Verbose (acks) -- Pedantic mode -- Ping/pong interval -- Parsing the protocol -- Deciding on a parsing strategy -- Storing and dispatching subscription callbacks -- Implementing requests/response -- Error handling, disconnecting and reconnecting -- Cluster support +* CONNECT handling +* Authorization +* Verbose \(acks\) +* Pedantic mode +* Ping/pong interval +* Parsing the protocol +* Deciding on a parsing strategy +* Storing and dispatching subscription callbacks +* Implementing requests/response +* Error handling, disconnecting and reconnecting +* Cluster support Probably the best way to learn about implementing a client is to look at one of the client's maintained by the Synadia team. These clients are generally full featured, so if you can use them, that is even better, but if you have to write a client these may go beyond your needs while still capturing many of the design considerations discussed here. -- [go](https://github.com/nats-io/nats.go) -- [node](https://github.com/nats-io/nats.js) -- [typescript](https://github.com/nats-io/nats.ts) -- [python2](https://github.com/nats-io/nats.py2) -- [python asyncio](https://github.com/nats-io/nats.py) -- [java](https://github.com/nats-io/nats.java) -- [c#](https://github.com/nats-io/nats.net) -- [ruby](https://github.com/nats-io/nats.rb) -- [c](https://github.com/nats-io/nats.c) +* [go](https://github.com/nats-io/nats.go) +* [node](https://github.com/nats-io/nats.js) +* [typescript](https://github.com/nats-io/nats.ts) +* [python2](https://github.com/nats-io/nats.py2) +* [python asyncio](https://github.com/nats-io/nats.py) +* [java](https://github.com/nats-io/nats.java) +* [c\#](https://github.com/nats-io/nats.net) +* [ruby](https://github.com/nats-io/nats.rb) +* [c](https://github.com/nats-io/nats.c) ## Client connection options -Clients can connect in authenticated or unauthenticated mode, as well as verbose mode which enables acknowledgements. See the [protocol documentation](/nats_protocol/nats-protocol.md#connect) for details. +Clients can connect in authenticated or unauthenticated mode, as well as verbose mode which enables acknowledgements. See the [protocol documentation](./#connect) for details. ## Client authorization @@ -36,19 +38,19 @@ By default clients can connect to the server in unauthenticated mode. You can co For example, using the command line: -``` +```text nats-server -DV -m 8222 -user foo -pass bar ``` The client must then authenticate to connect to the server. For example: -``` +```text nats.Connect("nats://foo:bar@localhost:4222") ``` ## Verbose mode -When 'verbose' is enabled (via the `CONNECT` message), the NATS server will return `+OK` to acknowledge receipt of a valid protocol message. The NATS server automatically runs in verbose mode. Most client implementations disable verbose mode (set it to `false` in the `CONNECT` message) for performance reasons. +When 'verbose' is enabled \(via the `CONNECT` message\), the NATS server will return `+OK` to acknowledge receipt of a valid protocol message. The NATS server automatically runs in verbose mode. Most client implementations disable verbose mode \(set it to `false` in the `CONNECT` message\) for performance reasons. ## Pedantic mode @@ -60,13 +62,13 @@ NATS implements auto-pruning. When a client connects to the server, the server e ## Parsing the protocol -NATS provides a text-based message format. The text-based [protocol](/documentation/internals/nats-protocol/) makes it easy to implement NATS clients. The key consideration is deciding on a parsing strategy. +NATS provides a text-based message format. The text-based [protocol](https://github.com/nats-io/nats.docs/tree/51fc56e3090645f7cedb242415e2d5361e1807e7/documentation/internals/nats-protocol/README.md) makes it easy to implement NATS clients. The key consideration is deciding on a parsing strategy. The NATS server implements a [zero allocation byte parser](https://youtu.be/ylRKac5kSOk?t=10m46s) that is fast and efficient. Off the wire, a NATS message is simply a slice of bytes. Across the wire the message is transported as an immutable string over a TCP connection. It is up to the client to implement logic to parse the message. -The NATS message structure includes the Subject string, an optional Reply string, and an optional Data field that is a byte array. The type `Msg` is a structure used by Subscribers and PublishMsg(). +The NATS message structure includes the Subject string, an optional Reply string, and an optional Data field that is a byte array. The type `Msg` is a structure used by Subscribers and PublishMsg\(\). -``` +```text type Msg struct { Subject string Reply string @@ -104,3 +106,4 @@ Considerations for error handling primarily include handling client disconnectio ## Cluster support The NATS client has reconnection logic. So, if you are implementing clustering, you need to implement reconnect callbacks a priori, meaning you cannot modify it during runtime. When you start it, you need to have that information already. + diff --git a/nats_protocol/nats-server-protocol.md b/nats-protocol/nats-server-protocol.md similarity index 58% rename from nats_protocol/nats-server-protocol.md rename to nats-protocol/nats-server-protocol.md index c26d603..8841646 100644 --- a/nats_protocol/nats-server-protocol.md +++ b/nats-protocol/nats-server-protocol.md @@ -1,53 +1,51 @@ +# NATS Cluster Protocol + ## NATS Cluster Protocol -The NATS server clustering protocol describes the protocols passed between NATS servers within a [cluster](/nats_server/clustering.md) to share accounts, subscriptions, forward messages, and share cluster topology regarding new servers. It is a simple text-based protocol. Servers communicate with each other through a regular TCP/IP or TLS socket using a small set of protocol operations that are terminated by newline. +The NATS server clustering protocol describes the protocols passed between NATS servers within a [cluster](../nats-server/configuration/clustering/) to share accounts, subscriptions, forward messages, and share cluster topology regarding new servers. It is a simple text-based protocol. Servers communicate with each other through a regular TCP/IP or TLS socket using a small set of protocol operations that are terminated by newline. The NATS server implements a [zero allocation byte parser](https://youtu.be/ylRKac5kSOk?t=10m46s) that is fast and efficient. -The NATS cluster protocol is very similar to that of the NATS client protocol. In the context of a cluster, it can be helpful to visualize a server being a proxy operating on behalf of its connected clients, subscribing, unsubscribing, sending and receiving messages. +The NATS cluster protocol is very similar to that of the NATS client protocol. In the context of a cluster, it can be helpful to visualize a server being a proxy operating on behalf of its connected clients, subscribing, unsubscribing, sending and receiving messages. ## NATS Cluster protocol conventions **Subject names and wildcards**: The NATS cluster protocol has the same features and restrictions as the client with respect to subject names and wildcards. Clients are bound to a single account, however the cluster protocol handles all accounts. -**Field Delimiters**: The fields of NATS protocol messages are delimited by whitespace characters '` `' (space) or `\t` (tab). -Multiple whitespace characters will be treated as a single field delimiter. +**Field Delimiters**: The fields of NATS protocol messages are delimited by whitespace characters '```' (space) or``\t\` \(tab\). Multiple whitespace characters will be treated as a single field delimiter. -**Newlines**: Like other text-based protocols, NATS uses `CR` followed by `LF` (`CR+LF`, `\r\n`, `0x0D0A`) to terminate protocol messages. This newline sequence is also used to mark the beginning of the actual message payload in a `RMSG` protocol message. +**Newlines**: Like other text-based protocols, NATS uses `CR` followed by `LF` \(`CR+LF`, `\r\n`, `0x0D0A`\) to terminate protocol messages. This newline sequence is also used to mark the beginning of the actual message payload in a `RMSG` protocol message. ## NATS Cluster protocol messages -The following table briefly describes the NATS cluster protocol messages. -As in the client protocol, the NATS protocol operation names are case insensitive, thus `SUB foo 1\r\n` and `sub foo 1\r\n` are equivalent. +The following table briefly describes the NATS cluster protocol messages. As in the client protocol, the NATS protocol operation names are case insensitive, thus `SUB foo 1\r\n` and `sub foo 1\r\n` are equivalent. Click the name to see more detailed information, including syntax: - -| OP Name | Sent By | Description -| -------------------- |:-----------------|:-------------------------------------------- -| [`INFO`](#info) | All Servers | Sent after initial TCP/IP connection and to update cluster knowledge -| [`CONNECT`](#connect)| All Servers | Sent to establish a route -| [`RS+`](#sub) | All Servers | Subscribes to a subject for a given account on behalf of interested clients. -| [`RS-`](#unsub) | All Servers | Unsubscribe (or auto-unsubscribe) from subject for a given account. -| [`RMSG`](#rmsg) | Origin Server | Delivers a message for a given subject and account to another server. -| [`PING`](#pingpong) | All Servers | PING keep-alive message -| [`PONG`](#pingpong) | All Servers | PONG keep-alive response -| [`-ERR`](#-err) | All Servers | Indicates a protocol error. May cause the remote server to disconnect. - +| OP Name | Sent By | Description | +| :--- | :--- | :--- | +| [`INFO`](nats-server-protocol.md#info) | All Servers | Sent after initial TCP/IP connection and to update cluster knowledge | +| [`CONNECT`](nats-server-protocol.md#connect) | All Servers | Sent to establish a route | +| [`RS+`](nats-server-protocol.md#sub) | All Servers | Subscribes to a subject for a given account on behalf of interested clients. | +| [`RS-`](nats-server-protocol.md#unsub) | All Servers | Unsubscribe \(or auto-unsubscribe\) from subject for a given account. | +| [`RMSG`](nats-server-protocol.md#rmsg) | Origin Server | Delivers a message for a given subject and account to another server. | +| [`PING`](nats-server-protocol.md#pingpong) | All Servers | PING keep-alive message | +| [`PONG`](nats-server-protocol.md#pingpong) | All Servers | PONG keep-alive response | +| [`-ERR`](nats-server-protocol.md#-err) | All Servers | Indicates a protocol error. May cause the remote server to disconnect. | The following sections explain each protocol message. ## INFO -#### Description +### Description As soon as the server accepts a connection from another server, it will send information about itself and the configuration and security requirements that are necessary for the other server to successfully authenticate with the server and exchange messages. -The connecting server also sends an `INFO` message. The accepting server will add an `ip` field containing the address and port of the connecting server, and forward the new server's `INFO` message to all servers it is routed to. +The connecting server also sends an `INFO` message. The accepting server will add an `ip` field containing the address and port of the connecting server, and forward the new server's `INFO` message to all servers it is routed to. -Any servers in a cluster receiving an `INFO` message with an `ip` field will attempt to connect to the server at that address, unless already connected. This propagation of `INFO` messages on behalf of a connecting server provides automatic discovery of new servers joining a cluster. +Any servers in a cluster receiving an `INFO` message with an `ip` field will attempt to connect to the server at that address, unless already connected. This propagation of `INFO` messages on behalf of a connecting server provides automatic discovery of new servers joining a cluster. -#### Syntax +### Syntax `INFO {["option_name":option_value],...}` @@ -64,7 +62,7 @@ The valid options are as follows: * `connect_urls` : A list of server urls that a client can connect to. * `ip`: Optional route connection address of a server, `nats-route://:` -#### Example +### Example Below is an example of an `INFO` string received by a NATS server, with the `ip` field. @@ -72,11 +70,11 @@ Below is an example of an `INFO` string received by a NATS server, with the `ip` ## CONNECT -#### Description +### Description -The `CONNECT` message is analogous to the [`INFO`](#info) message. Once the NATS server has established a TCP/IP socket connection with another server, and an [`INFO`](#info) message has been received, the server will send a `CONNECT` message to provide more information about the current connection as well as security information. +The `CONNECT` message is analogous to the [`INFO`](nats-server-protocol.md#info) message. Once the NATS server has established a TCP/IP socket connection with another server, and an [`INFO`](nats-server-protocol.md#info) message has been received, the server will send a `CONNECT` message to provide more information about the current connection as well as security information. -#### Syntax +### Syntax `CONNECT {["option_name":option_value],...}` @@ -84,26 +82,25 @@ The valid options are as follows: * `tls_required`: Indicates whether the server requires an SSL connection. * `auth_token`: Authorization token -* `user`: Connection username (if `auth_required` is set) -* `pass`: Connection password (if `auth_required` is set) +* `user`: Connection username \(if `auth_required` is set\) +* `pass`: Connection password \(if `auth_required` is set\) * `name`: Generated Server Name -* `lang`: The implementation language of the server (go). +* `lang`: The implementation language of the server \(go\). * `version`: The version of the server. -#### Example +### Example Here is an example from the default string from a server. `CONNECT {"tls_required":false,"name":"wt0vffeQyoDGMVBC2aKX0b"}\r\n` -## RS+ +## RS+ -#### Description +### Description -`RS+` initiates a subscription to a subject on on a given account, optionally with a distributed queue group name and weighting factor. -Note that queue subscriptions will use RS+ for increases and descreases to queue weight except when the weighting factor is 0. +`RS+` initiates a subscription to a subject on on a given account, optionally with a distributed queue group name and weighting factor. Note that queue subscriptions will use RS+ for increases and descreases to queue weight except when the weighting factor is 0. -#### Syntax +### Syntax **Subscription**: `RS+ \r\n` @@ -116,13 +113,13 @@ where: * `queue`: Optional queue group name * `weight`: Optional queue group weight representing how much interest/subscribers -## RS- +## RS- -#### Description +### Description `RS-` unsubcribes from the specified subject on the given account. It is sent by a server when it no longer has interest in a given subject. -#### Syntax +### Syntax **Subscription**: `RS- \r\n` @@ -133,11 +130,11 @@ where: ## RMSG -#### Description +### Description The `RMSG` protocol message delivers a message to another server. -#### Syntax +### Syntax `RMSG [reply-to] <#bytes>\r\n[payload]\r\n` @@ -151,19 +148,19 @@ where: ## PING/PONG -#### Description +### Description `PING` and `PONG` implement a simple keep-alive mechanism between servers. Once two servers establish a connection with each other, the NATS server will continuously send `PING` messages to other servers at a configurable interval. If another server fails to respond with a `PONG` message within the configured response interval, the server will terminate its connection. If your connection stays idle for too long, it is cut off. If the another server sends a ping request, a server will reply with a pong message to notify the other server that it is still present. -#### Syntax +### Syntax -`PING\r\n` -`PONG\r\n` +`PING\r\n` `PONG\r\n` ## -ERR -#### Description +### Description The `-ERR` message is used by the server to indicate a protocol, authorization, or other runtime connection error to another server. Most of these errors result in the remote server closing the connection. + diff --git a/nats_server/clients.md b/nats-server/clients.md similarity index 87% rename from nats_server/clients.md rename to nats-server/clients.md index 59639f9..30f84e5 100644 --- a/nats_server/clients.md +++ b/nats-server/clients.md @@ -1,25 +1,25 @@ -# NATS Clients +# Clients The nats-server doesn't come bundled with any clients. But most client libraries come with tools that allow you to publish, subscribe, send requests and reply messages. If you have a client library installed, you can try using a bundled client. Otherwise, you can easily install some clients. -### If you have Go installed: +## If you have Go installed: -``` +```text > go get github.com/nats-io/go-nats-examples/tools/nats-pub > go get github.com/nats-io/go-nats-examples/tools/nats-sub ``` -### Or download a zip file +## Or download a zip file You can install pre-built binaries from the [go-nats-examples repo](https://github.com/nats-io/go-nats-examples/releases/tag/0.0.50) +## Testing your setup -### Testing your setup +Open a terminal and [start a nats-server](running/): -Open a terminal and [start a nats-server](running.md): -``` +```text > nats-server [29670] 2019/05/16 08:45:59.836809 [INF] Starting nats-server version 2.0.0 [29670] 2019/05/16 08:45:59.836889 [INF] Git commit [not set] @@ -28,9 +28,9 @@ Open a terminal and [start a nats-server](running.md): [29670] 2019/05/16 08:45:59.837170 [INF] Server is ready ``` - On another terminal session start a subscriber: -``` + +```text > nats-sub ">" Listening on [>] ``` @@ -39,7 +39,7 @@ Note that when the client connected, the server didn't log anything interesting To make the server output more lively, you can specify the `-V` flag to enable logging of server protocol tracing messages. Go ahead and `+c` the process running the server, and restart the server with the `-V` flag: -``` +```text > nats-server -V [29785] 2019/05/16 08:46:12.731278 [INF] Starting nats-server version 2.0.0 [29785] 2019/05/16 08:46:12.731347 [INF] Git commit [not set] @@ -53,32 +53,32 @@ To make the server output more lively, you can specify the `-V` flag to enable l If you had created a subscriber, you should notice output on the subscriber telling you that it disconnected, and reconnected. The server output above is more interesting. You can see the subscriber send a `CONNECT` protocol message and a `PING` which was responded to by the server with a `PONG`. -> You can learn more about the [NATS protocol here](/nats_protocol/nats-protocol.md), but more intersting than the protocol description is [an interactive demo](/nats_protocol/nats-protocol-demo.md). +> You can learn more about the [NATS protocol here](../nats-protocol/nats-protocol/), but more intersting than the protocol description is [an interactive demo](../nats-protocol/nats-protocol-demo.md). On a third terminal, publish your first message: -``` + +```text > nats-pub hello world Published [hello] : 'world' ``` On the subscriber window you should see: -``` -[#1] Received on [hello]: 'world' + +```text + ``` - -### Testing Against a Remote Server +## Testing Against a Remote Server If the NATS server were running in a different machine or a different port, you'd have to specify that to the client by specifying a _NATS URL_. NATS URLs take the form of: `nats://:` and `tls://:`. URLs with a `tls` protocol sport a secured TLS connection. -``` +```text > nats-sub -s nats://server:port ">" ``` If you want to try on a remote server, the NATS team maintains a demo server you can reach at `demo.nats.io`. -``` +```text > nats-sub -s nats://demo.nats.io ">" ``` - diff --git a/nats_server/configuration.md b/nats-server/configuration/README.md similarity index 58% rename from nats_server/configuration.md rename to nats-server/configuration/README.md index 38c2aca..59921af 100644 --- a/nats_server/configuration.md +++ b/nats-server/configuration/README.md @@ -1,29 +1,31 @@ -# Configuration File Format +# Configuration While the NATS server has many flags that allow for simple testing of features, the NATS server products provide a flexible configuration format that combines the best of traditional formats and newer styles such as JSON and YAML. The NATS configuration file supports the following syntax: -- Lines can be commented with `#` and `//` -- Values can be assigned to properties with: - - Equals sign: `foo = 2` - - Colon: `foo: 2` - - Whitespace: `foo 2` -- Arrays are enclosed in brackets: `["a", "b", "c"]` -- Maps are enclosed in braces: `{foo: 2}` -- Maps can be assigned with no key separator -- Semicolons can be used as terminators +* Lines can be commented with `#` and `//` +* Values can be assigned to properties with: + * Equals sign: `foo = 2` + * Colon: `foo: 2` + * Whitespace: `foo 2` +* Arrays are enclosed in brackets: `["a", "b", "c"]` +* Maps are enclosed in braces: `{foo: 2}` +* Maps can be assigned with no key separator +* Semicolons can be used as terminators -### Strings and Numbers +## Strings and Numbers The configuration parser is very forgiving, as you have seen: -- values can be a primitive, or a list, or a map -- strings and numbers typically do the right thing + +* values can be a primitive, or a list, or a map +* strings and numbers typically do the right thing String values that start with a digit _can_ create issues. To force such values as strings, quote them. -*BAD Config*: -``` +_BAD Config_: + +```text listen: 127.0.0.1:4222 authorization: { # BAD! @@ -32,26 +34,27 @@ authorization: { ``` Fixed Config: -``` + +```text listen: 127.0.0.1:4222 authorization: { token: "3secret" } ``` -### Variables +## Variables -Server configurations can specify variables. Variables allow you to reference a value from one or more sections in the configuration. +Server configurations can specify variables. Variables allow you to reference a value from one or more sections in the configuration. Variables: -- Are block-scoped -- Are referenced with a `$` prefix. -- Can be resolved from environment variables having the same name + +* Are block-scoped +* Are referenced with a `$` prefix. +* Can be resolved from environment variables having the same name > If the environment variable value begins with a number you may have trouble resolving it depending on the server version you are running. - -``` +```text # Define a variable in the config TOKEN: "secret" @@ -63,7 +66,7 @@ authorization { A similar configuration, but this time, the value is in the environment: -``` +```text # TOKEN is defined in the environment authorization { token: $TOKEN @@ -72,14 +75,15 @@ authorization { export TOKEN="hello"; nats-server -c /config/file -### Include Directive +## Include Directive The `include` directive allows you to split a server configuration into several files. This is useful for separating configuration into chunks that you can easily reuse between different servers. -Includes *must* use relative paths, and are relative to the main configuration (the one specified via the `-c` option): +Includes _must_ use relative paths, and are relative to the main configuration \(the one specified via the `-c` option\): server.conf: -``` + +```text listen: 127.0.0.1:4222 include ./auth.conf ``` @@ -87,51 +91,52 @@ include ./auth.conf > Note that `include` is not followed by `=` or `:`, as it is a _directive_. auth.conf: -``` + +```text authorization: { token: "f0oBar" } ``` -``` +```text > nats-server -c server.conf ``` -### Configuration Properties +## Configuration Properties | Property | Description | -| :------ | :---- | -| [`authorization`](auth_intro.md) | Configuration map for client authentication/authorization | -| [`cluster`](cluster_config.md) | Configuration map for clustering configuration | -| `connect_error_reports` | Number of attempts at which a repeated failed route, gateway or leaf node connection is reported. Default is 3600, approx every hour. +| :--- | :--- | +| [`authorization`](securing_nats/auth_intro/) | Configuration map for client authentication/authorization | +| [`cluster`](clustering/cluster_config.md) | Configuration map for clustering configuration | +| `connect_error_reports` | Number of attempts at which a repeated failed route, gateway or leaf node connection is reported. Default is 3600, approx every hour. | | `debug` | If `true` enable debug log messages | -| [`gateway`](/gateways/gateway.md) | Gateway configuration map | +| [`gateway`](gateways/gateway.md) | Gateway configuration map | | `host` | Host for client connections | | [`http_port`](monitoring.md) | http port for server monitoring | | [`https_port`](monitoring.md) | https port for server monitoring | -| [`leafnode`](/leafnodes/leafnode_conf.md) | Leafnode configuration map | -| `listen` | Host/port for client connections | +| [`leafnode`](leafnodes/leafnode_conf.md) | Leafnode configuration map | +| `listen` | Host/port for client connections | | `max_connections` | Maximum number of active client connections | -| `max_control_line` | Maximum length of a protocol line (including subject length) | +| `max_control_line` | Maximum length of a protocol line \(including subject length\) | | `max_payload` | Maximum number of bytes in a message payload | | `max_pending` | Maximum number of bytes buffered for a connection | | `max_subscriptions` | Maximum numbers of subscriptions for a client connection | -| `max_traced_msg_len` | Set a limit to the trace of the payload of a message | -| `disable_sublist_cache` | Disable sublist cache globally for accounts. -| [`operator`](/nats_tools/nsc/nsc.md#nats-server-configuration) | Path to an operator JWT | -| [`ping_interval`](/developer/connecting/pingpong.md) | Interval in seconds in which the server checks if a connection is active | +| `max_traced_msg_len` | Set a limit to the trace of the payload of a message | +| `disable_sublist_cache` | Disable sublist cache globally for accounts. | +| [`operator`](../../nats-tools/nsc/nsc.md#nats-server-configuration) | Path to an operator JWT | +| [`ping_interval`](../../developing-with-nats/intro/pingpong.md) | Interval in seconds in which the server checks if a connection is active | | `port` | Port for client connections | -| `reconnect_error_reports` | Number of failed attempt to reconnect a route, gateway or leaf node connection. Default is to report every attempt. -| [`resolver`](/nats_tools/nsc/nsc.md#nats-server-configuration) | Resolver type `MEMORY` or `URL` for account JWTs | -| [`tls`](tls.md#tls-configuration) | Configuration map for tls for client and http monitoring | +| `reconnect_error_reports` | Number of failed attempt to reconnect a route, gateway or leaf node connection. Default is to report every attempt. | +| [`resolver`](../../nats-tools/nsc/nsc.md#nats-server-configuration) | Resolver type `MEMORY` or `URL` for account JWTs | +| [`tls`](securing_nats/tls.md#tls-configuration) | Configuration map for tls for client and http monitoring | | `trace` | If `true` enable protocol trace log messages | -| `write_deadline` | Maximum number of seconds the server will block when writing a to a client (slow consumer) | +| `write_deadline` | Maximum number of seconds the server will block when writing a to a client \(slow consumer\) | +## Configuration Reloading -### Configuration Reloading +A server can reload most configuration changes without requiring a server restart or clients to disconnect by sending the nats-server a [signal](../nats_admin/signals.md): -A server can reload most configuration changes without requiring a server restart or clients to disconnect by sending the nats-server a [signal](/nats_admin/signals.md): - -``` +```text > nats-server --signal reload ``` + diff --git a/nats_server/clustering.md b/nats-server/configuration/clustering/README.md similarity index 89% rename from nats_server/clustering.md rename to nats-server/configuration/clustering/README.md index 4210390..e19f278 100644 --- a/nats_server/clustering.md +++ b/nats-server/configuration/clustering/README.md @@ -1,5 +1,6 @@ -## NATS Server Clustering +# Clustering +## NATS Server Clustering NATS supports running each server in clustered mode. You can cluster servers together for high volume messaging systems and resiliency and high availability. Clients are cluster-aware. @@ -7,13 +8,13 @@ Note that NATS clustered servers have a forwarding limit of one hop. This means ## Cluster URLs -In addition to a port for listening for clients, `nats-server` can listen on a "cluster" URL (the `-cluster` option). Additional `nats-server` servers can then add that URL to their `-routes` argument to join the cluster. These options can also be specified in a config file, but only the command-line version is shown in this overview for simplicity. +In addition to a port for listening for clients, `nats-server` can listen on a "cluster" URL \(the `-cluster` option\). Additional `nats-server` servers can then add that URL to their `-routes` argument to join the cluster. These options can also be specified in a config file, but only the command-line version is shown in this overview for simplicity. ## Running a Simple Cluster Here is a simple cluster running on the same machine: -```sh +```bash # Server A - the 'seed server' > nats-server -p 4222 -cluster nats://0.0.0.0:5222 @@ -26,8 +27,7 @@ Here is a simple cluster running on the same machine: # Check the output of the server for the selected client and route ports. ``` -The _seed server_ simply declares its client and clustering port. All other servers delegate to the nats-server to auto-select a port that is not in use for both clients and cluster connections, and route to the seed server. Because the clustering protocol gossips members of the cluster, all servers are able to discover other server servers in the cluster. When a server is discovered, the discovering server will automatically attempt to connect to it in order to form a _full mesh_. Typically only one instance of the server will run per machine, so you can reuse the client port (4222) and the cluster port (5222), and simply the route to the host/port of the seed server. - +The _seed server_ simply declares its client and clustering port. All other servers delegate to the nats-server to auto-select a port that is not in use for both clients and cluster connections, and route to the seed server. Because the clustering protocol gossips members of the cluster, all servers are able to discover other server servers in the cluster. When a server is discovered, the discovering server will automatically attempt to connect to it in order to form a _full mesh_. Typically only one instance of the server will run per machine, so you can reuse the client port \(4222\) and the cluster port \(5222\), and simply the route to the host/port of the seed server. Similarly, clients connecting to any server in the cluster will discover other servers in the cluster. If the connection to the server is interrupted, the client will attempt to connect to all other known servers. @@ -35,10 +35,12 @@ Similarly, clients connecting to any server in the cluster will discover other s The following cluster options are supported: - --routes [rurl-1, rurl-2] Routes to solicit and connect - --cluster nats://host:port Cluster URL for solicited routes +```text +--routes [rurl-1, rurl-2] Routes to solicit and connect +--cluster nats://host:port Cluster URL for solicited routes +``` -When a NATS server routes to a specified URL, it will advertise its own cluster URL to all other servers in the route effectively creating a routing mesh to all other servers. +When a NATS server routes to a specified URL, it will advertise its own cluster URL to all other servers in the route effectively creating a routing mesh to all other servers. **Note:** when using the `-routes` option, you must also specify a `-cluster` option. @@ -48,13 +50,13 @@ Clustering can also be configured using the server [config file](cluster_config. The following example demonstrates how to run a cluster of 3 servers on the same host. We will start with the seed server and use the `-D` command line parameter to produce debug information. -```sh +```bash nats-server -p 4222 -cluster nats://localhost:5222 -D ``` Alternatively, you could use a configuration file, let's call it `seed.conf`, with a content similar to this: -```ascii +```text # Cluster Seed Node listen: 127.0.0.1:4222 @@ -67,22 +69,22 @@ cluster { And start the server like this: -```sh +```bash nats-server -config ./seed.conf -D ``` This will produce an output similar to: -```sh +```bash [75653] 2016/04/26 15:14:47.339321 [INF] Listening for route connections on 127.0.0.1:4248 [75653] 2016/04/26 15:14:47.340787 [INF] Listening for client connections on 127.0.0.1:4222 [75653] 2016/04/26 15:14:47.340822 [DBG] server id is xZfu3u7usAPWkuThomoGzM [75653] 2016/04/26 15:14:47.340825 [INF] server is ready ``` -It is also possible to specify the hostname and port independently. At the minimum, the port is required. If you leave the hostname off it will bind to all the interfaces ('0.0.0.0'). +It is also possible to specify the hostname and port independently. At the minimum, the port is required. If you leave the hostname off it will bind to all the interfaces \('0.0.0.0'\). -```ascii +```text cluster { host: 127.0.0.1 port: 4248 @@ -91,15 +93,15 @@ cluster { Now let's start two more servers, each one connecting to the seed server. -```sh +```bash nats-server -p 5222 -cluster nats://localhost:5248 -routes nats://localhost:4248 -D ``` -When running on the same host, we need to pick different ports for the client connections `-p`, and for the port used to accept other routes `-cluster`. Note that `-routes` points to the `-cluster` address of the seed server (`localhost:4248`). +When running on the same host, we need to pick different ports for the client connections `-p`, and for the port used to accept other routes `-cluster`. Note that `-routes` points to the `-cluster` address of the seed server \(`localhost:4248`\). -Here is the log produced. See how it connects and registers a route to the seed server (`...GzM`). +Here is the log produced. See how it connects and registers a route to the seed server \(`...GzM`\). -```sh +```bash [75665] 2016/04/26 15:14:59.970014 [INF] Listening for route connections on localhost:5248 [75665] 2016/04/26 15:14:59.971150 [INF] Listening for client connections on 0.0.0.0:5222 [75665] 2016/04/26 15:14:59.971176 [DBG] server id is 53Yi78q96t52QdyyWLKIyE @@ -113,7 +115,7 @@ Here is the log produced. See how it connects and registers a route to the seed From the seed's server log, we see that the route is indeed accepted: -```sh +```bash [75653] 2016/04/26 15:14:59.971602 [DBG] 127.0.0.1:52679 - rid:1 - Route connection created [75653] 2016/04/26 15:14:59.971733 [DBG] 127.0.0.1:52679 - rid:1 - Registering remote route "53Yi78q96t52QdyyWLKIyE" [75653] 2016/04/26 15:14:59.971739 [DBG] 127.0.0.1:52679 - rid:1 - Route sent local subscriptions @@ -121,13 +123,13 @@ From the seed's server log, we see that the route is indeed accepted: Finally, let's start the third server: -```sh +```bash nats-server -p 6222 -cluster nats://localhost:6248 -routes nats://localhost:4248 -D ``` Again, notice that we use a different client port and cluster address, but still point to the same seed server at the address `nats://localhost:4248`: -```sh +```bash [75764] 2016/04/26 15:19:11.528185 [INF] Listening for route connections on localhost:6248 [75764] 2016/04/26 15:19:11.529787 [INF] Listening for client connections on 0.0.0.0:6222 [75764] 2016/04/26 15:19:11.529829 [DBG] server id is IRepas80TBwJByULX1ulAp @@ -142,11 +144,11 @@ Again, notice that we use a different client port and cluster address, but still [75764] 2016/04/26 15:19:11.530664 [DBG] 127.0.0.1:52727 - rid:2 - Route sent local subscriptions ``` -First a route is created to the seed server (`...GzM`) and after that, a route from `...IyE` - which is the ID of the second server - is accepted. +First a route is created to the seed server \(`...GzM`\) and after that, a route from `...IyE` - which is the ID of the second server - is accepted. The log from the seed server shows that it accepted the route from the third server: -```sh +```bash [75653] 2016/04/26 15:19:11.530308 [DBG] 127.0.0.1:52726 - rid:2 - Route connection created [75653] 2016/04/26 15:19:11.530384 [DBG] 127.0.0.1:52726 - rid:2 - Registering remote route "IRepas80TBwJByULX1ulAp" [75653] 2016/04/26 15:19:11.530389 [DBG] 127.0.0.1:52726 - rid:2 - Route sent local subscriptions @@ -154,7 +156,7 @@ The log from the seed server shows that it accepted the route from the third ser And the log from the second server shows that it connected to the third. -```sh +```bash [75665] 2016/04/26 15:19:11.530469 [DBG] Trying to connect to route on 127.0.0.1:6248 [75665] 2016/04/26 15:19:11.530565 [DBG] 127.0.0.1:6248 - rid:2 - Route connection created [75665] 2016/04/26 15:19:11.530570 [DBG] 127.0.0.1:6248 - rid:2 - Route connect msg sent @@ -168,7 +170,7 @@ At this point, there is a full mesh cluster of NATS servers. Now, the following should work: make a subscription to Node A then publish to Node C. You should be able to to receive the message without problems. -```sh +```bash nats-sub -s "nats://192.168.59.103:7222" hello & nats-pub -s "nats://192.168.59.105:7222" hello world @@ -181,3 +183,4 @@ nats-pub -s "nats://192.168.59.105:7222" hello world # nats-server on Node A logs: [1] 2015/06/23 05:20:31.100600 [TRC] 10.0.2.2:51007 - cid:8 - <<- [MSG hello 2 5] ``` + diff --git a/nats_server/cluster_config.md b/nats-server/configuration/clustering/cluster_config.md similarity index 53% rename from nats_server/cluster_config.md rename to nats-server/configuration/clustering/cluster_config.md index a55404a..ef5a95b 100644 --- a/nats_server/cluster_config.md +++ b/nats-server/configuration/clustering/cluster_config.md @@ -1,17 +1,16 @@ -## Cluster Configuration +# Configuration The `cluster` configuration map has the following configuration options: | Property | Description | -| :------ | :---- | -| `listen` | host/port for inbound route connections | -| `authorization` | [authorization](authorization.md) map for configuring cluster clients. Supports `token`, `username`/`password` and `TLS authentication`. `permissions` are ignored. | -| `timeout` | Maximum amount of time (in seconds) to wait for a clustering connection to complete -| `tls` | A [`tls` configuration map](tls.md#tls-configuration) for securing the clustering connection | -| `routes` | A list of other servers (URLs) to cluster with. Self-routes are ignored. | +| :--- | :--- | +| `listen` | host/port for inbound route connections | +| `authorization` | [authorization](../securing_nats/authorization.md) map for configuring cluster clients. Supports `token`, `username`/`password` and `TLS authentication`. `permissions` are ignored. | +| `timeout` | Maximum amount of time \(in seconds\) to wait for a clustering connection to complete | +| `tls` | A [`tls` configuration map](../securing_nats/tls.md#tls-configuration) for securing the clustering connection | +| `routes` | A list of other servers \(URLs\) to cluster with. Self-routes are ignored. | - -```ascii +```text cluster { listen: localhost:4244 # host/port for inbound route connections @@ -31,4 +30,5 @@ cluster { nats-route://user2:pass2@127.0.0.1:4246 ] } -``` \ No newline at end of file +``` + diff --git a/nats_server/cluster_tls.md b/nats-server/configuration/clustering/cluster_tls.md similarity index 89% rename from nats_server/cluster_tls.md rename to nats-server/configuration/clustering/cluster_tls.md index 1172f7a..4688e4d 100644 --- a/nats_server/cluster_tls.md +++ b/nats-server/configuration/clustering/cluster_tls.md @@ -1,10 +1,10 @@ -## Cluster TLS Mutual Authentication +# TLS Authentication When setting up clusters all servers in the cluster, if using TLS, will both verify the connecting endpoints and the server responses. So certificates are checked in both directions. Certificates can be configured only for the server's cluster identity, keeping client and server certificates separate from cluster formation. -TLS Mutual Authentication *is the recommended way* of securing routes. +TLS Mutual Authentication _is the recommended way_ of securing routes. -``` +```text cluster { listen: 127.0.0.1:4244 @@ -25,3 +25,4 @@ cluster { ] } ``` + diff --git a/gateways/README.md b/nats-server/configuration/gateways/README.md similarity index 83% rename from gateways/README.md rename to nats-server/configuration/gateways/README.md index a26d8ba..6a28fea 100644 --- a/gateways/README.md +++ b/nats-server/configuration/gateways/README.md @@ -1,37 +1,38 @@ +# Gateways + ## Gateways Gateways enable connecting one or more clusters together; they allow the formation of super clusters from smaller clusters. Cluster and Gateway protocols listen in different ports. Clustering is used for adjacent servers; gateways are for joining clusters together. Typically all cluster nodes will also be gateway nodes, but this is not a requirement. Gateway configuration is similar to clustering: -- gateways have a dedicated port where they listen for gateway requests -- gateways gossip gateway members and remote discovered gateways +* gateways have a dedicated port where they listen for gateway requests +* gateways gossip gateway members and remote discovered gateways Unlike clusters, gateways: -- don't form a full mesh -- are bound by uni-directional connections +* don't form a full mesh +* are bound by uni-directional connections Gateways exist to: -- reduce the number of connections required between servers -- optimize the interest graph propagation +* reduce the number of connections required between servers +* optimize the interest graph propagation ## Gateway Connections -A nats-server in a gateway role will specify a port where it will accept gateways connections. If the configuration specifies other _external_ `gateways`, the gateway will create one outbound gateway connection for each gateway in its configuration. It will also gossip other gateways it knows or discovered. +A nats-server in a gateway role will specify a port where it will accept gateways connections. If the configuration specifies other _external_ `gateways`, the gateway will create one outbound gateway connection for each gateway in its configuration. It will also gossip other gateways it knows or discovered. If the local cluster has three gateway nodes, this means there will be three outbound connections to each external gateway. -![Gateway Connections](simple.svg) +![Gateway Connections](../../../.gitbook/assets/simple.svg) -> In the example above cluster _A_ has configured gateway connections for _B_ (solid lines). B has discovered gateway connections to _A_ (dotted lines). Note that the number of outgoing connections always matches the number of gateways with the same name. +> In the example above cluster _A_ has configured gateway connections for _B_ \(solid lines\). B has discovered gateway connections to _A_ \(dotted lines\). Note that the number of outgoing connections always matches the number of gateways with the same name. -![Gateway Discovered Gateways](three_gw.svg) +![Gateway Discovered Gateways](../../../.gitbook/assets/three_gw.svg) > In this second example, again configured connections are shown with solid lines and discovered gateway connections are shown using dotted lines. Gateways _A_ and _C_ were both discovered via gossiping; _B_ discovered _A_ and _A_ discovered _C_. - A key point in the description above is that each node in the cluster will make a connection to a single node in the remote cluster — a difference from the clustering protocol, where every node is directly connected to all other nodes. For those mathematically inclined, cluster connections are `N(N-1)/2` where _N_ is the number of nodes in the cluster. On gateway configurations, outbound connections are the summation of `Ni(M-1)` where Ni is the number of nodes in a gateway _i_, and _M_ is the total number of gateways. Inbound connections are the summation of `U-Ni` where U is the sum of all gateway nodes in all gateways, and N is the number of nodes in a gateway _i_. It works out that both inbound and outbound connection counts are the same. @@ -39,8 +40,8 @@ For those mathematically inclined, cluster connections are `N(N-1)/2` where _N_ The number of connections required to join clusters using clustering vs. gateways is apparent very quickly. For 3 clusters, with N nodes: | Nodes per Cluster | Full Mesh Conns | Gateway Conns | -| ---: | ----: | ----: | -| 1 | 3 | 6| +| ---: | ---: | ---: | +| 1 | 3 | 6 | | 2 | 15 | 12 | | 3 | 36 | 18 | | 4 | 66 | 24 | @@ -51,9 +52,9 @@ The number of connections required to join clusters using clustering vs. gateway Gateways propagate interest using three different mechanisms: -- Optimistic Mode -- Interest-only Mode -- Queue Subscriptions +* Optimistic Mode +* Interest-only Mode +* Queue Subscriptions ### Optimistic Mode @@ -74,3 +75,4 @@ Queue subscriptions work on _Interest-only Mode_ to honor NATS' queue semantics ### Gateway Configuration The [Gateway Configuration](gateway.md) document describes all the options available to gateways. + diff --git a/gateways/gateway.md b/nats-server/configuration/gateways/gateway.md similarity index 73% rename from gateways/gateway.md rename to nats-server/configuration/gateways/gateway.md index 8701963..456c220 100644 --- a/gateways/gateway.md +++ b/nats-server/configuration/gateways/gateway.md @@ -1,28 +1,28 @@ - -## Gateway Configuration +# Configuration The `gateway` configuration block is similar to a `cluster` block: -```hcl +```text gateway { - name: "A" - listen: "localhost:7222" - authorization { - user: gwu - password: gwp - } + name: "A" + listen: "localhost:7222" + authorization { + user: gwu + password: gwp + } - gateways: [ - {name: "A", url: "nats://gwu:gwp@localhost:7222"}, - {name: "B", url: "nats://gwu:gwp@localhost:7333"}, - {name: "C", url: "nats://gwu:gwp@localhost:7444"}, - ] + gateways: [ + {name: "A", url: "nats://gwu:gwp@localhost:7222"}, + {name: "B", url: "nats://gwu:gwp@localhost:7333"}, + {name: "C", url: "nats://gwu:gwp@localhost:7444"}, + ] } ``` One difference is that instead of `routes` you specify `gateways`. As expected _self-gateway_ connections are ignored, so you can share gateway configurations with minimal fuzz. -Starting a server: +Starting a server: + ```text > nats-server -c A.conf [85803] 2019/05/07 10:50:55.902474 [INF] Starting nats-server version 2.0.0 @@ -45,6 +45,7 @@ Starting a server: ``` Once all the gateways are up, these clusters of one will forward messages as expected: + ```text > nats-pub -s localhost:4444 foo bar Published [foo] : 'bar' @@ -52,15 +53,14 @@ Published [foo] : 'bar' # On a different session... > nats-sub -s localhost:4333 ">" Listening on [>] -[#1] Received on [foo]: 'bar' ``` -### `Gateway` Configuration Block +## `Gateway` Configuration Block | Property | Description | -| :------ | :---- | +| :--- | :--- | | `advertise` | Hostport `:` to advertise to other gateways. | -| `authorization` | Authorization block (same as other nats-server `authorization` configuration). | +| `authorization` | Authorization block \(same as other nats-server `authorization` configuration\). | | `connect_retries` | Number of times the server will try to connect to a discovered gateway. | | `gateways` | List of Gateway entries - see below. | | `host` | Interface where the gateway will listen for incomming gateway connections. | @@ -68,34 +68,30 @@ Listening on [>] | `name` | Name for this cluster, all gateways belonging to the same cluster, should specify the same name. | | `port` | Port where the gateway will listen for incomming gateway connections. | | `reject_unknown` | If `true`, gateway will reject connections from gateways that are not configured in `gateways`. | -| `tls` | TLS configuration block (same as other [nats-server `tls` configuration](/nats_server/tls.md#tls-configuration)). | +| `tls` | TLS configuration block \(same as other [nats-server `tls` configuration](../securing_nats/tls.md#tls-configuration)\). | - - -#### `Gateway` Entry +### `Gateway` Entry The `gateways` configuration block is a list of gateway entries with the following properties: | Property | Description | -| :------ | :---- | +| :--- | :--- | | `name` | Gateway name. | | `url` | Hostport `:` describing where the remote gateway can be reached. If multiple IPs are returned, one is randomly selected. | | `urls` | A list of `url` | -By using `urls` and an array, you can specify a list of endpoints that -form part of a cluster as below. A NATS Server will pick one of those -addresses randomly and only establish a single outbound gateway -connection to one of the members from another cluster: +By using `urls` and an array, you can specify a list of endpoints that form part of a cluster as below. A NATS Server will pick one of those addresses randomly and only establish a single outbound gateway connection to one of the members from another cluster: -```hcl +```text gateway { - name: "DC-A" - listen: "localhost:7222" + name: "DC-A" + listen: "localhost:7222" - gateways: [ - {name: "DC-A", urls: ["nats://localhost:7222", "nats://localhost:7223", "nats://localhost:7224"]}, - {name: "DC-B", urls: ["nats://localhost:7332", "nats://localhost:7333", "nats://localhost:7334"]}, - {name: "DC-C", urls: ["nats://localhost:7442", "nats://localhost:7333", "nats://localhost:7335"]} - ] + gateways: [ + {name: "DC-A", urls: ["nats://localhost:7222", "nats://localhost:7223", "nats://localhost:7224"]}, + {name: "DC-B", urls: ["nats://localhost:7332", "nats://localhost:7333", "nats://localhost:7334"]}, + {name: "DC-C", urls: ["nats://localhost:7442", "nats://localhost:7333", "nats://localhost:7335"]} + ] } ``` + diff --git a/leafnodes/README.md b/nats-server/configuration/leafnodes/README.md similarity index 78% rename from leafnodes/README.md rename to nats-server/configuration/leafnodes/README.md index eb54847..2bc4561 100644 --- a/leafnodes/README.md +++ b/nats-server/configuration/leafnodes/README.md @@ -1,23 +1,24 @@ -## Leaf Nodes +# Leaf Nodes A _Leaf Node_ allows an extension to a cluter or supercluster that bridges accounts and security domains. This is useful in IoT and edge scenarios and when the local server traffic should be low RTT and local unless routed to the super cluster. -Leaf Nodes leverage [accounts](../nats_server/jwt_auth.md) and JWTs to enable a server to connect to another and filter messages as per the leaf node's account user configuration. +Leaf Nodes leverage [accounts](../securing_nats/auth_intro/jwt_auth.md) and JWTs to enable a server to connect to another and filter messages as per the leaf node's account user configuration. This effectively means that the leaf node clusters with the other server at an account level: -- Leaf nodes clients authenticate locally (or just connect if authentication is not required) -- Traffic between the leaf node and the cluster assumes the restrictions of the user configuration used to create the leaf connection. - - Subjects that the user is allowed to publish are exported to the cluster. - - Subjects the user is allowed to subscribe to, are imported into the leaf node. +* Leaf nodes clients authenticate locally \(or just connect if authentication is not required\) +* Traffic between the leaf node and the cluster assumes the restrictions of the user configuration used to create the leaf connection. + * Subjects that the user is allowed to publish are exported to the cluster. + * Subjects the user is allowed to subscribe to, are imported into the leaf node. -> Leaf Nodes are an important component as a way to bridge traffic between local NATS servers you control and servers that are managed by a third-party. Synadia's [NATS Global Service (NGS)](https://www.synadia.com/) allows accounts to use leaf nodes, but gain accessibility to the global network to inexpensively connect geographically distributed servers or small clusters. +> Leaf Nodes are an important component as a way to bridge traffic between local NATS servers you control and servers that are managed by a third-party. Synadia's [NATS Global Service \(NGS\)](https://www.synadia.com/) allows accounts to use leaf nodes, but gain accessibility to the global network to inexpensively connect geographically distributed servers or small clusters. [LeafNode Configuration Options](leafnode_conf.md) -### LeafNode Configuration Tutorial +## LeafNode Configuration Tutorial Create a new operator called "O": + ```text > nsc add operator -n O Generated operator key - private key stored "~/.nkeys/O/O.nk" @@ -25,6 +26,7 @@ Success! - added operator "O" ``` Create an account called "A": + ```text > nsc add account -n A Generated account key - private key stored "~/.nkeys/O/accounts/A/A.nk" @@ -32,6 +34,7 @@ Success! - added account "A" ``` Create an user called "leaf": + ```text > nsc add user -n leaf Generated user key - private key stored "~/.nkeys/O/accounts/A/users/leaf.nk" @@ -40,6 +43,7 @@ Success! - added user "leaf" to "A" ``` Let's create an second user called 'nolimit' + ```text > nsc add user -n nolimit Generated user key - private key stored "~/.nkeys/O/accounts/A/users/nolimit.nk" @@ -48,91 +52,104 @@ Success! - added user "nolimit" to "A" ``` Start a nats-account-server: + ```text > nats-account-server -nsc ~/.nsc/nats/O ``` -Create the server configuration file (server.conf) with the following contents: +Create the server configuration file \(server.conf\) with the following contents: + ```text operator: /Users/synadia/.nsc/nats/O/O.jwt resolver: URL(http://localhost:9090/jwt/v1/accounts/) leafnodes { - listen: "127.0.0.1:4000" + listen: "127.0.0.1:4000" } ``` + The server configuration naturally requires an `operator` and `resolver` to deal with the JWT authentication and accounts. In addition the `leafnodes` configuration exposes a `listen` where the server will receive leaf nodes. In this case on the localhost on port 4000. Start the nats-server: + ```text > nats-server -c server.conf ``` Create a subscriber on the server: + ```text > nats-sub -creds ~/.nkeys/O/accounts/A/users/nolimit.creds ">" Listening on [>] ``` +Create the leaf server configuration \(leaf.conf\) with the following contents: -Create the leaf server configuration (leaf.conf) with the following contents: ```text port: 4111 leafnodes { - remotes = [ - { - url: "nats-leaf://localhost:4000" - credentials: "/Users/synadia/.nkeys/O/accounts/A/users/leaf.creds" - }, - ] + remotes = [ + { + url: "nats-leaf://localhost:4000" + credentials: "/Users/synadia/.nkeys/O/accounts/A/users/leaf.creds" + }, + ] } ``` + Note the leaf node configuration lists a number of `remotes`. The `url` specifies the port on the server where leaf node connections are allowed. The `credentials` configuration specifies the path to a user's credentials file. -The leaf server configuration (leaf.conf) also supports multiple URLs with `urls` such as the following: +The leaf server configuration \(leaf.conf\) also supports multiple URLs with `urls` such as the following: + ```text port: 4111 leafnodes { - remotes = [ - { - urls: ["nats-leaf://host1:4000", "nats-leaf://host2:4000"] - credentials: "/Users/synadia/.nkeys/O/accounts/A/users/leaf.creds" - }, - ] + remotes = [ + { + urls: ["nats-leaf://host1:4000", "nats-leaf://host2:4000"] + credentials: "/Users/synadia/.nkeys/O/accounts/A/users/leaf.creds" + }, + ] } ``` Create a subscriber on the leaf: + ```text > nats-sub -s localhost:4111 ">" Listening on [>] ``` Publish a message on the server: + ```text > nats-pub -creds ~/.nkeys/O/accounts/A/users/leaf.creds foo foo Published [foo] : 'foo' ``` Both the server and leaf subscriber print: + ```text -[#1] Received on [foo]: 'foo' + ``` Publish a message on the leaf: + ```text > nats-pub -s localhost:4111 bar bar Published [bar] : 'bar' ``` + Both the server and leaf subscribers print: + ```text -[#2] Received on [bar]: 'bar' + ``` The leaf forwards all local messages to the server where members of the account are able to receive them. Messages published on the server by the account are forwarded to the leaf where subscribers are able to receive them. -### Leaf Authorization +## Leaf Authorization -In some cases you may want to restrict what messages can be exported from the leaf node or imported from the account. For leaf servers this is simply a user account configuration, as users can have specific permissions on what subjects to publish and/or subscribe to. +In some cases you may want to restrict what messages can be exported from the leaf node or imported from the account. For leaf servers this is simply a user account configuration, as users can have specific permissions on what subjects to publish and/or subscribe to. Let's put some restrictions on the `leaf` user so that it can only publish to `foo` and subscribe to `bar`: @@ -174,22 +191,26 @@ Let's repeat the experiment. This time we'll restart the leaf server so that the ``` You should see a new message on the leaf subscriber: + ```text Reconnected [nats://localhost:4111] ``` Let's publish a message on the leaf: + ```text > nats-pub -s localhost:4111 foo foo Published [foo] : 'foo' ``` You should see a new message in all your subscriber windows: + ```text -[#3] Received on [foo]: 'foo' + ``` Now publish a new message on the leaf, but this time with the subject `bar`: + ```text > nats-pub -s localhost:4111 bar bar Published [bar] : 'bar' @@ -197,28 +218,26 @@ Published [bar] : 'bar' This time only the leaf subscriber will print `[#4] Received on [bar]: 'bar'`, the account subscriber won't print it because the leaf user doesn't have permissions to publish on 'bar'. - Let's try the flow of messages from the server to the leaf node: -``` + +```text > nats-pub -creds ~/.nkeys/O/accounts/A/users/leaf.creds foo foo Published [foo] : 'foo' ``` + Only the server subscriber will receive the message as expected. Repeat the publish this time with 'bar': -``` +```text > nats-pub -creds ~/.nkeys/O/accounts/A/users/leaf.creds bar bar Published [bar] : 'bar' ``` + Both subscribers will receive the message as expected. As you can see: -- Messages to and from the leaf node to the server are limited by the user associated with the leaf node connection. -- Messages within the leaf node are as per the server's authentication and authorization configuration - - - - +* Messages to and from the leaf node to the server are limited by the user associated with the leaf node connection. +* Messages within the leaf node are as per the server's authentication and authorization configuration diff --git a/leafnodes/leafnode_conf.md b/nats-server/configuration/leafnodes/leafnode_conf.md similarity index 75% rename from leafnodes/leafnode_conf.md rename to nats-server/configuration/leafnodes/leafnode_conf.md index 1498c23..44488e9 100644 --- a/leafnodes/leafnode_conf.md +++ b/nats-server/configuration/leafnodes/leafnode_conf.md @@ -1,39 +1,37 @@ -## `leafnodes` Configuration Block +# Configuration | Property | Description | -| :------ | :---- | +| :--- | :--- | | `advertise` | Hostport `:` to advertise to other servers. | -| `authorization` | Authorization block (same as other nats-server `authorization` configuration). | +| `authorization` | Authorization block \(same as other nats-server `authorization` configuration\). | | `host` | Interface where the server will listen for incoming leafnode connections. | | `listen` | Combines `host` and `port` as `:` | | `no_advertise` | if `true` the leafnode shouldn't be advertised. | | `port` | Port where the server will listen for incoming leafnode connections. | | `remotes` | List of `remote` entries specifying servers where leafnode client connection can be made. | -| `tls` | TLS configuration block (same as other nats-server `tls` configuration). | +| `tls` | TLS configuration block \(same as other nats-server `tls` configuration\). | - -### LeafNode `remotes` Entry Block +## LeafNode `remotes` Entry Block | Property | Description | -| :------ | :---- | -| `url` | Leafnode URL (URL protocol should be `nats-leaf`). | -| `urls` | Leafnode URL array. Supports multiple URLs for discovery, e.g., urls: [ "nats-leaf://host1:7422", "nats-leaf://host2:7422" ]| +| :--- | :--- | +| `url` | Leafnode URL \(URL protocol should be `nats-leaf`\). | +| `urls` | Leafnode URL array. Supports multiple URLs for discovery, e.g., urls: \[ "nats-leaf://host1:7422", "nats-leaf://host2:7422" \] | | `account` | Account public key identifying the leafnode. Account must be defined locally. | | `credentials` | Credential file for connecting to the leafnode server. | | `tls` | A TLS configuration block. Leafnode client will use specified TLS certificates when connecting/authenticating. | -### `tls` Configuration Block +## `tls` Configuration Block | Property | Description | -| :------ | :---- | +| :--- | :--- | | `cert_file` | TLS certificate file. | | `key_file` | TLS certificate key file. | | `ca_file` | TLS certificate authority file. | | `insecure` | Skip certificate verification. | | `verify` | If `true`, require and verify client certificates. | | `verify_and_map` | If `true`, require and verify client certificates and use values map certificate values for authentication purposes. | -| `cipher_suites` | When set, only the specified TLS cipher suites will be allowed. Values must match golang version used to build the server. | +| `cipher_suites` | When set, only the specified TLS cipher suites will be allowed. Values must match golang version used to build the server. | | `curve_preferences` | List of TLS cypher curves to use in order. | | `timeout` | TLS handshake timeout in fractional seconds. | - diff --git a/nats_server/logging.md b/nats-server/configuration/logging.md similarity index 61% rename from nats_server/logging.md rename to nats-server/configuration/logging.md index 85779b5..71de673 100644 --- a/nats_server/logging.md +++ b/nats-server/configuration/logging.md @@ -1,31 +1,34 @@ +# Logging ## Configuring Logging -The NATS server provides various logging options that you can set via the command line or the configuration file. +The NATS server provides various logging options that you can set via the command line or the configuration file. ### Command Line Options The following logging operations are supported: - -l, --log FILE File to redirect log output. - -T, --logtime Timestamp log entries (default is true). - -s, --syslog Enable syslog as log method. - -r, --remote_syslog Syslog server address. - -D, --debug Enable debugging output. - -V, --trace Trace the raw protocol. - -DV Debug and Trace. +```text +-l, --log FILE File to redirect log output. +-T, --logtime Timestamp log entries (default is true). +-s, --syslog Enable syslog as log method. +-r, --remote_syslog Syslog server address. +-D, --debug Enable debugging output. +-V, --trace Trace the raw protocol. +-DV Debug and Trace. +``` #### Debug and trace The `-DV` flag enables trace and debug for the server. -```sh +```bash nats-server -DV -m 8222 -user foo -pass bar ``` #### Log file redirect -```sh +```bash nats-server -DV -m 8222 -l nats.log ``` @@ -37,19 +40,19 @@ If `-T false` then log entries are not timestamped. Default is true. You can configure syslog with `UDP`: -```sh +```bash nats-server -s udp://localhost:514 ``` or `syslog:` -```sh +```bash nats-server -r syslog://: ``` For example: -```sh +```bash syslog://logs.papertrailapp.com:26900 ``` @@ -57,7 +60,7 @@ syslog://logs.papertrailapp.com:26900 All of these settings are available in the configuration file as well. -```ascii +```text debug: false trace: true logtime: false @@ -66,11 +69,11 @@ log_file: "/tmp/nats-server.log" ### Log Rotation with logrotate -NATS server does not provide tools to manage log files, but it does include mechanisms that make log rotation simple. We can use this mechanism with [logrotate](https://github.com/logrotate/logrotate); a simple standard Linux utility to rotate logs available on most distributions like Debian, Ubuntu, RedHat (CentOS), etc. +NATS server does not provide tools to manage log files, but it does include mechanisms that make log rotation simple. We can use this mechanism with [logrotate](https://github.com/logrotate/logrotate); a simple standard Linux utility to rotate logs available on most distributions like Debian, Ubuntu, RedHat \(CentOS\), etc. For example, you could configure `logrotate` with: -```ascii +```text /path/to/nats-server.log { daily rotate 30 @@ -85,12 +88,13 @@ For example, you could configure `logrotate` with: The first line specifies the location that the subsequent lines will apply to. -The rest of the file specifies that the logs will rotate daily ("daily" option) and that 30 older copies will be preserved ("rotate" option). Other options are described in [logrorate documentation](https://linux.die.net/man/8/logrotate). +The rest of the file specifies that the logs will rotate daily \("daily" option\) and that 30 older copies will be preserved \("rotate" option\). Other options are described in [logrorate documentation](https://linux.die.net/man/8/logrotate). -The "postrotate" section tells NATS server to reload the log files once the rotation is complete. The command ```kill -SIGUSR1 `cat /var/run/nats-server.pid` ``` does not kill the NATS server process, but instead sends it a signal causing it to reload its log files. This will cause new requests to be logged to the refreshed log file. +The "postrotate" section tells NATS server to reload the log files once the rotation is complete. The command ``kill -SIGUSR1 `cat /var/run/nats-server.pid``` does not kill the NATS server process, but instead sends it a signal causing it to reload its log files. This will cause new requests to be logged to the refreshed log file. The `/var/run/nats-server.pid` file is where NATS server stores the master process's pid. ## Some Logging Notes -- The NATS server, in verbose mode, will log the receipt of `UNSUB` messages, but this does not indicate the subscription is gone, only that the message was received. The `DELSUB` message in the log can be used to determine when the actual subscription removal has taken place. \ No newline at end of file +* The NATS server, in verbose mode, will log the receipt of `UNSUB` messages, but this does not indicate the subscription is gone, only that the message was received. The `DELSUB` message in the log can be used to determine when the actual subscription removal has taken place. + diff --git a/nats_server/monitoring.md b/nats-server/configuration/monitoring.md similarity index 62% rename from nats_server/monitoring.md rename to nats-server/configuration/monitoring.md index dc494c3..9ec4a22 100644 --- a/nats_server/monitoring.md +++ b/nats-server/configuration/monitoring.md @@ -1,14 +1,15 @@ +# Monitoring + ## Monitoring NATS -To monitor the NATS messaging system, `nats-server` provides a lightweight HTTP server on a dedicated monitoring port. -The monitoring server provides several endpoints, providing statistics and other information about the following: +To monitor the NATS messaging system, `nats-server` provides a lightweight HTTP server on a dedicated monitoring port. The monitoring server provides several endpoints, providing statistics and other information about the following: -* [General Server Information](#general-information) -* [Connections](#connection-information) -* [Routing](#route-information) -* [Gateways](#gateway-information) -* [Leaf Nodes](#leaf-nodes-information) -* [Subscription Routing](#subscription-routing-information) +* [General Server Information](monitoring.md#general-information) +* [Connections](monitoring.md#connection-information) +* [Routing](monitoring.md#route-information) +* [Gateways](monitoring.md#gateway-information) +* [Leaf Nodes](monitoring.md#leaf-nodes-information) +* [Subscription Routing](monitoring.md#subscription-routing-information) All endpoints return a JSON object. @@ -16,14 +17,16 @@ The NATS monitoring endpoints support JSONP and CORS, making it easy to create s ### Enabling monitoring from the command line -To enable the monitoring server, start the NATS server with the monitoring flag `-m` and the monitoring port, or turn it on in the [configuration file](configuration.md#configuration-properties). +To enable the monitoring server, start the NATS server with the monitoring flag `-m` and the monitoring port, or turn it on in the [configuration file](./#configuration-properties). - -m, --http_port PORT HTTP PORT for monitoring - -ms,--https_port PORT Use HTTPS PORT for monitoring +```text +-m, --http_port PORT HTTP PORT for monitoring +-ms,--https_port PORT Use HTTPS PORT for monitoring +``` Example: -```sh +```bash $ nats-server -m 8222 [4528] 2019/06/01 20:09:58.572939 [INF] Starting nats-server version 2.0.0 [4528] 2019/06/01 20:09:58.573007 [INF] Starting http monitor on port 8222 @@ -31,7 +34,7 @@ $ nats-server -m 8222 [4528] 2019/06/01 20:09:58.573090 [INF] nats-server is ready ``` -To test, run `nats-server -m 8222`, then go to http://demo.nats.io:8222/ +To test, run `nats-server -m 8222`, then go to [http://demo.nats.io:8222/](http://demo.nats.io:8222/) ### Enable monitoring from the configuration file @@ -41,13 +44,11 @@ You can also enable monitoring using the configuration file as follows: http_port: 8222 ``` -For example, to monitor this server locally, the endpoint would be http://demo.nats.io:8222/varz reports various general statistics. +For example, to monitor this server locally, the endpoint would be [http://demo.nats.io:8222/varz](http://demo.nats.io:8222/varz) reports various general statistics. ## Monitoring endpoints -The following sections describe each supported monitoring endpoint: `varz`, `connz`, `routez`, `subsz`, and `gatewayz`. -There are not any required arguments, however use of arguments can let you tailor monitoring to your environment -and tooling. +The following sections describe each supported monitoring endpoint: `varz`, `connz`, `routez`, `subsz`, and `gatewayz`. There are not any required arguments, however use of arguments can let you tailor monitoring to your environment and tooling. ### General Information @@ -55,10 +56,10 @@ The `/varz` endpoint returns general information about the server state and conf **Endpoint:** `http://server:port/varz` -| Result | Return Code | -|:---|:----| -| Success | 200 (OK) | -| Error | 400 (Bad Request) | +| Result | Return Code | +| :--- | :--- | +| Success | 200 \(OK\) | +| Error | 400 \(Bad Request\) | #### Arguments @@ -66,11 +67,11 @@ N/A #### Example -http://demo.nats.io:8222/varz +[http://demo.nats.io:8222/varz](http://demo.nats.io:8222/varz) #### Response -```json +```javascript { "server_id": "NACDVKFBUW4C4XA24OOT6L4MDP56MW76J5RJDFXG7HLABSB46DCMWCOW", "version": "2.0.0", @@ -124,61 +125,60 @@ N/A ### Connection Information -The `/connz` endpoint reports more detailed information on current and recently closed connections. -It uses a paging mechanism which defaults to 1024 connections. +The `/connz` endpoint reports more detailed information on current and recently closed connections. It uses a paging mechanism which defaults to 1024 connections. **Endpoint:** `http://server:port/connz` -| Result | Return Code | -|:---|:---| -| Success | 200 (OK) | -| Error | 400 (Bad Request) | +| Result | Return Code | +| :--- | :--- | +| Success | 200 \(OK\) | +| Error | 400 \(Bad Request\) | #### Arguments | Argument | Values | Description | -|:---|:---|:---| -| sort | (*see sort options*) | Sorts the results. Default is connection ID. | -| auth | true, 1, false, 0 | Include username. Default is false. | -| subs | true, 1, false, 0 | Include subscriptions. Default is false. | -| offset | number > 0 | Pagination offset. Default is 0. | -| limit | number > 0 | Number of results to return. Default is 1024. | -| cid | number, valid id | Return a connection by it's id | -| state | open, *closed, any | Return connections of partular state. Default is open. | +| :--- | :--- | :--- | +| sort | \(_see sort options_\) | Sorts the results. Default is connection ID. | +| auth | true, 1, false, 0 | Include username. Default is false. | +| subs | true, 1, false, 0 | Include subscriptions. Default is false. | +| offset | number > 0 | Pagination offset. Default is 0. | +| limit | number > 0 | Number of results to return. Default is 1024. | +| cid | number, valid id | Return a connection by it's id | +| state | open, \*closed, any | Return connections of partular state. Default is open. | -*The server will default to holding the last 10,000 closed connections.* +_The server will default to holding the last 10,000 closed connections._ -##### Sort Options +**Sort Options** -| Option | Sort by| -|:---|:---| -|cid | Connection ID | -|start | Connection start time, same as CID | -|subs | Number of subscriptions | -|pending | Amount of data in bytes waiting to be sent to client | -|msgs_to | Number of messages sent | -|msgs_from | Number of messages received | -|bytes_to | Number of bytes sent | -|bytes_from | Number of bytes received | -|last | Last activity | -|idle | Amount of inactivity | -|uptime | Lifetime of the connection | -|stop | Stop time for a closed connection | -|reason | Reason for a closed connection | +| Option | Sort by | +| :--- | :--- | +| cid | Connection ID | +| start | Connection start time, same as CID | +| subs | Number of subscriptions | +| pending | Amount of data in bytes waiting to be sent to client | +| msgs\_to | Number of messages sent | +| msgs\_from | Number of messages received | +| bytes\_to | Number of bytes sent | +| bytes\_from | Number of bytes received | +| last | Last activity | +| idle | Amount of inactivity | +| uptime | Lifetime of the connection | +| stop | Stop time for a closed connection | +| reason | Reason for a closed connection | #### Examples -Get up to 1024 connections: http://demo.nats.io:8222/connz +Get up to 1024 connections: [http://demo.nats.io:8222/connz](http://demo.nats.io:8222/connz) -Control limit and offset: http://demo.nats.io:8222/connz?limit=16&offset=128. +Control limit and offset: [http://demo.nats.io:8222/connz?limit=16&offset=128](http://demo.nats.io:8222/connz?limit=16&offset=128). -Get closed connection information: http://demo.nats.io:8222/connz?state=closed. +Get closed connection information: [http://demo.nats.io:8222/connz?state=closed](http://demo.nats.io:8222/connz?state=closed). -You can also report detailed subscription information on a per connection basis using subs=1. For example: http://demo.nats.io:8222/connz?limit=1&offset=1&subs=1. +You can also report detailed subscription information on a per connection basis using subs=1. For example: [http://demo.nats.io:8222/connz?limit=1&offset=1&subs=1](http://demo.nats.io:8222/connz?limit=1&offset=1&subs=1). #### Response -```json +```javascript { "server_id": "NACDVKFBUW4C4XA24OOT6L4MDP56MW76J5RJDFXG7HLABSB46DCMWCOW", "now": "2019-06-24T14:28:16.520365-07:00", @@ -237,31 +237,30 @@ You can also report detailed subscription information on a per connection basis ### Route Information -The `/routez` endpoint reports information on active routes for a cluster. -Routes are expected to be low, so there is no paging mechanism with this endpoint. +The `/routez` endpoint reports information on active routes for a cluster. Routes are expected to be low, so there is no paging mechanism with this endpoint. **Endpoint:** `http://server:port/routez` -| Result | Return Code | -|:---|:---| -| Success | 200 (OK) | -| Error | 400 (Bad Request) | +| Result | Return Code | +| :--- | :--- | +| Success | 200 \(OK\) | +| Error | 400 \(Bad Request\) | #### Arguments | Argument | Values | Description | -|:---|:---|:---| -| subs | true, 1, false, 0 | Include internal subscriptions. Default is false.| +| :--- | :--- | :--- | +| subs | true, 1, false, 0 | Include internal subscriptions. Default is false. | -As noted above, the `routez` endpoint does support the `subs` argument from the `/connz` endpoint. For example: http://demo.nats.io:8222/routez?subs=1 +As noted above, the `routez` endpoint does support the `subs` argument from the `/connz` endpoint. For example: [http://demo.nats.io:8222/routez?subs=1](http://demo.nats.io:8222/routez?subs=1) #### Example -* Get route information: http://demo.nats.io:8222/routez?subs=1 +* Get route information: [http://demo.nats.io:8222/routez?subs=1](http://demo.nats.io:8222/routez?subs=1) #### Response -```json +```javascript { "server_id": "NACDVKFBUW4C4XA24OOT6L4MDP56MW76J5RJDFXG7HLABSB46DCMWCOW", "now": "2019-06-24T14:29:16.046656-07:00", @@ -286,31 +285,30 @@ As noted above, the `routez` endpoint does support the `subs` argument from the ### Gateway Information -The `/gatewayz` endpoint reports information about gateways used to create a NATS supercluster. -Like routes, the number of gateways are expected to be low, so there is no paging mechanism with this endpoint. +The `/gatewayz` endpoint reports information about gateways used to create a NATS supercluster. Like routes, the number of gateways are expected to be low, so there is no paging mechanism with this endpoint. **Endpoint:** `http://server:port/gatewayz` -| Result | Return Code | -|:---|:---| -| Success | 200 (OK) | -| Error | 400 (Bad Request) | +| Result | Return Code | +| :--- | :--- | +| Success | 200 \(OK\) | +| Error | 400 \(Bad Request\) | #### Arguments | Argument | Values | Description | -|:---|:---|:---| -| accs | true, 1, false, 0 | Include account information. Default is false. | -| gw_name | string | Return only remote gateways with this name. | -| acc_name | string | Limit the list of accounts to this account name. | +| :--- | :--- | :--- | +| accs | true, 1, false, 0 | Include account information. Default is false. | +| gw\_name | string | Return only remote gateways with this name. | +| acc\_name | string | Limit the list of accounts to this account name. | #### Examples -* Retrieve Gateway Information: http://demo.nats.io:8222/gatewayz +* Retrieve Gateway Information: [http://demo.nats.io:8222/gatewayz](http://demo.nats.io:8222/gatewayz) #### Response -```json +```javascript { "server_id": "NANVBOU62MDUWTXWRQ5KH3PSMYNCHCEUHQV3TW3YH7WZLS7FMJE6END6", "now": "2019-07-24T18:02:55.597398-06:00", @@ -429,26 +427,26 @@ The `/leafz` endpoint reports detailed information about the leaf node connectio **Endpoint:** `http://server:port/leafz` -| Result | Return Code | -|:---|:---| -| Success | 200 (OK) | -| Error | 400 (Bad Request) | +| Result | Return Code | +| :--- | :--- | +| Success | 200 \(OK\) | +| Error | 400 \(Bad Request\) | #### Arguments | Argument | Values | Description | -|:---|:---|:---| -| subs | true, 1, false, 0 | Include internal subscriptions. Default is false.| +| :--- | :--- | :--- | +| subs | true, 1, false, 0 | Include internal subscriptions. Default is false. | -As noted above, the `leafz` endpoint does support the `subs` argument from the `/connz` endpoint. For example: http://demo.nats.io:8222/leafz?subs=1 +As noted above, the `leafz` endpoint does support the `subs` argument from the `/connz` endpoint. For example: [http://demo.nats.io:8222/leafz?subs=1](http://demo.nats.io:8222/leafz?subs=1) #### Example -* Get leaf nodes information: http://demo.nats.io:8222/leafz?subs=1 +* Get leaf nodes information: [http://demo.nats.io:8222/leafz?subs=1](http://demo.nats.io:8222/leafz?subs=1) #### Response -```json +```javascript { "server_id": "NC2FJCRMPBE5RI5OSRN7TKUCWQONCKNXHKJXCJIDVSAZ6727M7MQFVT3", "now": "2019-08-27T09:07:05.841132-06:00", @@ -474,31 +472,31 @@ As noted above, the `leafz` endpoint does support the `subs` argument from the ` ### Subscription Routing Information -The `/subz` endpoint reports detailed information about the current subscriptions and the routing data structure. It is not normally used. +The `/subz` endpoint reports detailed information about the current subscriptions and the routing data structure. It is not normally used. **Endpoint:** `http://server:port/subz` -| Result | Return Code | -|:---|:---| -| Success | 200 (OK) | -| Error | 400 (Bad Request) | +| Result | Return Code | +| :--- | :--- | +| Success | 200 \(OK\) | +| Error | 400 \(Bad Request\) | #### Arguments | Argument | Values | Description | -|:---|:---|:---| -| subs | true, 1, false, 0 | Include subscriptions. Default is false. | -| offset | integer > 0 | Pagination offset. Default is 0. | -| limit | integer > 0 | Number of results to return. Default is 1024. | -| test | subject | Test whether a subsciption exists. | +| :--- | :--- | :--- | +| subs | true, 1, false, 0 | Include subscriptions. Default is false. | +| offset | integer > 0 | Pagination offset. Default is 0. | +| limit | integer > 0 | Number of results to return. Default is 1024. | +| test | subject | Test whether a subsciption exists. | #### Example -* Get subscription routing information: http://demo.nats.io:8222/subsz +* Get subscription routing information: [http://demo.nats.io:8222/subsz](http://demo.nats.io:8222/subsz) #### Response -```json +```javascript { "num_subscriptions": 2, "num_cache": 0, @@ -517,7 +515,7 @@ NATS monitoring endpoints support [JSONP](https://en.wikipedia.org/wiki/JSONP) a For example: -```sh +```bash http://demo.nats.io:8222/connz?callback=cb ``` @@ -527,9 +525,9 @@ Here is a JQuery example implementation: $.getJSON('http://demo.nats.io:8222/connz?callback=?', function(data) { console.log(data); }); - ``` ## Monitoring Tools In addition to writing custom monitoring tools, you can monitor nats-server in Prometheus. The [Prometheus NATS Exporter](https://github.com/nats-io/prometheus-nats-exporter) allows you to configure the metrics you want to observe and store in Prometheus. There's a sample [Grafana](https://grafana.com) dashboard that you can use to visualize the server metrics. + diff --git a/nats-server/configuration/securing_nats/README.md b/nats-server/configuration/securing_nats/README.md new file mode 100644 index 0000000..781ae7c --- /dev/null +++ b/nats-server/configuration/securing_nats/README.md @@ -0,0 +1,8 @@ +# Securing NATS + +The NATS server provides several forms of security: + +* Connections can be [_encrypted_ with TLS](tls.md) +* Client connections can require [_authentication_](auth_intro/) +* Clients can require [_authorization_](authorization.md) for subjects the publish or subscribe to + diff --git a/nats_server/auth_intro.md b/nats-server/configuration/securing_nats/auth_intro/README.md similarity index 59% rename from nats_server/auth_intro.md rename to nats-server/configuration/securing_nats/auth_intro/README.md index 2f23515..8daa75f 100644 --- a/nats_server/auth_intro.md +++ b/nats-server/configuration/securing_nats/auth_intro/README.md @@ -2,38 +2,37 @@ The NATS server provides various ways of authenticating clients: -- [Token Authentication](tokens.md) -- [Username/Password credentials](username_password.md) -- [TLS Certificate](tls_mutual_auth.md) -- [NKEY with Challenge](nkey_auth.md) -- [Accounts](accounts.md) -- [JWTs](jwt_auth.md) +* [Token Authentication](tokens.md) +* [Username/Password credentials](username_password.md) +* [TLS Certificate](tls_mutual_auth.md) +* [NKEY with Challenge](nkey_auth.md) +* [Accounts](accounts.md) +* [JWTs](jwt_auth.md) -Authentication deals with allowing a NATS client to connect to the server. -Except for JWT authentication, authentication and authorization are configured in the `authorization` section of the configuration. +Authentication deals with allowing a NATS client to connect to the server. Except for JWT authentication, authentication and authorization are configured in the `authorization` section of the configuration. ## Authorization Map The `authorization` block provides _authentication_ configuration as well as _authorization_: | Property | Description | -| :------ | :---- | -| [`token`](tokens.md) | Specifies a global token that can be used to authenticate to the server (exclusive of user and password) | -| [`user`](username_password.md) | Specifies a single _global_ user name for clients to the server (exclusive of token) | -| [`password`](username_password.md) | Specifies a single _global_ password for clients to the server (exclusive of `token`) | +| :--- | :--- | +| [`token`](tokens.md) | Specifies a global token that can be used to authenticate to the server \(exclusive of user and password\) | +| [`user`](username_password.md) | Specifies a single _global_ user name for clients to the server \(exclusive of token\) | +| [`password`](username_password.md) | Specifies a single _global_ password for clients to the server \(exclusive of `token`\) | | `users` | A list of user configuration maps | | `timeout` | Maximum number of seconds to wait for client authentication | For multiple username and password credentials, specify a `users` list. - ## User Configuration Map A `user` configuration map specifies credentials and permissions options for a single user: | Property | Description | -| :------ | :---- | +| :--- | :--- | | [`user`](username_password.md) | username for client authentication | | [`password`](username_password.md) | password for the user entry | | [`nkey`](nkey_auth.md) | public nkey identifying an user | -| [`permissions`](authorization.md) | permissions map configuring subjects accessible to the user | +| [`permissions`](../authorization.md) | permissions map configuring subjects accessible to the user | + diff --git a/nats_server/accounts.md b/nats-server/configuration/securing_nats/auth_intro/accounts.md similarity index 71% rename from nats_server/accounts.md rename to nats-server/configuration/securing_nats/auth_intro/accounts.md index a7512c7..68fa792 100644 --- a/nats_server/accounts.md +++ b/nats-server/configuration/securing_nats/auth_intro/accounts.md @@ -1,21 +1,22 @@ +# Accounts + ## Accounts -_Accounts_ expand on the authentication foundation. With traditional authentication (except for JWT authentication), all clients can publish and subscribe to anything unless explicitly configured otherwise. To protect clients and information, you have to carve the subject space and permission clients carefully. +_Accounts_ expand on the authentication foundation. With traditional authentication \(except for JWT authentication\), all clients can publish and subscribe to anything unless explicitly configured otherwise. To protect clients and information, you have to carve the subject space and permission clients carefully. -_Accounts_ allow the grouping of clients, *isolating* them from clients in other accounts, thus enabling *multi-tenancy* in the server. With accounts, the subject space is not globally shared, greatly simplifying the messaging environment. Instead of devising complicated subject name carving patterns, clients can use short subjects without explicit authorization rules. +_Accounts_ allow the grouping of clients, _isolating_ them from clients in other accounts, thus enabling _multi-tenancy_ in the server. With accounts, the subject space is not globally shared, greatly simplifying the messaging environment. Instead of devising complicated subject name carving patterns, clients can use short subjects without explicit authorization rules. Accounts configuration is done in `accounts` map. The contents of an account entry includes: | Property | Description | -| :-- | :-- | -| `users` | a list of [user configuration maps](auth_intro.md#user-configuration-map) | +| :--- | :--- | +| `users` | a list of [user configuration maps](./#user-configuration-map) | | `exports` | a list of export maps | | `imports` | a list of import maps | - The `accounts` list is a map, where the keys on the map are an account name. -``` +```text accounts: { A: { users: [ @@ -31,46 +32,44 @@ accounts: { ``` > In the most straightforward configuration above you have an account named `A` which has a single user identified by the username `a` and the password `a`, and an account named `B` with a user identified by the username `b` and the password `b`. - +> > These two accounts are isolated from each other. Messages published by users in `A` are not visible to users in `B`. +> +> The user configuration map is the same as any other NATS [user configuration map](./#user-configuration-map). You can use: -> The user configuration map is the same as any other NATS [user configuration map](auth_intro.md#user-configuration-map). You can use: +* username/password +* nkeys +* and add permissions -- username/password -- nkeys -- and add permissions - -> While the name _account_ implies one or more users, it is much simpler and enlightening to think of one account as a messaging container for one application. Users in the account are simply the minimum number of services that must work together to provide some functionality. -> In simpler terms, more accounts with few (even one) clients is a better design topology than a large account with many users with complex authorization configuration. +> While the name _account_ implies one or more users, it is much simpler and enlightening to think of one account as a messaging container for one application. Users in the account are simply the minimum number of services that must work together to provide some functionality. In simpler terms, more accounts with few \(even one\) clients is a better design topology than a large account with many users with complex authorization configuration. ### Exporting and Importing Messaging exchange between different accounts is enabled by _exporting_ streams and services from one account and _importing_ them into another. Each account controls what is exported and imported. -The `exports` configuration list enable you to define the services and streams that others can import. Services and streams are expressed as an [Export configuration map](#export-configuration-map). +The `exports` configuration list enable you to define the services and streams that others can import. Services and streams are expressed as an [Export configuration map](accounts.md#export-configuration-map). ### Streams Streams are messages your application publishes. Importing applications won't be able to make requests from your applications but will be able to consume messages you generate. -### Services +### Services Services are messages your application can consume and act on, enabling other accounts to make requests that are fulfilled by your account. - - ### Export Configuration Map The export configuration map binds a subject for use as a `service` or `stream` and optionally defines specific accounts that can import the stream or service. Here are the supported configuration properties: | Property | Description | -| :-- | :-- | -| `stream` | A subject or subject with wildcards that the account will publish. (exclusive of `service`) | -| `service` | A subject or subject with wildcards that the account will subscribe to. (exclusive of `stream`) | +| :--- | :--- | +| `stream` | A subject or subject with wildcards that the account will publish. \(exclusive of `service`\) | +| `service` | A subject or subject with wildcards that the account will subscribe to. \(exclusive of `stream`\) | | `accounts` | A list of account names that can import the stream or service. If not specified, the service or stream is public and any account can import it. | Here are some example exports: -``` + +```text accounts: { A: { users: [ @@ -89,38 +88,34 @@ accounts: { Here's what `A` is exporting: -- a public stream on the wildcard subject `puba.>` -- a public service on the wildcard subject `pubq.>` -- a stream to account `B` on the wildcard subject `a.>` -- a service to account `B` on the subject `q.b` - +* a public stream on the wildcard subject `puba.>` +* a public service on the wildcard subject `pubq.>` +* a stream to account `B` on the wildcard subject `a.>` +* a service to account `B` on the subject `q.b` ## Source Configuration Map -The _source configuration map_ describes an export from a remote account by specifying the `account` and `subject` of the export being imported. This map is embedded in the [import configuration map](#import-configuration-map): +The _source configuration map_ describes an export from a remote account by specifying the `account` and `subject` of the export being imported. This map is embedded in the [import configuration map](accounts.md#import-configuration-map): | Property | Description | -| :-- | :-- | +| :--- | :--- | | `account` | Account name owning the export. | | `subject` | The subject under which the stream or service is made accessible to the importing account | - ### Import Configuration Map An import enables an account to consume streams published by another account or make requests to services implemented by another account. All imports require a corresponding export on the exporting account. Accounts cannot do self-imports. | Property | Description | -| :-- | :-- | -| `stream` | Stream import source configuration. (exclusive of `service`) | -| `service` | Service import source configuration (exclusive of `stream`) | -| `prefix` | A local subject prefix mapping for the imported stream.| +| :--- | :--- | +| `stream` | Stream import source configuration. \(exclusive of `service`\) | +| `service` | Service import source configuration \(exclusive of `stream`\) | +| `prefix` | A local subject prefix mapping for the imported stream. | | `to` | A local subject mapping for imported service. | The `prefix` and `to` options allow you to remap the subject that is used locally to receive stream messages or publish service requests. - - -``` +```text accounts: { A: { users: [ @@ -156,21 +151,19 @@ accounts: { Account `B` imports: -- the private stream from `A` that only `B` can receive on `b.>` -- the private service from `A` that only `B` can send requests on `q.b` +* the private stream from `A` that only `B` can receive on `b.>` +* the private service from `A` that only `B` can send requests on `q.b` Account `C` imports the public service and stream from `A`, but also: -- remaps the `puba.>` stream to be locally available under `from_a.puba.>`. The messages will have their original subjects prefixed by `from_a`. -- remaps the `pubq.C` service to be locally available under `Q`. Account `C` only needs to publish to `Q` locally. +* remaps the `puba.>` stream to be locally available under `from_a.puba.>`. The messages will have their original subjects prefixed by `from_a`. +* remaps the `pubq.C` service to be locally available under `Q`. Account `C` only needs to publish to `Q` locally. It is important to reiterate that: -- stream `puba.>` from `A` is visible to all external accounts that imports the stream. -- service `pubq.>` from `A` is available to all external accounts so long as they know the full subject of where to send the request. Typically an account will export a wildcard service but then coordinate with a client account on specific subjects where requests will be answered. On our example, account `C` access the service on `pubq.C` (but has mapped it for simplicity to `Q`). -- stream `b.>` is private, only account `B` can receive messages from the stream. -- service `q.b` is private; only account `B` can send requests to the service. -- When `C` publishes a request to `Q`, local `C` clients will see `Q` messages. However, the server will remap `Q` to `pubq.C` and forward the requests to account `A`. - - +* stream `puba.>` from `A` is visible to all external accounts that imports the stream. +* service `pubq.>` from `A` is available to all external accounts so long as they know the full subject of where to send the request. Typically an account will export a wildcard service but then coordinate with a client account on specific subjects where requests will be answered. On our example, account `C` access the service on `pubq.C` \(but has mapped it for simplicity to `Q`\). +* stream `b.>` is private, only account `B` can receive messages from the stream. +* service `q.b` is private; only account `B` can send requests to the service. +* When `C` publishes a request to `Q`, local `C` clients will see `Q` messages. However, the server will remap `Q` to `pubq.C` and forward the requests to account `A`. diff --git a/nats_server/auth_timeout.md b/nats-server/configuration/securing_nats/auth_intro/auth_timeout.md similarity index 74% rename from nats_server/auth_timeout.md rename to nats-server/configuration/securing_nats/auth_intro/auth_timeout.md index d31d384..518d04d 100644 --- a/nats_server/auth_timeout.md +++ b/nats-server/configuration/securing_nats/auth_intro/auth_timeout.md @@ -1,14 +1,14 @@ # Authentication Timeout -Much like the [`tls timeout` option](/nats_server/tls.md#tls-timeout), authentication can specify a `timeout` value. +Much like the [`tls timeout` option](../tls.md#tls-timeout), authentication can specify a `timeout` value. If a client doesn't authenticate to the server within the specified time, the server disconnects the server to prevent abuses. -Timeouts are specified in seconds (and can be fractional). +Timeouts are specified in seconds \(and can be fractional\). As with TLS timeouts, long timeouts can be an opportunity for abuse. If setting the authentication timeout, it is important to note that it should be longer than the `tls timeout` option, as the authentication timeout includes the TLS upgrade time. -``` +```text authorization: { timeout: 3 users: [ @@ -16,4 +16,5 @@ authorization: { {user: b, password a} ] } -``` \ No newline at end of file +``` + diff --git a/nats_server/jwt_auth.md b/nats-server/configuration/securing_nats/auth_intro/jwt_auth.md similarity index 59% rename from nats_server/jwt_auth.md rename to nats-server/configuration/securing_nats/auth_intro/jwt_auth.md index e83ad70..76ff7d8 100644 --- a/nats_server/jwt_auth.md +++ b/nats-server/configuration/securing_nats/auth_intro/jwt_auth.md @@ -1,71 +1,67 @@ - -## Accounts +# JWTs _Accounts_ expand on [Accounts](accounts.md) and [NKeys](nkey_auth.md) authentication foundation to create a decentralized authentication and authorization model. -With other authentication mechanisms, configuration for identifying a user or an account is in the server configuration file. JWT authentication leverages [JSON Web Tokens (JWT)](https://jwt.io/) to describe the various entities supported. When a client connects, servers query for account JWTs and validate a trust chain. Users are not directly tracked by the server, but rather verified as belonging to an account. This enables the management of users without requiring server configuration updates. +With other authentication mechanisms, configuration for identifying a user or an account is in the server configuration file. JWT authentication leverages [JSON Web Tokens \(JWT\)](https://jwt.io/) to describe the various entities supported. When a client connects, servers query for account JWTs and validate a trust chain. Users are not directly tracked by the server, but rather verified as belonging to an account. This enables the management of users without requiring server configuration updates. -Effectively, accounts provide for a distributed configuration paradigm. Previously each user (or client) needed to be known and authorized a priori in the server’s configuration requiring an administrator to modify and update server configurations. Accounts eliminate these chores. +Effectively, accounts provide for a distributed configuration paradigm. Previously each user \(or client\) needed to be known and authorized a priori in the server’s configuration requiring an administrator to modify and update server configurations. Accounts eliminate these chores. +## JSON Web Tokens -### JSON Web Tokens +[JSON Web Tokens \(JWT\)](https://jwt.io/) are an open and industry standard [RFC7519](https://tools.ietf.org/html/rfc7519) method for representing claims securely between two parties. -[JSON Web Tokens (JWT)](https://jwt.io/) are an open and industry standard [RFC7519](https://tools.ietf.org/html/rfc7519) method for representing claims securely between two parties. - -Claims are a fancy way of asserting information on a _subject_. In this context, a _subject_ is the entity being described (not a messaging subject). Standard JWT claims are typically digitally signed and verified. +Claims are a fancy way of asserting information on a _subject_. In this context, a _subject_ is the entity being described \(not a messaging subject\). Standard JWT claims are typically digitally signed and verified. NATS further restricts JWTs by requiring that JWTs be: -- Digitally signed _always_ and only using [Ed25519](https://ed25519.cr.yp.to/). -- NATS adopts the convention that all _Issuer_ and _Subject_ fields in a JWT claim must be a public [NKEY](nkey_auth.md). -- _Issuer_ and _Subject_ must match specific roles depending on the claim [NKeys](https://github.com/nats-io/nkeys). +* Digitally signed _always_ and only using [Ed25519](https://ed25519.cr.yp.to/). +* NATS adopts the convention that all _Issuer_ and _Subject_ fields in a JWT claim must be a public [NKEY](nkey_auth.md). +* _Issuer_ and _Subject_ must match specific roles depending on the claim [NKeys](https://github.com/nats-io/nkeys). -#### NKey Roles +### NKey Roles NKey Roles are: -- Operators -- Accounts -- Users +* Operators +* Accounts +* Users Roles are hierarchical and form a chain of trust. Operators issue Accounts which in turn issue Users. Servers trust specific Operators. If an account is issued by an operator that is trusted, account users are trusted. +## The Authentication Process -### The Authentication Process +When a _User_ connects to a server, it presents a JWT issued by its _Account_. The user proves its identity by signing a server-issued cryptographic challenge with its private key. The signature verification validates that the signature is attributable to the user's public key. Next, the server retrieves the associated account JWT that issued the user. It verifies the _User_ issuer matches the referenced account. Finally, the server checks that a trusted _Operator_ issued the _Account_, completing the trust chain verification. -When a _User_ connects to a server, it presents a JWT issued by its _Account_. The user proves its identity by signing a server-issued cryptographic challenge with its private key. The signature verification validates that the signature is attributable to the user's public key. Next, the server retrieves the associated account JWT that issued the user. It verifies the _User_ issuer matches the referenced account. Finally, the server checks that a trusted _Operator_ issued the _Account_, completing the trust chain verification. +## The Authorization Process - -### The Authorization Process - -From an authorization point of view, the account provides information on messaging subjects that are imported from other accounts (including any ancillary related authorization) as well as messaging subjects exported to other accounts. Accounts can also bear limits, such as the maximum number of connections they may have. A user JWT can express restrictions on the messaging subjects to which it can publish or subscribe. +From an authorization point of view, the account provides information on messaging subjects that are imported from other accounts \(including any ancillary related authorization\) as well as messaging subjects exported to other accounts. Accounts can also bear limits, such as the maximum number of connections they may have. A user JWT can express restrictions on the messaging subjects to which it can publish or subscribe. When a new user is added to an account, the account configuration need not change, as each user can and should have its own user JWT that can be verified by simply resolving its parent account. -### JWTs and Privacy +## JWTs and Privacy One crucial detail to keep in mind is that while in other systems JWTs are used as sessions or proof of authentication, NATS JWTs are only used as configuration describing: -- the public ID of the entity -- the public ID of the entity that issued it -- capabilities of the entity +* the public ID of the entity +* the public ID of the entity that issued it +* capabilities of the entity Authentication is a public key cryptographic process — a client signs a nonce proving identity while the trust chain and configuration provides the authorization. The server is never aware of private keys but can verify that a signer or issuer indeed matches a specified or known public key. -Lastly, all NATS JWTs (Operators, Accounts, Users and others) are expected to be signed using the [Ed25519](https://ed25519.cr.yp.to/) algorithm. If they are not, they are rejected by the system. +Lastly, all NATS JWTs \(Operators, Accounts, Users and others\) are expected to be signed using the [Ed25519](https://ed25519.cr.yp.to/) algorithm. If they are not, they are rejected by the system. -### Sharing Between Accounts +## Sharing Between Accounts While accounts provide isolation, there are many cases where you want to be able to consume messages produced by one account in another. There are two kinds of shares an account can _export_: -- Streams -- Services +* Streams +* Services Streams are messages published by a foreign account; Subscribers in an _importing_ account can receive messages from a stream _exported_ by another. -Services are endpoints exported by a foreign account; Requesters _importing_ the service can publish requests to the _exported_ endpoint. +Services are endpoints exported by a foreign account; Requesters _importing_ the service can publish requests to the _exported_ endpoint. Streams and Services can be public; Public exports can be imported by any account. Or they can be private. Private streams and services require an authorization token from the exporting account that authorizes the foreign account to import the stream or service. @@ -73,12 +69,13 @@ An importing account can remap the subject where a stream subscriber will receiv Exports and imports from an account are explicit, and they are visible in the account's JWT. For private exports, the import will embed an authorization token or a URL storing the token. Imports and exports make it easy to audit where data is coming from or going to. -### Configuration +## Configuration -Entity JWT configuration is done using the [`nsc` tool](/nats_tools/nsc/README.md). The basic steps include: +Entity JWT configuration is done using the [`nsc` tool](../../../../nats-tools/nsc/). The basic steps include: -- [Creation of an operator JWT](/nats_tools/nsc/nsc.md#creating-an-operator) -- [Configuring an Account Server](/nats_tools/nsc/nsc.md#account-server-configuration) -- [Setting up the NATS server to resolve Accounts](/nats_tools/nsc/nsc.md#nats-server-configuration) +* [Creation of an operator JWT](../../../../nats-tools/nsc/nsc.md#creating-an-operator) +* [Configuring an Account Server](../../../../nats-tools/nsc/nsc.md#account-server-configuration) +* [Setting up the NATS server to resolve Accounts](../../../../nats-tools/nsc/nsc.md#nats-server-configuration) After that, `nsc` is used to create and edit accounts and users. + diff --git a/nats_server/nkey_auth.md b/nats-server/configuration/securing_nats/auth_intro/nkey_auth.md similarity index 78% rename from nats_server/nkey_auth.md rename to nats-server/configuration/securing_nats/auth_intro/nkey_auth.md index 81bc923..2b2ba0c 100644 --- a/nats_server/nkey_auth.md +++ b/nats-server/configuration/securing_nats/auth_intro/nkey_auth.md @@ -1,4 +1,4 @@ -## NKey Authentication +# NKeys NKeys are a new, highly secure public-key signature system based on [Ed25519](https://ed25519.cr.yp.to/). @@ -6,20 +6,19 @@ With NKeys the server can verify identities without ever storing or ever seeing > NKey is an excellent replacement for token authentication because a connecting client will have to prove it controls the private key for the authorized public key. -To generate nkeys, you'll need the [`nk` tool](/nats_tools/nk.md). +To generate nkeys, you'll need the [`nk` tool](../../../../nats-tools/nk.md). - -### Generating NKeys and Configuring the Server +## Generating NKeys and Configuring the Server To generate a _User_ NKEY: -``` +```text > nk -gen user -pubout SUACSSL3UAHUDXKFSNVUZRF5UHPMWZ6BFDTJ7M6USDXIEDNPPQYYYCU3VY UDXU4RCSJNZOIQHZNWXHXORDPRTGNJAHAHFRGZNEEJCPQTT2M7NLCNF4 ``` -The first output line starts with the letter `S` for _Seed_. The second letter, `U` stands for _User_. Seeds are private keys; you should treat them as secrets and guard them with care. +The first output line starts with the letter `S` for _Seed_. The second letter, `U` stands for _User_. Seeds are private keys; you should treat them as secrets and guard them with care. The second line starts with the letter `U` for _User_ and is a public key which can be safely shared. @@ -33,10 +32,9 @@ authorization: { } ``` -Note that the user section sets the `nkey` property (user/password/token properties are not needed). Add `permission` sections as required. +Note that the user section sets the `nkey` property \(user/password/token properties are not needed\). Add `permission` sections as required. - -### Client Configuration +## Client Configuration Now that you have a user nkey, let's configure a client to use it for authentication. As an example, here are the connect options for the node client: @@ -59,6 +57,5 @@ const nc = NATS.connect({ ... ``` -The client provides a function that it uses to parse the seed (the private key) and sign the connection challenge. - +The client provides a function that it uses to parse the seed \(the private key\) and sign the connection challenge. diff --git a/nats_server/tls_mutual_auth.md b/nats-server/configuration/securing_nats/auth_intro/tls_mutual_auth.md similarity index 81% rename from nats_server/tls_mutual_auth.md rename to nats-server/configuration/securing_nats/auth_intro/tls_mutual_auth.md index 5ab3898..d844d73 100644 --- a/nats_server/tls_mutual_auth.md +++ b/nats-server/configuration/securing_nats/auth_intro/tls_mutual_auth.md @@ -1,15 +1,15 @@ -## Client TLS Mutual Authentication +# TLS Authentication The server can require TLS certificates from a client. When needed, you can use the certificates to: -- Validate the client certificate matches a known or trusted CA -- Extract information from a trusted certificate to provide authentication +* Validate the client certificate matches a known or trusted CA +* Extract information from a trusted certificate to provide authentication -### Validating a Client Certificate +## Validating a Client Certificate The server can verify a client certificate using a CA certificate. To require verification, add the option `verify` the TLS configuration section as follows: -``` +```text tls { cert_file: "./configs/certs/server-cert.pem" key_file: "./configs/certs/server-key.pem" @@ -20,19 +20,19 @@ tls { Or via the command line: -```sh +```bash > ./nats-server --tlsverify --tlscert=./test/configs/certs/server-cert.pem --tlskey=./test/configs/certs/server-key.pem --tlscacert=./test/configs/certs/ca.pem ``` -This option verifies the client's certificate is signed by the CA specified in the `ca_file` option. +This option verifies the client's certificate is signed by the CA specified in the `ca_file` option. -### Mapping Client Certificates To A User +## Mapping Client Certificates To A User In addition to verifying that a specified CA issued a client certificate, you can use information encoded in the certificate to authenticate a client. The client wouldn't have to provide or track usernames or passwords. To have TLS Mutual Authentication map certificate attributes to the user's identity use `verify_and_map` as shown as follows: -``` +```text tls { cert_file: "./configs/certs/server-cert.pem" key_file: "./configs/certs/server-key.pem" @@ -44,9 +44,9 @@ tls { > Note that `verify` was changed to `verify_and_map`. -There are two options for certificate attributes that can be mapped to user names. The first is the email address in the Subject Alternative Name (SAN) field of the certificate. While generating a certificate with this attribute is outside the scope of this document, you can view one with `openssl`: +There are two options for certificate attributes that can be mapped to user names. The first is the email address in the Subject Alternative Name \(SAN\) field of the certificate. While generating a certificate with this attribute is outside the scope of this document, you can view one with `openssl`: -``` +```text $ openssl x509 -noout -text -in test/configs/certs/client-id-auth-cert.pem Certificate: ... @@ -60,7 +60,7 @@ Certificate: The configuration to authorize this user would be as follows: -``` +```text authorization { users = [ {user: "derek@nats.io"} @@ -72,7 +72,7 @@ authorization { The second option is to use the RFC 2253 Distinguished Names syntax from the certificate subject as follows: -``` +```text $ openssl x509 -noout -text -in test/configs/certs/tlsauth/client2.pem Certificate: Data: @@ -83,7 +83,7 @@ Certificate: The configuration to authorize this user would be as follows: -``` +```text authorization { users = [ {user: "CN=example.com,OU=CNCF"} @@ -91,6 +91,7 @@ authorization { } ``` -### TLS Timeout +## TLS Timeout + +[TLS timeout](../tls.md#tls-timeout) is described here. -[TLS timeout](/nats_server/tls.md#tls-timeout) is described here. \ No newline at end of file diff --git a/nats_server/tokens.md b/nats-server/configuration/securing_nats/auth_intro/tokens.md similarity index 88% rename from nats_server/tokens.md rename to nats-server/configuration/securing_nats/auth_intro/tokens.md index 77b230c..2500735 100644 --- a/nats_server/tokens.md +++ b/nats-server/configuration/securing_nats/auth_intro/tokens.md @@ -1,42 +1,45 @@ -## Token Authentication - -Token authentication is a string that if provided by a client, allows it to connect. It is the most straightforward authentication provided by the NATS server. +# Tokens +Token authentication is a string that if provided by a client, allows it to connect. It is the most straightforward authentication provided by the NATS server. To use token authentication, you can specify an `authorization` section with the `token` property set: -``` + +```text authorization { token: "s3cr3t" } ``` + Token authentication can be used in the authorization section for clients and clusters. Or start the server with the `--auth` flag: -``` + +```text > nats-server --auth s3cr3t ``` A client can easily connect by specifying the server URL: -``` + +```text > nats-sub -s nats://s3cr3t@localhost:4222 ">" Listening on [>] ``` -### Bcrypted Tokens +## Bcrypted Tokens Tokens can be bcrypted enabling an additional layer of security, as the clear-text version of the token would not be persisted on the server configuration file. -You can generate bcrypted tokens and passwords using the [`mkpasswd`](/nats_tools/mkpasswd.md) tool: +You can generate bcrypted tokens and passwords using the [`mkpasswd`](../../../../nats-tools/mkpasswd.md) tool: -``` +```text > mkpasswd pass: dag0HTXl4RGg7dXdaJwbC8 bcrypt hash: $2a$11$PWIFAL8RsWyGI3jVZtO9Nu8.6jOxzxfZo7c/W0eLk017hjgUKWrhy ``` - Here's a simple configuration file: -``` + +```text authorization { token: "$2a$11$PWIFAL8RsWyGI3jVZtO9Nu8.6jOxzxfZo7c/W0eLk017hjgUKWrhy" } @@ -44,9 +47,8 @@ authorization { The client will still require the clear-text token to connect: -``` +```text nats-sub -s nats://dag0HTXl4RGg7dXdaJwbC8@localhost:4222 ">" Listening on [>] ``` - diff --git a/nats_server/username_password.md b/nats-server/configuration/securing_nats/auth_intro/username_password.md similarity index 81% rename from nats_server/username_password.md rename to nats-server/configuration/securing_nats/auth_intro/username_password.md index a9fd0cd..c69b543 100644 --- a/nats_server/username_password.md +++ b/nats-server/configuration/securing_nats/auth_intro/username_password.md @@ -1,9 +1,10 @@ -## Username and Password +# Username/Password You can authenticate one or more clients using username and passwords; this enables you to have greater control over the management and issuance of credential secrets. For a single user: -``` + +```text authorization: { user: a, password: b @@ -12,12 +13,13 @@ authorization: { You can also specify a single username/password by: -``` +```text > nats-server --user a --pass b ``` For multiple users: -``` + +```text authorization: { users: [ {user: a, password: b}, @@ -26,18 +28,19 @@ authorization: { } ``` -### Bcrypted Passwords +## Bcrypted Passwords -Username/password also supports bcrypted passwords using the [`mkpasswd`](/nats_tools/mkpasswd.md) tool. Simply replace the clear text password with the bcrypted entries: +Username/password also supports bcrypted passwords using the [`mkpasswd`](../../../../nats-tools/mkpasswd.md) tool. Simply replace the clear text password with the bcrypted entries: -``` +```text > mkpasswd ass: (Uffs#rG42PAu#Oxi^BNng bcrypt hash: $2a$11$V1qrpBt8/SLfEBr4NJq4T.2mg8chx8.MTblUiTBOLV3MKDeAy.f7u ``` + And on the configuration file: -``` +```text authorization: { users: [ {user: a, password: "$2a$11$V1qrpBt8/SLfEBr4NJq4T.2mg8chx8.MTblUiTBOLV3MKDeAy.f7u"}, @@ -46,10 +49,11 @@ authorization: { } ``` -### Reloading a Configuration +## Reloading a Configuration As you add/remove passwords from the server configuration file, you'll want your changes to take effect. To reload without restarting the server and disconnecting clients, do: -``` +```text > nats-server --signal reload -``` \ No newline at end of file +``` + diff --git a/nats_server/authorization.md b/nats-server/configuration/securing_nats/authorization.md similarity index 75% rename from nats_server/authorization.md rename to nats-server/configuration/securing_nats/authorization.md index 719cc02..531b4fe 100644 --- a/nats_server/authorization.md +++ b/nats-server/configuration/securing_nats/authorization.md @@ -1,39 +1,36 @@ -## Authorization - +# Authorization The NATS server supports authorization using subject-level permissions on a per-user basis. Permission-based authorization is available with multi-user authentication via the `users` list. -Each permission specifies the subjects the user can publish to and subscribe to. The parser is generous at understanding what the intent is, so both arrays and singletons are processed. For more complex configuration, you can specify a `permission` object which explicitly allows or denies subjects. The specified subjects can specify wildcards. Permissions can make use of [variables](configuration.md#variables). +Each permission specifies the subjects the user can publish to and subscribe to. The parser is generous at understanding what the intent is, so both arrays and singletons are processed. For more complex configuration, you can specify a `permission` object which explicitly allows or denies subjects. The specified subjects can specify wildcards. Permissions can make use of [variables](../#variables). You configure authorization by creating a `permissions` entry in the `authorization` object. -### Permissions Configuration Map +## Permissions Configuration Map The `permissions` map specify subjects that can be subscribed to or published by the specified client. | Property | Description | -| :------ | :---- | +| :--- | :--- | | `publish` | subject, list of subjects, or permission map the client can publish | | `subscribe` | subject, list of subjects, or permission map the client can subscribe | -### Permission Map +## Permission Map The `permission` map provides additional properties for configuring a `permissions` map. Instead of providing a list of subjects that are allowed, the `permission` map allows you to explicitly list subjects you want to`allow` or `deny`: | Property | Description | -| :------ | :---- | +| :--- | :--- | | `allow` | List of subject names that are allowed to the client | | `deny` | List of subjects that are denied to the client | +**Important Note** NATS Authorizations can be _allow lists_, _deny lists_, or both. It is important to not break request/reply patterns. In some cases \(as shown below\) you need to add rules as above with Alice and Bob for the `_INBOX.>` pattern. If an unauthorized client publishes or attempts to subscribe to a subject that has not been _allow listed_, the action fails and is logged at the server, and an error message is returned to the client. - -**Important Note** NATS Authorizations can be _allow lists_, _deny lists_, or both. It is important to not break request/reply patterns. In some cases (as shown below) you need to add rules as above with Alice and Bob for the `_INBOX.>` pattern. If an unauthorized client publishes or attempts to subscribe to a subject that has not been _allow listed_, the action fails and is logged at the server, and an error message is returned to the client. - -### Example +## Example Here is an example authorization configuration that uses _variables_ which defines four users, three of whom are assigned explicit permissions. -```ascii +```text authorization { ADMIN = { publish = ">" @@ -60,14 +57,12 @@ authorization { } ``` -> *DEFAULT_PERMISSIONS* is a special permissions name. If defined, it applies to all users that don't have specific permissions set. +> _DEFAULT\_PERMISSIONS_ is a special permissions name. If defined, it applies to all users that don't have specific permissions set. -- _admin_ has `ADMIN` permissions and can publish/subscribe on any subject. We use the wildcard `>` to match any subject. +* _admin_ has `ADMIN` permissions and can publish/subscribe on any subject. We use the wildcard `>` to match any subject. +* _client_ is a `REQUESTOR` and can publish requests on subjects `req.a` or `req.b`, and subscribe to anything that is a response \(`_INBOX.>`\). +* _service_ is a `RESPONDER` to `req.a` and `req.b` requests, so it needs to be able to subscribe to the request subjects and respond to client's that can publish requests to `req.a` and `req.b`. The reply subject is an inbox. Typically inboxes start with the prefix `_INBOX.` followed by a generated string. The `_INBOX.>` subject matches all subjects that begin with `_INBOX.`. +* _other_ has no permissions granted and therefore inherits the default permission set. You set the inherited default permissions by assigning them to the `default_permissions` entry inside of the authorization configuration block. -- _client_ is a `REQUESTOR` and can publish requests on subjects `req.a` or `req.b`, and subscribe to anything that is a response (`_INBOX.>`). +> Note that in the above example, any client with permissions to subscribe to `_INBOX.>` can receive _all_ responses published. More sensitive installations will want to add or subset the prefix to further limit subjects that a client can subscribe. Alternatively, [_Accounts_](auth_intro/accounts.md) allow complete isolation limiting what members of an account can see. -- _service_ is a `RESPONDER` to `req.a` and `req.b` requests, so it needs to be able to subscribe to the request subjects and respond to client's that can publish requests to `req.a` and `req.b`. The reply subject is an inbox. Typically inboxes start with the prefix `_INBOX.` followed by a generated string. The `_INBOX.>` subject matches all subjects that begin with `_INBOX.`. - -- _other_ has no permissions granted and therefore inherits the default permission set. You set the inherited default permissions by assigning them to the `default_permissions` entry inside of the authorization configuration block. - -> Note that in the above example, any client with permissions to subscribe to `_INBOX.>` can receive _all_ responses published. More sensitive installations will want to add or subset the prefix to further limit subjects that a client can subscribe. Alternatively, [_Accounts_](accounts.md) allow complete isolation limiting what members of an account can see. diff --git a/nats_server/tls.md b/nats-server/configuration/securing_nats/tls.md similarity index 91% rename from nats_server/tls.md rename to nats-server/configuration/securing_nats/tls.md index a81a04f..7f16e7f 100644 --- a/nats_server/tls.md +++ b/nats-server/configuration/securing_nats/tls.md @@ -1,13 +1,12 @@ -## TLS Configuration +# Enabling TLS -The NATS server uses modern TLS semantics to encrypt client, route, and monitoring connections. -Server configuration revolves around a `tls` map, which has the following properties: +The NATS server uses modern TLS semantics to encrypt client, route, and monitoring connections. Server configuration revolves around a `tls` map, which has the following properties: | Property | Description | -| :------ | :---- | +| :--- | :--- | | `ca_file` | TLS certificate authority file. | | `cert_file` | TLS certificate file. | -| `cipher_suites` | When set, only the specified TLS cipher suites will be allowed. Values must match the golang version used to build the server. | +| `cipher_suites` | When set, only the specified TLS cipher suites will be allowed. Values must match the golang version used to build the server. | | `curve_preferences` | List of TLS cipher curves to use in order. | | `insecure` | Skip certificate verification. | | `key_file` | TLS certificate key file. | @@ -16,14 +15,17 @@ Server configuration revolves around a `tls` map, which has the following proper | `verify` | If `true`, require and verify client certificates. | The simplest configuration: -``` + +```text tls: { cert_file: "./server-cert.pem" key_file: "./server-key.pem" } ``` -Or by using [server options](./flags.md#tls-options): -``` + +Or by using [server options](../../flags.md#tls-options): + +```text > nats-server --tls --tlscert=./server-cert.pem --tlskey=./server-key.pem [21417] 2019/05/16 11:21:19.801539 [INF] Starting nats-server version 2.0.0 [21417] 2019/05/16 11:21:19.801621 [INF] Git commit [not set] @@ -35,7 +37,7 @@ Or by using [server options](./flags.md#tls-options): Notice that the log indicates that the client connections will be required to use TLS. If you run the server in Debug mode with `-D` or `-DV`, the logs will show the cipher suite selection for each connected client: -``` +```text [22242] 2019/05/16 11:22:20.216322 [DBG] 127.0.0.1:51383 - cid:1 - Client connection created [22242] 2019/05/16 11:22:20.216539 [DBG] 127.0.0.1:51383 - cid:1 - Starting TLS client connection handshake [22242] 2019/05/16 11:22:20.367275 [DBG] 127.0.0.1:51383 - cid:1 - TLS handshake complete @@ -44,17 +46,16 @@ Notice that the log indicates that the client connections will be required to us When a `tls` section is specified at the root of the configuration, it also affects the monitoring port if `https_port` option is specified. Other sections such as `cluster` can specify a `tls` block. - -### TLS Timeout +## TLS Timeout The `timeout` setting enables you to control the amount of time that a client is allowed to upgrade its connection to tls. If your clients are experiencing disconnects during TLS handshake, you'll want to increase the value, however, if you do be aware that an extended `timeout` exposes your server to attacks where a client doesn't upgrade to TLS and thus consumes resources. Conversely, if you reduce the TLS `timeout` too much, you are likely to experience handshake errors. - -``` +```text tls: { cert_file: "./server-cert.pem" key_file: "./server-key.pem" # clients will fail to connect (value is too low) timeout: 0.0001 } -``` \ No newline at end of file +``` + diff --git a/nats_server/flags.md b/nats-server/flags.md similarity index 60% rename from nats_server/flags.md rename to nats-server/flags.md index 553c460..8eb734e 100644 --- a/nats_server/flags.md +++ b/nats-server/flags.md @@ -1,53 +1,48 @@ # Flags - The NATS server has many flags to customize its behavior without having to write a configuration file. The configuration flags revolve around: -- Server Options -- Logging -- Authorization -- TLS Security -- Clustering -- Information +* Server Options +* Logging +* Authorization +* TLS Security +* Clustering +* Information - -### Server Options +## Server Options | Flag | Description | -| :-------------------- | :-------- | -| `-a`, `--addr` | Host address to bind to (default: `0.0.0.0` - all interfaces). | -| `-p`, `--port` | NATS client port (default: 4222). | -| `-P`, `--pid` | File to store the process ID (PID). | -| `-m`, `--http_port` | HTTP port for monitoring dashboard (exclusive of `--https_port`). | -| `-ms`, `--https_port` | HTTPS port monitoring for monitoring dashboard (exclusive of `--http_port`). | +| :--- | :--- | +| `-a`, `--addr` | Host address to bind to \(default: `0.0.0.0` - all interfaces\). | +| `-p`, `--port` | NATS client port \(default: 4222\). | +| `-P`, `--pid` | File to store the process ID \(PID\). | +| `-m`, `--http_port` | HTTP port for monitoring dashboard \(exclusive of `--https_port`\). | +| `-ms`, `--https_port` | HTTPS port monitoring for monitoring dashboard \(exclusive of `--http_port`\). | | `-c`, `--config` | Path to NATS server configuration file. | -| `-sl`, `--signal` | Send a signal to nats-server process. See [process signaling](/nats_admin/signals.md). | +| `-sl`, `--signal` | Send a signal to nats-server process. See [process signaling](nats_admin/signals.md). | | `--client_advertise` | Client HostPort to advertise to other servers. | | `-t` | Test configuration and exit | - - -### Authentication Options +## Authentication Options The following options control straightforward authentication: | Flag | Description | -| :-------------------- | :-------- | -| `--user` | Required _username_ for connections (exclusive of `--token`). | -| `--pass` | Required _password_ for connections (exclusive of `--token`). | -| `--auth` | Required _authorization token_ for connections (exclusive of `--user` and `--password`). | +| :--- | :--- | +| `--user` | Required _username_ for connections \(exclusive of `--token`\). | +| `--pass` | Required _password_ for connections \(exclusive of `--token`\). | +| `--auth` | Required _authorization token_ for connections \(exclusive of `--user` and `--password`\). | -See [token authentication](tokens.md), and [username/password](username_password.md) for more information. +See [token authentication](configuration/securing_nats/auth_intro/tokens.md), and [username/password](configuration/securing_nats/auth_intro/username_password.md) for more information. - -### Logging Options +## Logging Options The following flags are available on the server to configure logging: | Flag | Description | -| :-------------------- | :-------- | +| :--- | :--- | | `-l`, `--log` | File to redirect log output | | `-T`, `--logtime` | Specify `-T=false` to disable timestamping log entries | | `-s`, `--syslog` | Log to syslog or windows event log | @@ -55,42 +50,38 @@ The following flags are available on the server to configure logging: | `-D`, `--debug` | Enable debugging output | | `-V`, `--trace` | Enable protocol trace log messages | | `-DV` | Enable both debug and protocol trace messages | -| `--max_traced_msg_len` | Maximum printable length for traced messages. 0 for unlimited| +| `--max_traced_msg_len` | Maximum printable length for traced messages. 0 for unlimited | -You can read more about [logging configuration here](logging.md). +You can read more about [logging configuration here](configuration/logging.md). - -### TLS Options +## TLS Options | Flag | Description | -| :-------------------- | :-------- | +| :--- | :--- | | `--tls` | Enable TLS, do not verify clients | | `--tlscert` | Server certificate file | | `--tlskey` | Private key for server certificate | | `--tlsverify` | Enable client TLS certificate verification | | `--tlscacert` | Client certificate CA for verification | - -### Cluster Options +## Cluster Options The following flags are available on the server to configure clustering: - | Flag | Description | -| :-------------------- | :-------- | +| :--- | :--- | | `--routes` | Comma-separated list of cluster URLs to solicit and connect | | `--cluster` | Cluster URL for clustering requests | | `--no_advertise` | Do not advertise known cluster information to clients | | `--cluster_advertise` | Cluster URL to advertise to other servers | | `--connect_retries` | For implicit routes, number of connect retries | -You can read more about [clustering configuration here](clustering.md). +You can read more about [clustering configuration here](configuration/clustering/). - -### Common Options +## Common Options | Flag | Description | -| :-------------------- | :-------- | +| :--- | :--- | | `-h`, `--help` | Show this message | | `-v`, `--version` | Show version | | `--help_tls` | TLS help | diff --git a/nats_server/installation.md b/nats-server/installation.md similarity index 77% rename from nats_server/installation.md rename to nats-server/installation.md index 5bd90da..848906f 100644 --- a/nats_server/installation.md +++ b/nats-server/installation.md @@ -1,19 +1,18 @@ -# NATS Server Installation +# Installing NATS philosophy is simplicity. Installation is just decompressing a zip file and copying the binary to an appropriate directory; you can also use your favorite package manager. Here's a list of different ways you can install or run NATS: -- [Docker](#installing-via-docker) -- [Kubernetes](#installing-on-kubernetes-with-nats-operator) -- [Package Manager](#installing-via-a-package-manager) -- [Release Zip](#downloading-a-release-build) -- [Development Build](#installing-from-the-source) +* [Docker](installation.md#installing-via-docker) +* [Kubernetes](installation.md#installing-on-kubernetes-with-nats-operator) +* [Package Manager](installation.md#installing-via-a-package-manager) +* [Release Zip](installation.md#downloading-a-release-build) +* [Development Build](installation.md#installing-from-the-source) - -### Installing via Docker +## Installing via Docker With Docker you can install the server easily without scattering binaries and other artifacts on your system. The only pre-requisite is to [install docker](https://docs.docker.com/install). -``` +```text > docker pull nats:latest latest: Pulling from library/nats Digest: sha256:0c98cdfc4332c0de539a064bfab502a24aae18ef7475ddcc7081331502327354 @@ -23,7 +22,7 @@ docker.io/library/nats:latest To run NATS on Docker: -``` +```text > docker run -p 4222:4222 -ti nats:latest [1] 2019/05/24 15:42:58.228063 [INF] Starting nats-server version #.#.# [1] 2019/05/24 15:42:58.228115 [INF] Git commit [#######] @@ -33,30 +32,29 @@ To run NATS on Docker: [1] 2019/05/24 15:42:58.229003 [INF] Listening for route connections on 0.0.0.0:6222 ``` -More information on [containerized NATS is available here](/nats_docker/README.md). +More information on [containerized NATS is available here](nats_docker/). +## Installing on Kubernetes with NATS Operator -### Installing on Kubernetes with NATS Operator +Installation via the NATS Operator is beyond this tutorial. You can read about the [NATS Operator](https://github.com/nats-io/nats-operator) here. -Installation via the NATS Operator is beyond this tutorial. You can read about the [NATS -Operator](https://github.com/nats-io/nats-operator) here. - - -### Installing via a Package Manager +## Installing via a Package Manager On Windows: -``` + +```text > choco install nats-server ``` On Mac OS: -``` + +```text > brew install nats-server ``` -To test your installation (provided the executable is visible to your shell): +To test your installation \(provided the executable is visible to your shell\): -``` +```text > nats-server [41634] 2019/05/13 09:42:11.745919 [INF] Starting nats-server version 2.0.0 [41634] 2019/05/13 09:42:11.746240 [INF] Listening for client connections on 0.0.0.0:4222 @@ -65,13 +63,13 @@ To test your installation (provided the executable is visible to your shell): [41634] 2019/05/13 09:42:11.746252 [INF] Server is ready ``` -### Downloading a Release Build +## Downloading a Release Build You can find the latest release of nats-server [here](https://github.com/nats-io/nats-server/releases/latest). Download the zip file matching your systems architecture, and unzip. For this example, assuming version 2.0.0 of the server and a Linux AMD64: -``` +```text > curl -L https://github.com/nats-io/nats-server/releases/download/v2.0.0/nats-server-v2.0.0-linux-amd64.zip -o nats-server.zip > unzip nats-server.zip -d nats-server @@ -82,22 +80,21 @@ Archive: nats-server.zip inflating: nats-server-v2.0.0darwin-amd64/nats-server > cp nats-server-v2.0.0darwin-amd64/nats-server /usr/local/bin - ``` -### Installing From the Source +## Installing From the Source If you have Go installed, installing the binary is easy: -``` +```text > GO111MODULE=on go get github.com/nats-io/nats-server/v2 ``` -This mechanism will install a build of [master](https://github.com/nats-io/nats-server), which almost certainly will not be a released version. If you are a developer and want to play with the latest, this is the easiest way. +This mechanism will install a build of [master](https://github.com/nats-io/nats-server), which almost certainly will not be a released version. If you are a developer and want to play with the latest, this is the easiest way. -To test your installation (provided the $GOPATH/bin is set): +To test your installation \(provided the $GOPATH/bin is set\): -``` +```text > nats-server [41634] 2019/05/13 09:42:11.745919 [INF] Starting nats-server version 2.0.0 [41634] 2019/05/13 09:42:11.746240 [INF] Listening for client connections on 0.0.0.0:4222 @@ -106,4 +103,3 @@ To test your installation (provided the $GOPATH/bin is set): [41634] 2019/05/13 09:42:11.746252 [INF] Server is ready ``` - diff --git a/nats-server/nats_admin/README.md b/nats-server/nats_admin/README.md new file mode 100644 index 0000000..84077f5 --- /dev/null +++ b/nats-server/nats_admin/README.md @@ -0,0 +1,8 @@ +# Managing A NATS Server + +Managing a NATS server is simple, typical lifecycle operations include: + +* [Sending signals](signals.md) to a server to reload a configuration or rotate log files +* [Upgrading](upgrading_cluster.md) a server \(or cluster\) +* Understanding [slow consumers](slow_consumers.md) + diff --git a/nats_admin/signals.md b/nats-server/nats_admin/signals.md similarity index 69% rename from nats_admin/signals.md rename to nats-server/nats_admin/signals.md index 35a9fea..ac8e972 100644 --- a/nats_admin/signals.md +++ b/nats-server/nats_admin/signals.md @@ -1,18 +1,18 @@ -## Process Signaling +# Signals On Unix systems, the NATS server responds to the following signals: -| Signal | Result | +| Signal | Result | | :--- | :--- | | `SIGKILL` | Kills the process immediately | -| `SIGINT` | Stops the server gracefully | +| `SIGINT` | Stops the server gracefully | | `SIGUSR1` | Reopens the log file for log rotation | -| `SIGHUP` | Reloads server configuration file | -| `SIGUSR2` | Stops the server after evicting all clients (lame duck mode) | +| `SIGHUP` | Reloads server configuration file | +| `SIGUSR2` | Stops the server after evicting all clients \(lame duck mode\) | The `nats-server` binary can be used to send these signals to running NATS servers using the `-sl` flag: -```sh +```bash # Quit the server nats-server --signal quit @@ -31,12 +31,13 @@ nats-server --signal ldm If there are multiple `nats-server` processes running, or if `pgrep` isn't available, you must either specify a PID or the absolute path to a PID file: -```sh +```bash nats-server --signal stop= ``` -```sh +```bash nats-server --signal stop=/path/to/pidfile ``` -See the [Windows Service](/nats_server/windows_srv.md) section for information on signaling the NATS server on Windows. \ No newline at end of file +See the [Windows Service](../running/windows_srv.md) section for information on signaling the NATS server on Windows. + diff --git a/nats-server/nats_admin/slow_consumers.md b/nats-server/nats_admin/slow_consumers.md new file mode 100644 index 0000000..767f08d --- /dev/null +++ b/nats-server/nats_admin/slow_consumers.md @@ -0,0 +1,112 @@ +# Slow Consumers + +To support resiliency and high availability, NATS provides built-in mechanisms to automatically prune the registered listener interest graph that is used to keep track of subscribers, including slow consumers and lazy listeners. NATS automatically handles a slow consumer. If a client is not processing messages quick enough, the NATS server cuts it off. To support scaling, NATS provides for auto-pruning of client connections. If a subscriber does not respond to ping requests from the server within the [ping-pong interval](../../nats-protocol/nats-protocol/#PINGPONG), the client is cut off \(disconnected\). The client will need to have reconnect logic to reconnect with the server. + +In core NATS, consumers that cannot keep up are handled differently from many other messaging systems: NATS favors the approach of protecting the system as a whole over accommodating a particular consumer to ensure message delivery. + +**What is a slow consumer?** + +A slow consumer is a subscriber that cannot keep up with the message flow delivered from the NATS server. This is a common case in distributed systems because it is often easier to generate data than it is to process it. When consumers cannot process data fast enough, back pressure is applied to the rest of the system. NATS has mechanisms to reduce this back pressure. + +NATS identifies slow consumers in the client or the server, providing notification through registered callbacks, log messages, and statistics in the server's monitoring endpoints. + +**What happens to slow consumers?** + +When detected at the client, the application is notified and messages are dropped to allow the consumer to continue and reduce potential back pressure. When detected in the server, the server will disconnect the connection with the slow consumer to protect itself and the integrity of the messaging system. + +## Slow consumers identified in the client + +A [client can detect it is a slow consumer](../../developing-with-nats/intro-5/slow.md) on a local connection and notify the application through use of the asynchronous error callback. It is better to catch a slow consumer locally in the client rather than to allow the server to detect this condition. This example demonstrates how to define and register an asynchronous error handler that will handle slow consumer errors. + +```go +func natsErrHandler(nc *nats.Conn, sub *nats.Subscription, natsErr error) { + fmt.Printf("error: %v\n", natsErr) + if natsErr == nats.ErrSlowConsumer { + pendingMsgs, _, err := sub.Pending() + if err != nil { + fmt.Printf("couldn't get pending messages: %v", err) + return + } + fmt.Printf("Falling behind with %d pending messages on subject %q.\n", + pendingMsgs, sub.Subject) + // Log error, notify operations... + } + // check for other errors +} + +// Set the error handler when creating a connection. +nc, err := nats.Connect("nats://localhost:4222", + nats.ErrorHandler(natsErrHandler)) +``` + +With this example code and default settings, a slow consumer error would generate output something like this: + +```bash +error: nats: slow consumer, messages dropped +Falling behind with 65536 pending messages on subject "foo". +``` + +Note that if you are using a synchronous subscriber, `Subscription.NextMsg(timeout time.Duration)` will also return an error indicating there was a slow consumer and messages have been dropped. + +## Slow consumers identified by the server + +When a client does not process messages fast enough, the server will buffer messages in the outbound connection to the client. When this happens and the server cannot write data fast enough to the client, in order to protect itself, it will designate a subscriber as a "slow consumer" and may drop the associated connection. + +When the server initiates a slow consumer error, you'll see the following in the server output: + +```bash +[54083] 2017/09/28 14:45:18.001357 [INF] ::1:63283 - cid:7 - Slow Consumer Detected +``` + +The server will also keep count of the number of slow consumer errors encountered, available through the monitoring `varz` endpoint in the `slow_consumers` field. + +## Handling slow consumers + +Apart from using [NATS streaming](../../nats-streaming-concepts/intro.md) or optimizing your consuming application, there are a few options available: scale, meter, or tune NATS to your environment. + +**Scaling with queue subscribers** + +This is ideal if you do not rely on message order. Ensure your NATS subscription belongs to a [queue group](../../concepts/queue.md), then scale as required by creating more instances of your service or application. This is a great approach for microservices - each instance of your microservice will receive a portion of the messages to process, and simply add more instances of your service to scale. No code changes, configuration changes, or downtime whatsoever. + +**Create a subject namespace that can scale** + +You can distribute work further through the subject namespace, with some forethought in design. This approach is useful if you need to preserve message order. The general idea is to publish to a deep subject namespace, and consume with wildcard subscriptions while giving yourself room to expand and distribute work in the future. + +For a simple example, if you have a service that receives telemetry data from IoT devices located throughout a city, you can publish to a subject namespace like `Sensors.North`, `Sensors.South`, `Sensors.East` and `Sensors.West`. Initially, you'll subscribe to `Sensors.>` to process everything in one consumer. As your enterprise grows and data rates exceed what one consumer can handle, you can replace your single consumer with four consuming applications to subscribe to each subject representing a smaller segment of your data. Note that your publishing applications remain untouched. + +**Meter the publisher** + +A less favorable option may be to meter the publisher. There are several ways to do this varying from simply slowing down your publisher to a more complex approach periodically issuing a blocking request/reply to match subscriber rates. + +**Tune NATS through configuration** + +The NATS server can be tuned to determine how much data can be buffered before a consumer is considered slow, and some officially supported clients allow buffer sizes to be adjusted. Decreasing buffer sizes will let you identify slow consumers more quickly. Increasing buffer sizes is not typically recommended unless you are handling temporary bursts of data. Often, increasing buffer capacity will only _postpone_ slow consumer problems. + +### Server Configuration + +The NATS server has a write deadline it uses to write to a connection. When this write deadline is exceeded, a client is considered to have a slow consumer. If you are encountering slow consumer errors in the server, you can increase the write deadline to buffer more data. + +The `write_deadline` configuration option in the NATS server configuration file will tune this: + +```text +write_deadline: 2s +``` + +Tuning this parameter is ideal when you have bursts of data to accommodate. _**Be sure you are not just postponing a slow consumer error.**_ + +### Client Configuration + +Most officially supported clients have an internal buffer of pending messages and will notify your application through an asynchronous error callback if a local subscription is not catching up. Receiving an error locally does not necessarily mean that the server will have identified a subscription as a slow consumer. + +This buffer can be configured through setting the pending limits after a subscription has been created: + +```go +if err := sub.SetPendingLimits(1024*500, 1024*5000); err != nil { + log.Fatalf("Unable to set pending limits: %v", err) +} +``` + +The default subscriber pending message limit is `65536`, and the default subscriber pending byte limit is `65536*1024` + +If the client reaches this internal limit, it will drop messages and continue to process new messages. This is aligned with NATS at most once delivery. It is up to your application to detect the missing messages and recover from this condition. + diff --git a/sys_accounts/README.md b/nats-server/nats_admin/sys_accounts/README.md similarity index 53% rename from sys_accounts/README.md rename to nats-server/nats_admin/sys_accounts/README.md index b7403a5..03947a8 100644 --- a/sys_accounts/README.md +++ b/nats-server/nats_admin/sys_accounts/README.md @@ -1,15 +1,17 @@ -## System Events +# System Accounts -NATS servers leverage [Account](/nats_server/jwt_auth.md) support and generate events such as: +NATS servers leverage [Account](../../configuration/securing_nats/auth_intro/jwt_auth.md) support and generate events such as: -- account connect/disconnect -- authentication errors -- server shutdown -- server stat summary +* account connect/disconnect +* authentication errors +* server shutdown +* server stat summary In addition the server supports a limitted number of requests that can be used to query for account connections, server stat summaries, and pinging servers in the cluster. -These events are only accepted and visible to _system account_ users. +These events are only accepted and visible to _system account_ users. + +## The System Events Tutorial -### The System Events Tutorial You can learn more about System Accounts in the [Tutorial](sys_accounts.md). + diff --git a/sys_accounts/sys_accounts.md b/nats-server/nats_admin/sys_accounts/sys_accounts.md similarity index 78% rename from sys_accounts/sys_accounts.md rename to nats-server/nats_admin/sys_accounts/sys_accounts.md index 192cd76..3b23de3 100644 --- a/sys_accounts/sys_accounts.md +++ b/nats-server/nats_admin/sys_accounts/sys_accounts.md @@ -1,51 +1,50 @@ -## System Events Tutorial +# Configuration The following is a short tutorial on how you can activate a system account to: -- receive periodic updates from the server -- send requests to the server -- send an account update to the server +* receive periodic updates from the server +* send requests to the server +* send an account update to the server -### Events and Services +## Events and Services The system account publishes messages under well known subject patterns. Server initiated events: -- `$SYS.ACCOUNT..CONNECT` (client connects) -- `$SYS.ACCOUNT..DISCONNECT` (client disconnects) -- `$SYS.SERVER.ACCOUNT..CONNS` (connections for an account changed) -- `$SYS.SERVER..CLIENT.AUTH.ERR` (authentication error) -- `$SYS.ACCOUNT..LEAFNODE.CONNECT` (leaf node connnects) -- `$SYS.ACCOUNT..LEAFNODE.DISCONNECT` (leaf node disconnects) -- `$SYS.SERVER..STATSZ` (stats summary) +* `$SYS.ACCOUNT..CONNECT` \(client connects\) +* `$SYS.ACCOUNT..DISCONNECT` \(client disconnects\) +* `$SYS.SERVER.ACCOUNT..CONNS` \(connections for an account changed\) +* `$SYS.SERVER..CLIENT.AUTH.ERR` \(authentication error\) +* `$SYS.ACCOUNT..LEAFNODE.CONNECT` \(leaf node connnects\) +* `$SYS.ACCOUNT..LEAFNODE.DISCONNECT` \(leaf node disconnects\) +* `$SYS.SERVER..STATSZ` \(stats summary\) In addition other tools with system account privileges, can initiate requests: -- `$SYS.REQ.SERVER..STATSZ` (request server stat summary) -- `$SYS.REQ.SERVER.PING` (discover servers - will return multiple messages) - +* `$SYS.REQ.SERVER..STATSZ` \(request server stat summary\) +* `$SYS.REQ.SERVER.PING` \(discover servers - will return multiple messages\) Servers like `nats-account-server` publish system account messages when a claim is updated, the nats-server listens for them, and updates its account information accordingly: -- `$SYS.ACCOUNT..CLAIMS.UPDATE` +* `$SYS.ACCOUNT..CLAIMS.UPDATE` With these few messages you can build fairly surprisingly useful monitoring tools: -- health/load of your servers -- client connects/disconnects -- account connections -- authentication errors +* health/load of your servers +* client connects/disconnects +* account connections +* authentication errors -### Enabling System Events +## Enabling System Events To enable and access system events, you'll have to: -- Create an Operator, Account and User -- Run a NATS Account Server (or Memory Resolver) +* Create an Operator, Account and User +* Run a NATS Account Server \(or Memory Resolver\) +### Create an Operator, Account, User -#### Create an Operator, Account, User Let's create an operator, system account and system account user: ```text @@ -68,23 +67,26 @@ Success! - added user "SYSU" to "SYS" By default, the operator JWT can be found in `~/.nsc/nats//.jwt`. -#### Nats-Account-Server +### Nats-Account-Server + +To vend the credentials to the nats-server, we'll use a [nats-account-server](../../../nats-tools/nas/). Let's start a nats-account-server to serve the JWT credentials: -To vend the credentials to the nats-server, we'll use a [nats-account-server](/nats_tools/nas/README.md). Let's start a nats-account-server to serve the JWT credentials: ```text > nats-account-server -nsc ~/.nsc/nats/SAOP ``` The server will by default vend JWT configurations on the an endpoint at: `http(s):///jwt/v1/accounts/`. -#### NATS Server Configuration +### NATS Server Configuration The server configuration will need: -- The operator JWT - (`~/.nsc/nats//.jwt`) -- The URL where the server can resolve accounts (`http://localhost:9090/jwt/v1/accounts/`) -- The public key of the `system_account` + +* The operator JWT - \(`~/.nsc/nats//.jwt`\) +* The URL where the server can resolve accounts \(`http://localhost:9090/jwt/v1/accounts/`\) +* The public key of the `system_account` The only thing we don't have handy is the public key for the system account. We can get it easy enough: + ```text > nsc list accounts -W ╭─────────────────────────────────────────────────────────────────╮ @@ -98,37 +100,39 @@ The only thing we don't have handy is the public key for the system account. We Because the server has additional resolver implementations, you need to enclose the server url like: `URL()`. - Let's create server config with the following contents and save it to `server.conf`: + ```text operator: /Users/synadia/.nsc/nats/SAOP/SAOP.jwt system_account: ADWJVSUSEVC2GHL5GRATN2LOEOQOY2E6Z2VXNU3JEIK6BDGPWNIW3AXF resolver: URL(http://localhost:9090/jwt/v1/accounts/) ``` - Let's start the nats-server: + ```text > nats-server -c server.conf ``` -### Inspecting Server Events +## Inspecting Server Events Let's add a subscriber for all the events published by the system account: ```text > nats-sub -creds ~/.nkeys/SAOP/accounts/SYS/users/SYSU.creds ">" ``` + Very quickly we'll start seeing messages from the server as they are published by the NATS server. As should be expected, the messages are just JSON, so they can easily be inspected even if just using a simple `nats-sub` to read them. To see an an account update: + ```text > nats-pub -creds ~/.nkeys/SAOP/accounts/SYS/users/SYSU.creds foo bar ``` The subscriber will print the connect and disconnect: + ```text -[#35] Received on [$SYS.SERVER.ACCOUNT.ADWJVSUSEVC2GHL5GRATN2LOEOQOY2E6Z2VXNU3JEIK6BDGPWNIW3AXF.CONNS]: '{ "server": { "host": "0.0.0.0", "id": "NBTGVY3OKDKEAJPUXRHZLKBCRH3LWCKZ6ZXTAJRS2RMYN3PMDRMUZWPR", @@ -140,7 +144,6 @@ The subscriber will print the connect and disconnect: "conns": 1, "total_conns": 1 }' -[#36] Received on [$SYS.ACCOUNT.ADWJVSUSEVC2GHL5GRATN2LOEOQOY2E6Z2VXNU3JEIK6BDGPWNIW3AXF.DISCONNECT]: '{ "server": { "host": "0.0.0.0", "id": "NBTGVY3OKDKEAJPUXRHZLKBCRH3LWCKZ6ZXTAJRS2RMYN3PMDRMUZWPR", @@ -171,8 +174,7 @@ The subscriber will print the connect and disconnect: }' ``` - -### `$SYS.REQ.SERVER.PING` - Discovering Servers +## `$SYS.REQ.SERVER.PING` - Discovering Servers To discover servers in the cluster, and get a small heath summary, publish a request to `$SYS.REQ.SERVER.PING`. Note that while the example below uses `nats-req`, only the first answer for the request will be printed. You can easily modify the example to wait until no additional responses are received for a specific amount of time, thus allowing for all responses to be collected. @@ -209,9 +211,9 @@ Received [_INBOX.G5mbsf0k7l7nb4eWHa7GTT.omklmvnm] : '{ }' ``` -### `$SYS.SERVER..STATSZ` - Requesting Server Stats Summary +## `$SYS.SERVER..STATSZ` - Requesting Server Stats Summary -If you know the server id for a particular server (such as from a response to `$SYS.REQ.SERVER.PING`), you can query the specific server for its health information: +If you know the server id for a particular server \(such as from a response to `$SYS.REQ.SERVER.PING`\), you can query the specific server for its health information: ```text nats-req -creds ~/.nkeys/SAOP/accounts/SYS/users/SYSU.creds \$SYS.REQ.SERVER.NC7AKPQRC6CIZGWRJOTVFIGVSL7VW7WXTQCTUJFNG7HTCMCKQTGE5PUL.STATSZ "" @@ -244,8 +246,5 @@ Received [_INBOX.DQD44ugVt0O4Ur3pWIOOD1.WQOBevoq] : '{ "slow_consumers": 0 } }' - ``` - - diff --git a/nats_admin/upgrading_cluster.md b/nats-server/nats_admin/upgrading_cluster.md similarity index 68% rename from nats_admin/upgrading_cluster.md rename to nats-server/nats_admin/upgrading_cluster.md index 3eb96da..f6101ee 100644 --- a/nats_admin/upgrading_cluster.md +++ b/nats-server/nats_admin/upgrading_cluster.md @@ -1,10 +1,10 @@ -## Cluster Upgrading +# Upgrading a Cluster -The basic strategy for upgrading a cluster revolves around the server's ability to gossip cluster configuration to clients and other servers. When cluster configuration changes, clients become aware of new servers automatically. In the case of a disconnect, a client has a list of servers that joined the cluster in addition to the ones it knew about from its connection settings. +The basic strategy for upgrading a cluster revolves around the server's ability to gossip cluster configuration to clients and other servers. When cluster configuration changes, clients become aware of new servers automatically. In the case of a disconnect, a client has a list of servers that joined the cluster in addition to the ones it knew about from its connection settings. Note that since each server stores it's own permission and authentication configuration, new servers added to a cluster should provide the same users and authorization to prevent clients from getting rejected or gaining unexpected privileges. -For purposes of describing the scenario, let's get some fingers on keyboards, and go through the motions. Let's consider a cluster of two servers: 'A' and 'B', and yes - clusters should be *three* to *five* servers, but for purposes of describing the behavior and cluster upgrade process, a cluster of two servers will suffice. +For purposes of describing the scenario, let's get some fingers on keyboards, and go through the motions. Let's consider a cluster of two servers: 'A' and 'B', and yes - clusters should be _three_ to _five_ servers, but for purposes of describing the behavior and cluster upgrade process, a cluster of two servers will suffice. Let's build this cluster: @@ -12,32 +12,33 @@ Let's build this cluster: nats-server -D -p 4222 -cluster nats://localhost:6222 -routes nats://localhost:6222,nats://localhost:6333 ``` -The command above is starting nats-server with debug output enabled, listening for clients on port 4222, and accepting cluster connections on port 6222. The `-routes` option specifies a list of nats URLs where the server will attempt to connect -to other servers. These URLs define the cluster ports enabled on the cluster peers. +The command above is starting nats-server with debug output enabled, listening for clients on port 4222, and accepting cluster connections on port 6222. The `-routes` option specifies a list of nats URLs where the server will attempt to connect to other servers. These URLs define the cluster ports enabled on the cluster peers. Keen readers will notice a self-route. The NATS server will ignore the self-route, but it makes for a single consistent configuration for all servers. You will see the server started, we notice it emits some warnings because it cannot connect to 'localhost:6333'. The message more accurately reads: -```ascii +```text Error trying to connect to route: dial tcp localhost:6333: connect: connection refused ``` Let's fix that, by starting the second server: + ```bash nats-server -D -p 4333 -cluster nats://localhost:6333 -routes nats://localhost:6222,nats://localhost:6333 ``` + The second server was started on port 4333 with its cluster port on 6333. Otherwise the same as 'A'. Let's get one client, so we can observe it moving between servers as servers get removed: + ```bash nats-sub -s nats://localhost:4222 ">" ``` -`nats-sub` is a subscriber sample included with all NATS clients. `nats-sub` subscribes to a subject and prints out any messages received. You can find the source code to the go version of `nats-sub` [here)(https://github.com/nats-io/nats.go/tree/master/examples). After starting the subscriber you should see a message on 'A' that a new client connected. +`nats-sub` is a subscriber sample included with all NATS clients. `nats-sub` subscribes to a subject and prints out any messages received. You can find the source code to the go version of `nats-sub` \[here\)\([https://github.com/nats-io/nats.go/tree/master/examples](https://github.com/nats-io/nats.go/tree/master/examples)\). After starting the subscriber you should see a message on 'A' that a new client connected. -We have two servers and a client. Time to simulate our rolling upgrade. But wait, before we upgrade 'A', let's introduce a new server 'C'. Server 'C' will join the existing cluster while we perform the upgrade. Its sole purpose is to provide an additional place where clients can go other than 'A' and ensure we don't end up with a single server serving all the clients after the upgrade procedure. Clients will randomly select a server when connecting unless a special option is provided that disables that functionality (usually called 'DontRandomize' or 'noRandomize'). You can read more about ["Avoiding the Thundering Herd"](/developer/reconnect/random.md/). -Suffice it to say that clients redistribute themselves about evenly between all servers in the cluster. In our case 1/2 of the clients on 'A' will jump over to 'B' and the remaining half to 'C'. +We have two servers and a client. Time to simulate our rolling upgrade. But wait, before we upgrade 'A', let's introduce a new server 'C'. Server 'C' will join the existing cluster while we perform the upgrade. Its sole purpose is to provide an additional place where clients can go other than 'A' and ensure we don't end up with a single server serving all the clients after the upgrade procedure. Clients will randomly select a server when connecting unless a special option is provided that disables that functionality \(usually called 'DontRandomize' or 'noRandomize'\). You can read more about ["Avoiding the Thundering Herd"](../../developing-with-nats/intro-1/random.md). Suffice it to say that clients redistribute themselves about evenly between all servers in the cluster. In our case 1/2 of the clients on 'A' will jump over to 'B' and the remaining half to 'C'. Let's start our temporary server: @@ -45,7 +46,7 @@ Let's start our temporary server: nats-server -D -p 4444 -cluster nats://localhost:6444 -routes nats://localhost:6222,nats://localhost:6333 ``` -After an instant or so, clients on 'A' learn of the new cluster member that joined. On our hands-on tutorial, `nats-sub` is now aware of 3 possible servers, 'A' (specified when we started the tool) and 'B' and 'C' learned from the cluster gossip. +After an instant or so, clients on 'A' learn of the new cluster member that joined. On our hands-on tutorial, `nats-sub` is now aware of 3 possible servers, 'A' \(specified when we started the tool\) and 'B' and 'C' learned from the cluster gossip. We invoke our admin powers and turn off 'A' by issuing a `CTRL+C` to the terminal on 'A' and observe that either 'B' or 'C' reports that a new client connected. That is our `nats-sub` client. @@ -61,26 +62,29 @@ We move on to upgrade 'B'. Notice that clients from 'B' reconnect to 'A' and 'C' nats-server -D -p 4333 -cluster nats://localhost:6333 -routes nats://localhost:6222,nats://localhost:6333 ``` -If we had more servers, we would continue the stop, update, restart rotation as we did for 'A' and 'B'. After restarting the last server, we can go ahead and turn off 'C.' Any clients on 'C' will redistribute to our permanent cluster members. +If we had more servers, we would continue the stop, update, restart rotation as we did for 'A' and 'B'. After restarting the last server, we can go ahead and turn off 'C.' Any clients on 'C' will redistribute to our permanent cluster members. - -### Seed Servers +## Seed Servers In the examples above we started nats-server specifying two clustering routes. It is possible to allow the server gossip protocol drive it and reduce the amount of configuration. You could for example start A, B and C as follows: -#### A - Seed Server +### A - Seed Server + ```bash nats-server -D -p 4222 -cluster nats://localhost:6222 ``` -#### B +### B + ```bash nats-server -D -p 4333 -cluster nats://localhost:6333 -routes nats://localhost:6222 ``` -#### C +### C + ```bash nats-server -D -p 4444 -cluster nats://localhost:6444 -routes nats://localhost:6222 ``` Once they connect to the 'seed server', they will learn about all the other servers and connect to each other forming the full mesh. + diff --git a/nats_docker/README.md b/nats-server/nats_docker/README.md similarity index 84% rename from nats_docker/README.md rename to nats-server/nats_docker/README.md index 39dabd3..1f6c82b 100644 --- a/nats_docker/README.md +++ b/nats-server/nats_docker/README.md @@ -1,3 +1,4 @@ +# NATS and Docker ## NATS Server Containerization @@ -9,26 +10,26 @@ The NATS server is provided as a Docker image on [Docker Hub](https://hub.docker To use the Docker container image, install Docker and pull the public image: -```sh +```bash > docker pull nats ``` Run the NATS server image: -```sh +```bash > docker run -d --name nats-main nats ``` By default the NATS server exposes multiple ports: -- 4222 is for clients. -- 8222 is an HTTP management port for information reporting. -- 6222 is a routing port for clustering. -- Use -p or -P to customize. +* 4222 is for clients. +* 8222 is an HTTP management port for information reporting. +* 6222 is a routing port for clustering. +* Use -p or -P to customize. For example: -```sh +```bash $ docker run -d --name nats-main nats [INF] Starting nats-server version 0.6.6 [INF] Starting http monitor on port 8222 @@ -39,19 +40,19 @@ $ docker run -d --name nats-main nats To run with the ports exposed on the host: -```sh +```bash > docker run -d -p 4222:4222 -p 6222:6222 -p 8222:8222 --name nats-main nats ``` To run a second server and cluster them together: -```sh +```bash > docker run -d --name=nats-2 --link nats-main nats --routes=nats-route://ruser:T0pS3cr3t@nats-main:6222 ``` **NOTE** Since the Docker image protects routes using credentials we need to provide them above. Extracted [from Docker image configuration](https://github.com/nats-io/nats-docker/blob/master/amd64/nats-server.conf#L16-L20) -```ascii +```text # Routes are protected, so need to use them with --routes flag # e.g. --routes=nats-route://ruser:T0pS3cr3t@otherdockerhost:6222 authorization { @@ -63,7 +64,7 @@ authorization { To verify the routes are connected: -```sh +```bash $ docker run -d --name=nats-2 --link nats-main nats --routes=nats-route://ruser:T0pS3cr3t@nats-main:6222 -DV [INF] Starting nats-server version 2.0.0 [INF] Starting http monitor on port 8222 @@ -79,16 +80,16 @@ $ docker run -d --name=nats-2 --link nats-main nats --routes=nats-route://ruser: ## Clustering With Docker -Below is are a couple examples of how to setup nats-server cluster using Docker. We put 3 different configurations (one per nats-server server) under a folder named conf as follows: +Below is are a couple examples of how to setup nats-server cluster using Docker. We put 3 different configurations \(one per nats-server server\) under a folder named conf as follows: -```ascii +```text |-- conf |-- nats-server-A.conf |-- nats-server-B.conf |-- nats-server-C.conf ``` -Each one of those files have the following content below: (Here I am using ip 192.168.59.103 as an example, so just replace with the proper ip from your server) +Each one of those files have the following content below: \(Here I am using ip 192.168.59.103 as an example, so just replace with the proper ip from your server\) ### Example 1: Setting up a cluster on 3 different servers provisioned beforehand @@ -96,7 +97,7 @@ In this example, the three servers are started with config files that know about #### nats-server-A -```ascii +```text # Cluster Server A port: 7222 @@ -114,7 +115,7 @@ cluster { #### nats-server-B -```ascii +```text # Cluster Server B port: 8222 @@ -132,7 +133,7 @@ cluster { #### nats-server-C -```ascii +```text # Cluster Server C port: 9222 @@ -150,15 +151,15 @@ cluster { To start the containers, on each one of your servers, you should be able to start the nats-server image as follows: -```sh +```bash docker run -it -p 0.0.0.0:7222:7222 -p 0.0.0.0:7244:7244 --rm -v $(pwd)/conf/nats-server-A.conf:/tmp/cluster.conf nats -c /tmp/cluster.conf -p 7222 -D -V ``` -``` +```text docker run -it -p 0.0.0.0:8222:8222 -p 0.0.0.0:7246:7246 --rm -v $(pwd)/conf/nats-server-B.conf:/tmp/cluster.conf nats -c /tmp/cluster.conf -p 8222 -D -V ``` -``` +```text docker run -it -p 0.0.0.0:9222:9222 -p 0.0.0.0:7248:7248 --rm -v $(pwd)/conf/nats-server-C.conf:/tmp/cluster.conf nats -c /tmp/cluster.conf -p 9222 -D -V ``` @@ -166,13 +167,13 @@ docker run -it -p 0.0.0.0:9222:9222 -p 0.0.0.0:7248:7248 --rm -v $(pwd)/conf/nat In this scenario: -- We bring up A and get its ip (nats-route://192.168.59.103:7244) -- Then create B and then use address of A in its configuration. -- Get the address of B nats-route://192.168.59.104:7246 and create C and use the addresses of A and B. +* We bring up A and get its ip \(nats-route://192.168.59.103:7244\) +* Then create B and then use address of A in its configuration. +* Get the address of B nats-route://192.168.59.104:7246 and create C and use the addresses of A and B. First, we create the Node A and start up a nats-server server with the following config: -```ascii +```text # Cluster Server A port: 4222 @@ -184,13 +185,13 @@ cluster { } ``` -```sh +```bash docker run -it -p 0.0.0.0:4222:4222 -p 0.0.0.0:7244:7244 --rm -v $(pwd)/conf/nats-server-A.conf:/tmp/cluster.conf nats -c /tmp/cluster.conf -p 4222 -D -V ``` Then we proceed to create the next node. We realize that the first node has ip:port as `192.168.59.103:7244` so we add this to the routes configuration as follows: -```ascii +```text # Cluster Server B port: 4222 @@ -207,13 +208,13 @@ cluster { Then start server B: -```sh +```bash docker run -it -p 0.0.0.0:4222:4222 -p 0.0.0.0:7244:7244 --rm -v $(pwd)/conf/nats-server-B.conf:/tmp/cluster.conf nats -c /tmp/cluster.conf -p 4222 -D -V ``` Finally, we create another Node C. We now know the routes of A and B so we can add it to its configuration: -```ascii +```text # Cluster Server C port: 4222 @@ -231,7 +232,7 @@ cluster { Then start it: -```sh +```bash docker run -it -p 0.0.0.0:4222:4222 -p 0.0.0.0:7244:7244 --rm -v $(pwd)/conf/nats-server-C.conf:/tmp/cluster.conf nats -c /tmp/cluster.conf -p 9222 -D -V ``` @@ -239,7 +240,7 @@ docker run -it -p 0.0.0.0:4222:4222 -p 0.0.0.0:7244:7244 --rm -v $(pwd)/conf/nat Now, the following should work: make a subscription to Node A then publish to Node C. You should be able to to receive the message without problems. -```sh +```bash nats-sub -s "nats://192.168.59.103:7222" hello & nats-pub -s "nats://192.168.59.105:7222" hello world @@ -255,4 +256,5 @@ nats-pub -s "nats://192.168.59.105:7222" hello world ## Tutorial -See the [NATS Docker tutorial](tutorial.md) for more instructions on using the NATS server Docker image. +See the [NATS Docker tutorial](https://github.com/nats-io/nats.docs/tree/51fc56e3090645f7cedb242415e2d5361e1807e7/nats_docker/tutorial.md) for more instructions on using the NATS server Docker image. + diff --git a/nats_docker/docker_swarm.md b/nats-server/nats_docker/docker_swarm.md similarity index 82% rename from nats_docker/docker_swarm.md rename to nats-server/nats_docker/docker_swarm.md index 5b3fdda..d9c0798 100644 --- a/nats_docker/docker_swarm.md +++ b/nats-server/nats_docker/docker_swarm.md @@ -1,24 +1,26 @@ -## Docker Swarm +# Docker Swarm -#### Step 1: -Create an overlay network for the cluster (in this example, `nats-cluster-example`), and instantiate an initial NATS server. +### Step 1: + +Create an overlay network for the cluster \(in this example, `nats-cluster-example`\), and instantiate an initial NATS server. First create an overlay network: -```sh +```bash % docker network create --driver overlay nats-cluster-example ``` Next instantiate an initial "seed" server for a NATS cluster listening for other servers to join route to it on port 6222: -```sh +```bash % docker service create --network nats-cluster-example --name nats-cluster-node-1 nats:1.0.0 -cluster nats://0.0.0.0:6222 -DV ``` -#### Step 2: -The 2nd step is to create another service which connects to the NATS server within the overlay network. Note that we connect to to the server at `nats-cluster-node-1`: +### Step 2: -```sh +The 2nd step is to create another service which connects to the NATS server within the overlay network. Note that we connect to to the server at `nats-cluster-node-1`: + +```bash % docker service create --name ruby-nats --network nats-cluster-example wallyqs/ruby-nats:ruby-2.3.1-nats-v0.8.0 -e ' NATS.on_error do |e| puts "ERROR: #{e}" @@ -44,24 +46,25 @@ The 2nd step is to create another service which connects to the NATS server with end' ``` -#### Step 3: +### Step 3: + Now you can add more nodes to the Swarm cluster via more docker services, referencing the seed server in the `-routes` parameter: -```sh +```bash % docker service create --network nats-cluster-example --name nats-cluster-node-2 nats:1.0.0 -cluster nats://0.0.0.0:6222 -routes nats://nats-cluster-node-1:6222 -DV ``` -In this case, `nats-cluster-node-1` is seeding the rest of the cluster through the autodiscovery feature. Now NATS servers `nats-cluster-node-1` and `nats-cluster-node-2` are clustered together. +In this case, `nats-cluster-node-1` is seeding the rest of the cluster through the autodiscovery feature. Now NATS servers `nats-cluster-node-1` and `nats-cluster-node-2` are clustered together. Add in more replicas of the subscriber: -```sh +```bash % docker service scale ruby-nats=3 ``` Then confirm the distribution on the Docker Swarm cluster: -```sh +```bash % docker service ps ruby-nats ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR 25skxso8honyhuznu15e4989m ruby-nats.1 wallyqs/ruby-nats:ruby-2.3.1-nats-v0.8.0 node-1 Running Running 2 minutes ago @@ -69,27 +72,29 @@ ID NAME IMAGE 2sxl8rw6vm99x622efbdmkb96 ruby-nats.3 wallyqs/ruby-nats:ruby-2.3.1-nats-v0.8.0 node-2 Running Running 2 minutes ago ``` -The sample output after adding more NATS server nodes to the cluster, is below - and notice that the client is *dynamically* aware of more nodes being part of the cluster via auto discovery! +The sample output after adding more NATS server nodes to the cluster, is below - and notice that the client is _dynamically_ aware of more nodes being part of the cluster via auto discovery! -```sh +```bash [2016-08-15 12:51:52 +0000] Saying hi (servers in pool: [{:uri=>#, :was_connected=>true, :reconnect_attempts=>0}] [2016-08-15 12:51:53 +0000] Saying hi (servers in pool: [{:uri=>#, :was_connected=>true, :reconnect_attempts=>0}] [2016-08-15 12:51:54 +0000] Saying hi (servers in pool: [{:uri=>#, :was_connected=>true, :reconnect_attempts=>0}] [2016-08-15 12:51:55 +0000] Saying hi (servers in pool: [{:uri=>#, :was_connected=>true, :reconnect_attempts=>0}, {:uri=>#, :reconnect_attempts=>0}, {:uri=>#, :reconnect_attempts=>0}] ``` -Sample output after adding more workers which can reply back (since ignoring own responses): +Sample output after adding more workers which can reply back \(since ignoring own responses\): -```sh +```bash [2016-08-15 16:06:26 +0000] Received reply - world [2016-08-15 16:06:26 +0000] Received reply - world [2016-08-15 16:06:27 +0000] Received greeting - hi - _INBOX.b8d8c01753d78e562e4dc561f1 [2016-08-15 16:06:27 +0000] Received greeting - hi - _INBOX.4c35d18701979f8c8ed7e5f6ea ``` -### And so forth... -From here you can experiment adding to the NATS cluster by simply adding servers with new service names, that route to the seed server `nats-cluster-node-1`. As you've seen above, clients will automatically be updated to know that new servers are available in the cluster. +## And so forth... -```sh +From here you can experiment adding to the NATS cluster by simply adding servers with new service names, that route to the seed server `nats-cluster-node-1`. As you've seen above, clients will automatically be updated to know that new servers are available in the cluster. + +```bash % docker service create --network nats-cluster-example --name nats-cluster-node-3 nats:1.0.0 -cluster nats://0.0.0.0:6222 -routes nats://nats-cluster-node-1:6222 -DV -``` \ No newline at end of file +``` + diff --git a/nats_docker/nats-docker-tutorial.md b/nats-server/nats_docker/nats-docker-tutorial.md similarity index 87% rename from nats_docker/nats-docker-tutorial.md rename to nats-server/nats_docker/nats-docker-tutorial.md index acdce8a..730488f 100644 --- a/nats_docker/nats-docker-tutorial.md +++ b/nats-server/nats_docker/nats-docker-tutorial.md @@ -1,6 +1,6 @@ -## NATS Docker Tutorial +# Tutorial -In this tutorial you run the [NATS server Docker image](https://hub.docker.com/_/nats/). The Docker image provides an instance of the [NATS Server](/README.md). Synadia actively maintains and supports the nats-server Docker image. The NATS image is only 6 MB in size. +In this tutorial you run the [NATS server Docker image](https://hub.docker.com/_/nats/). The Docker image provides an instance of the [NATS Server](../../). Synadia actively maintains and supports the nats-server Docker image. The NATS image is only 6 MB in size. **1. Set up Docker.** @@ -10,7 +10,7 @@ The easiest way to run Docker is to use the [Docker Toolbox](http://docs.docker. **2. Run the nats-server Docker image.** -```sh +```bash > docker run -p 4222:4222 -p 8222:8222 -p 6222:6222 --name nats-server -ti nats:latest ``` @@ -18,7 +18,7 @@ The easiest way to run Docker is to use the [Docker Toolbox](http://docs.docker. You should see the following: -```sh +```bash Unable to find image 'nats:latest' locally latest: Pulling from library/nats 2d3d00b0941f: Pull complete @@ -29,7 +29,7 @@ Status: Downloaded newer image for nats:latest Followed by this, indicating that the NATS server is running: -```sh +```bash [1] 2019/06/01 18:34:19.605144 [INF] Starting nats-server version 2.0.0 [1] 2019/06/01 18:34:19.605191 [INF] Starting http monitor on 0.0.0.0:8222 [1] 2019/06/01 18:34:19.605286 [INF] Listening for client connections on 0.0.0.0:4222 @@ -43,17 +43,18 @@ Notice how quickly the NATS server Docker image downloads. It is a mere 6 MB in An easy way to test the client connection port is through using telnet. -```sh +```bash > telnet localhost 4222 ``` Expected result: -```sh +```bash Trying ::1... Connected to localhost. Escape character is '^]'. -INFO {"server_id":"NDP7NP2P2KADDDUUBUDG6VSSWKCW4IC5BQHAYVMLVAJEGZITE5XP7O5J","version":"2.0.0","proto":1,"go":"go1.11.10","host":"0.0.0.0","port":4222,"max_payload":1048576,"client_id":13249} +INFO {"server_id":"NDP7NP2P2KADDDUUBUDG6VSSWKCW4IC5BQHAYVMLVAJEGZITE5XP7O5J","version":"2.0.0","proto":1,"go":"go1.11.10","host":"0.0.0.0","port":4222,"max_payload":1048576,"client_id":13249} ``` You can also test the monitoring endpoint, viewing `http://localhost:8222` with a browser. + diff --git a/nats_server/running.md b/nats-server/running/README.md similarity index 77% rename from nats_server/running.md rename to nats-server/running/README.md index e4345dc..b1827b8 100644 --- a/nats_server/running.md +++ b/nats-server/running/README.md @@ -1,14 +1,12 @@ # Running -The nats-server has many command line options. To get started, you don't have to specify anything. -In the absence of any flags, the NATS server will start listening for NATS client connections on port 4222. -By default, security is disabled. +The nats-server has many command line options. To get started, you don't have to specify anything. In the absence of any flags, the NATS server will start listening for NATS client connections on port 4222. By default, security is disabled. -### Standalone +## Standalone When the server starts it will print some information including where the server is listening for client connections: -``` +```text > nats-server [41634] 2019/05/13 09:42:11.745919 [INF] Starting nats-server version 2.0.0 [41634] 2019/05/13 09:42:11.746240 [INF] Listening for client connections on 0.0.0.0:4222 @@ -17,12 +15,11 @@ When the server starts it will print some information including where the server [41634] 2019/05/13 09:42:11.746252 [INF] Server is ready ``` - -### Docker +## Docker If you are running your NATS server in a docker container: -``` +```text > docker run -p 4222:4222 -ti nats:latest [1] 2019/05/13 14:55:11.981434 [INF] Starting nats-server version 2.0.0 ... @@ -33,4 +30,5 @@ If you are running your NATS server in a docker container: ... ``` -More information on [containerized NATS is available here](/nats_docker/README.md). +More information on [containerized NATS is available here](../nats_docker/). + diff --git a/nats_server/windows_srv.md b/nats-server/running/windows_srv.md similarity index 89% rename from nats_server/windows_srv.md rename to nats-server/running/windows_srv.md index a6dd5b6..f575adc 100644 --- a/nats_server/windows_srv.md +++ b/nats-server/running/windows_srv.md @@ -1,15 +1,15 @@ -## Windows Service +# Window Service The NATS server supports running as a Windows service. In fact, this is the recommended way of running NATS on Windows. There is currently no installer; users should use `sc.exe` to install the service: -```batch +```text sc.exe create nats-server binPath= "%NATS_PATH%\nats-server.exe [nats-server flags]" sc.exe start nats-server ``` The above will create and start a `nats-server` service. Note that the nats-server flags should be provided when creating the service. This allows for running multiple NATS server configurations on a single Windows server by using a 1:1 service instance per installed NATS server service. Once the service is running, it can be controlled using `sc.exe` or `nats-server.exe --signal`: -```batch +```text REM Reload server configuration nats-server.exe --signal reload @@ -22,8 +22,9 @@ nats-server.exe --signal stop The above commands will default to controlling the `nats-server` service. If the service is another name, it can be specified: -```batch +```text nats-server.exe --signal stop= ``` -For a complete list of signals, see [process signaling](/nats_admin/signals.md). \ No newline at end of file +For a complete list of signals, see [process signaling](../nats_admin/signals.md). + diff --git a/nats-streaming-concepts/channels/README.md b/nats-streaming-concepts/channels/README.md new file mode 100644 index 0000000..c32ddad --- /dev/null +++ b/nats-streaming-concepts/channels/README.md @@ -0,0 +1,8 @@ +# Channels + +Channels are at the heart of the NATS Streaming Server. Channels are subjects clients send data to and consume from. + +_**Note: NATS Streaming server does not support wildcard for channels, that is, one cannot subscribe on \`foo.**_**`, or`>\`, etc...\*** + +The number of channels can be limited \(and is by default\) through configuration. Messages produced to a channel are stored in a message log inside this channel. + diff --git a/nats-streaming-concepts/channels/message-log.md b/nats-streaming-concepts/channels/message-log.md new file mode 100644 index 0000000..b0b8ffe --- /dev/null +++ b/nats-streaming-concepts/channels/message-log.md @@ -0,0 +1,6 @@ +# Message Log + +You can view a message log as a First In First Out \(FIFO\) queue. Messages are appended to the end of the log. If a limit is set globally for all channels, or specifically for this channel, when the limit is reached, older messages are removed to make room for the new ones. + +But except for the administrative size/age limit set for a message log, messages are not removed due to consumers consuming them. In fact, messages are stored regardless of the presence of subscriptions on that channel. + diff --git a/nats_streaming/channels/subscriptions/subscriptions.md b/nats-streaming-concepts/channels/subscriptions/README.md similarity index 95% rename from nats_streaming/channels/subscriptions/subscriptions.md rename to nats-streaming-concepts/channels/subscriptions/README.md index fce5dc5..e4eb06f 100644 --- a/nats_streaming/channels/subscriptions/subscriptions.md +++ b/nats-streaming-concepts/channels/subscriptions/README.md @@ -1,6 +1,6 @@ # Subscriptions -A client creates a subscription on a given channel. Remember, there is no support for wildcards, so a subscription is really tied to one and only one channel. The server will maintain the subscription state on behalf of the client until the later closes the subscription (or its connection). +A client creates a subscription on a given channel. Remember, there is no support for wildcards, so a subscription is really tied to one and only one channel. The server will maintain the subscription state on behalf of the client until the later closes the subscription \(or its connection\). If there are messages in the log for this channel, messages will be sent to the consumer when the subscription is created. The server will send up to the maximum number of inflight messages as given by the client when creating the subscription. @@ -9,3 +9,4 @@ When receiving ACKs from the consumer, the server will then deliver more message A subscription can be created to start at any point in the message log, either by message sequence, or by time. The following pages describe all the types of subscriptions. + diff --git a/nats_streaming/channels/subscriptions/durable.md b/nats-streaming-concepts/channels/subscriptions/durable.md similarity index 84% rename from nats_streaming/channels/subscriptions/durable.md rename to nats-streaming-concepts/channels/subscriptions/durable.md index b7cb995..bac4d45 100644 --- a/nats_streaming/channels/subscriptions/durable.md +++ b/nats-streaming-concepts/channels/subscriptions/durable.md @@ -2,8 +2,9 @@ If an application wishes to resume message consumption from where it previously stopped, it needs to create a durable subscription. It does so by providing a durable name, which is combined with the client ID provided when the client created its connection. The server then maintains the state for this subscription even after the client connection is closed. -***Note: The starting position given by the client when restarting a durable subscription is ignored.*** +_**Note: The starting position given by the client when restarting a durable subscription is ignored.**_ -When the application wants to stop receiving messages on a durable subscription, it should close - but *not unsubscribe* - this subscription. If a given client library does not have the option to close a subscription, the application should close the connection instead. +When the application wants to stop receiving messages on a durable subscription, it should close - but _not unsubscribe_ - this subscription. If a given client library does not have the option to close a subscription, the application should close the connection instead. When the application wants to delete the subscription, it must unsubscribe it. Once unsubscribed, the state is removed and it is then possible to re-use the durable name, but it will be considered a brand new durable subscription, with the start position being the one given by the client when creating the durable subscription. + diff --git a/nats_streaming/channels/subscriptions/queue-group.md b/nats-streaming-concepts/channels/subscriptions/queue-group.md similarity index 73% rename from nats_streaming/channels/subscriptions/queue-group.md rename to nats-streaming-concepts/channels/subscriptions/queue-group.md index 08b1965..a025108 100644 --- a/nats_streaming/channels/subscriptions/queue-group.md +++ b/nats-streaming-concepts/channels/subscriptions/queue-group.md @@ -1,11 +1,12 @@ -# Queue Group in NATS Streaming +# Queue Group When consumers want to consume from the same channel but each receive a different message, as opposed to all receiving the same messages, they need to create a queue subscription. When a queue group name is specified, the server will send each messages from the log to a single consumer in the group. The distribution of these messages is not specified, therefore applications should not rely on an expected delivery scheme. After the first queue member is created, any other member joining the group will receive messages based on where the server is in the message log for that particular group. That means that the starting position given by joining members is ignored by the server. -When the last member of the group leaves (subscription unsubscribed/closed/or connection closed), the group is removed from the server. The next application creating a subscription with the same name will create a new group, starting at the start position given in the subscription request. +When the last member of the group leaves \(subscription unsubscribed/closed/or connection closed\), the group is removed from the server. The next application creating a subscription with the same name will create a new group, starting at the start position given in the subscription request. A queue subscription can also be durable. For that, the client needs to provide a queue and durable name. The behavior is, as you would expect, a combination of queue and durable subscription. Though unlike a durable subscription, the client ID is not part of the queue group name since the client ID must be unique, and would prevent more than one connection to participate in the queue group. The main difference between a queue subscription and a durable one, is that when the last member leaves the group, the state of the group will be maintained by the server. Later, when a member rejoins the group, the delivery will resume. -***Note: For a durable queue subscription, the last member to * unsubscribe * (not simply close) causes the group to be removed from the server.*** +_**Note: For a durable queue subscription, the last member to**_ **unsubscribe** _**\(not simply close\) causes the group to be removed from the server.**_ + diff --git a/nats_streaming/channels/subscriptions/redelivery.md b/nats-streaming-concepts/channels/subscriptions/redelivery.md similarity index 69% rename from nats_streaming/channels/subscriptions/redelivery.md rename to nats-streaming-concepts/channels/subscriptions/redelivery.md index 0f3ac68..9ab9b9b 100644 --- a/nats_streaming/channels/subscriptions/redelivery.md +++ b/nats-streaming-concepts/channels/subscriptions/redelivery.md @@ -4,8 +4,9 @@ When the server sends a message to a consumer, it expects to receive an ACK from When the server restarts and recovers unacknowledged messages for a subscription, it will first attempt to redeliver those messages before sending new messages. However, if during the initial redelivery some messages don't make it to the client, the server cannot know that and will enable delivery of new messages. -***So it is possible for an application to receive redelivered messages mixed with new messages. This is typically what happens outside of the server restart scenario.*** +_**So it is possible for an application to receive redelivered messages mixed with new messages. This is typically what happens outside of the server restart scenario.**_ -For queue subscriptions, if a member has unacknowledged messages, when this member's `AckWait` (which is the duration given to the server before the server should attempt to redeliver unacknowledged messages) time elapses, the messages are redelivered to any other member in the group (including itself). +For queue subscriptions, if a member has unacknowledged messages, when this member's `AckWait` \(which is the duration given to the server before the server should attempt to redeliver unacknowledged messages\) time elapses, the messages are redelivered to any other member in the group \(including itself\). If a queue member leaves the group, its unacknowledged messages are redistributed to other queue members. + diff --git a/nats-streaming-concepts/channels/subscriptions/regular.md b/nats-streaming-concepts/channels/subscriptions/regular.md new file mode 100644 index 0000000..4b96aa0 --- /dev/null +++ b/nats-streaming-concepts/channels/subscriptions/regular.md @@ -0,0 +1,4 @@ +# Regular + +The state of these subscriptions is removed when they are unsubscribed or closed \(which is equivalent for this type of subscription\) or the client connection is closed \(explicitly by the client, or closed by the server due to timeout\). They do, however, survive a _server_ failure \(if running with a persistent store\). + diff --git a/nats_streaming/client-connections.md b/nats-streaming-concepts/client-connections.md similarity index 99% rename from nats_streaming/client-connections.md rename to nats-streaming-concepts/client-connections.md index 3d03fa6..5b7a092 100644 --- a/nats_streaming/client-connections.md +++ b/nats-streaming-concepts/client-connections.md @@ -5,3 +5,4 @@ As described, clients are not directly connected to the streaming server. Instea This client ID links a given connection to its published messages, subscriptions, especially durable subscriptions. Indeed, durable subscriptions are stored as a combination of the client ID and durable name. More on durable subscriptions later. It is also used to resolve the issue of not having direct client connections to the server. For instance, say that a client crashes without closing the connection. It later restarts with the same client ID. The server will detect that this client ID is already in-use. It will try to contact that known client to its original private inbox. If the server does not receive a response - which would be the case if the client crashed - it will replace the old client with this new one. Otherwise, the server would reject the connection request since the client ID is already in-use. + diff --git a/nats_streaming/clustering/clustering.md b/nats-streaming-concepts/clustering/README.md similarity index 77% rename from nats_streaming/clustering/clustering.md rename to nats-streaming-concepts/clustering/README.md index 4125f77..0cb79c9 100644 --- a/nats_streaming/clustering/clustering.md +++ b/nats-streaming-concepts/clustering/README.md @@ -2,8 +2,9 @@ NATS Streaming Server supports clustering and data replication, implemented with the [Raft consensus algorithm](https://raft.github.io/), for the purposes of high availability. -There are two ways to bootstrap a cluster: with an explicit cluster configuration or with "auto" configuration using a seed node. With the first, we provide the IDs of the nodes participating in the cluster. In this case, the participating nodes will elect a leader. With the second, we start one server as a seed node, which will elect itself as leader, and subsequent servers will automatically join the seed (note that this also works with the explicit cluster configuration once the leader has been established). With the second method, we need to be careful to avoid starting multiple servers as seed as this will result in a split-brain. Both of these configuration methods are shown in the sections below. +There are two ways to bootstrap a cluster: with an explicit cluster configuration or with "auto" configuration using a seed node. With the first, we provide the IDs of the nodes participating in the cluster. In this case, the participating nodes will elect a leader. With the second, we start one server as a seed node, which will elect itself as leader, and subsequent servers will automatically join the seed \(note that this also works with the explicit cluster configuration once the leader has been established\). With the second method, we need to be careful to avoid starting multiple servers as seed as this will result in a split-brain. Both of these configuration methods are shown in the sections below. It is recommended to run an odd number of servers in a cluster with a minimum of three servers to avoid split-brain scenarios. Note that if less than a majority of servers are available, the cluster cannot make progress, e.g. if two nodes go down in a cluster of three, the cluster is unavailable until at least one node comes back. -Note about Channels Partitioning and Clustering. These two features are mutually exclusive. Trying to start a server with channels Partitioning and Clustering enabled will result in a startup error. Clustering requires all channels to be replicated in the cluster. \ No newline at end of file +Note about Channels Partitioning and Clustering. These two features are mutually exclusive. Trying to start a server with channels Partitioning and Clustering enabled will result in a startup error. Clustering requires all channels to be replicated in the cluster. + diff --git a/nats_streaming/clustering/auto-configuration.md b/nats-streaming-concepts/clustering/auto-configuration.md similarity index 99% rename from nats_streaming/clustering/auto-configuration.md rename to nats-streaming-concepts/clustering/auto-configuration.md index 76361f2..e392275 100644 --- a/nats_streaming/clustering/auto-configuration.md +++ b/nats-streaming-concepts/clustering/auto-configuration.md @@ -4,7 +4,7 @@ We can also bootstrap a NATS Streaming cluster by starting **one server** as the Here is an example of starting three servers in a cluster by starting one as the seed and letting the others automatically join: -``` +```text nats-streaming-server -store file -dir store-a -clustered -cluster_bootstrap -nats_server nats://localhost:4222 nats-streaming-server -store file -dir store-b -clustered -nats_server nats://localhost:4222 @@ -15,3 +15,4 @@ nats-streaming-server -store file -dir store-c -clustered -nats_server nats://lo For a given cluster ID, if more than one server is started with `cluster_bootstrap` set to true, each server with this parameter will report the misconfiguration and exit. The very first server that bootstrapped the cluster can be restarted, however, the operator **must remove the datastores** of the other servers that were incorrectly started with the bootstrap parameter before attempting to restart them. If they are restarted with existing state, even without the `-cluster_bootstrap` parameter, they will once again start as a leader. + diff --git a/nats_streaming/clustering/configuration.md b/nats-streaming-concepts/clustering/configuration.md similarity index 86% rename from nats_streaming/clustering/configuration.md rename to nats-streaming-concepts/clustering/configuration.md index 994012d..c35ecb2 100644 --- a/nats_streaming/clustering/configuration.md +++ b/nats-streaming-concepts/clustering/configuration.md @@ -4,7 +4,7 @@ We can bootstrap a NATS Streaming cluster by providing the cluster topology usin Here is an example of starting three servers in a cluster. For this example, we run a separate NATS server which the Streaming servers connect to. -``` +```text nats-streaming-server -store file -dir store-a -clustered -cluster_node_id a -cluster_peers b,c -nats_server nats://localhost:4222 nats-streaming-server -store file -dir store-b -clustered -cluster_node_id b -cluster_peers a,c -nats_server nats://localhost:4222 @@ -14,19 +14,19 @@ nats-streaming-server -store file -dir store-c -clustered -cluster_node_id c -cl Note that once a leader is elected, subsequent servers can be started without providing the cluster configuration. They will automatically join the cluster. Similarly, the cluster node ID does not need to be provided as one will be automatically assigned. As long as the file store is used, this ID will be recovered on restart. -``` +```text nats-streaming-server -store file -dir store-d -clustered -nats_server nats://localhost:4222 ``` -The equivalent clustering configurations can be specified in a configuration file under the `cluster` group. See the [Configuring](../configuring/configuring.md) section for more information. +The equivalent clustering configurations can be specified in a configuration file under the `cluster` group. See the [Configuring](../../nats-streaming-server/configuring/) section for more information. -Here is an example of a cluster of 3 nodes using the following configuration files. The nodes are running on `host1`, `host2` and `host3` respectively. -**NOTE** If you have an existing NATS cluster and want to run NATS Streaming Cluster on top of that, see details at the end of this section. +Here is an example of a cluster of 3 nodes using the following configuration files. The nodes are running on `host1`, `host2` and `host3` respectively. **NOTE** If you have an existing NATS cluster and want to run NATS Streaming Cluster on top of that, see details at the end of this section. On `host1`, this configuration indicates that the server will accept client connections on port 4222. It will accept route connections on port 6222. It creates 2 routes, to `host2` and `host3` cluster port. -It defines the NATS Streaming cluster name as `mycluster`, uses a store file that points to the `store` directory. The `cluster` section inside `streaming` makes the NATS Streaming server run in cluster mode. This configuration explicitly define each node id (`a` for `host1`) and list its peers. -``` +It defines the NATS Streaming cluster name as `mycluster`, uses a store file that points to the `store` directory. The `cluster` section inside `streaming` makes the NATS Streaming server run in cluster mode. This configuration explicitly define each node id \(`a` for `host1`\) and list its peers. + +```text # NATS specific configuration port: 4222 cluster { @@ -48,8 +48,9 @@ streaming { Below is the configuration for the server running on `host2`. Notice how the routes are now to `host1` and `host3`. The other thing that changed is the node id that is set to `b` and peers are updated accordingly to `a` and `c`. -Note that the `dir` configuration is also `store` but these are local directories and do not (actually must not) be shared. Each node will have its own copy of the datastore. You could have each configuration have a different value for `dir` if desired. -``` +Note that the `dir` configuration is also `store` but these are local directories and do not \(actually must not\) be shared. Each node will have its own copy of the datastore. You could have each configuration have a different value for `dir` if desired. + +```text # NATS specific configuration port: 4222 cluster { @@ -69,9 +70,9 @@ streaming { } ``` -As you would expect, for `host3`, the routes are now to `host1` and `host2` and the node id is `c` while its peers -are `a` and `b`. -``` +As you would expect, for `host3`, the routes are now to `host1` and `host2` and the node id is `c` while its peers are `a` and `b`. + +```text # NATS specific configuration port: 4222 cluster { @@ -92,3 +93,4 @@ streaming { ``` In the example above, the configuration assumes no existing NATS Cluster and therefore configure the NATS routes between each node. Should you want to use an existing NATS cluster, do not include the "NATS specific configuration" section, instead, add `nats_server_url` in the `streaming` section to point to the NATS server you want. + diff --git a/nats_streaming/clustering/containers.md b/nats-streaming-concepts/clustering/containers.md similarity index 61% rename from nats_streaming/clustering/containers.md rename to nats-streaming-concepts/clustering/containers.md index 71cf971..7a7246b 100644 --- a/nats_streaming/clustering/containers.md +++ b/nats-streaming-concepts/clustering/containers.md @@ -1,9 +1,12 @@ # Containers When running the docker image of NATS Streaming Server, you will want to specify a mounted volume so that the data can be recovered. Your `-dir` parameter then points to a directory inside that mounted volume. However, after a restart you may get a failure with a message similar to this: -``` + +```text [FTL] STREAM: Failed to start: streaming state was recovered but cluster log path "mycluster/a" is empty ``` -This is because the server recovered the streaming state (as pointed by `-dir` and located in the mounted volume), but did not recover the RAFT specific state that is by default stored in a directory named after your cluster id, relative to the current directory starting the executable. In the context of a container, this data will be lost after the container is stopped. + +This is because the server recovered the streaming state \(as pointed by `-dir` and located in the mounted volume\), but did not recover the RAFT specific state that is by default stored in a directory named after your cluster id, relative to the current directory starting the executable. In the context of a container, this data will be lost after the container is stopped. In order to avoid this issue, you need to specify the `-cluster_log_path` and ensure that it points to the mounted volume so that the RAFT state can be recovered along with the Streaming state. + diff --git a/nats_streaming/clustering/supported-stores.md b/nats-streaming-concepts/clustering/supported-stores.md similarity index 99% rename from nats_streaming/clustering/supported-stores.md rename to nats-streaming-concepts/clustering/supported-stores.md index 7c0322e..88eaef6 100644 --- a/nats_streaming/clustering/supported-stores.md +++ b/nats-streaming-concepts/clustering/supported-stores.md @@ -7,3 +7,4 @@ The NATS Streaming stores server meta information, messages and subscriptions to However, in clustered mode, we use RAFT for leader election. The raft layer uses its own stores which are currently necessarily file based. The location of the RAFT stores defaults to the current directory under a sub-directory named after the cluster ID, or you can configure it using `--cluster_log_path`. This means that even if you select a SQL Store, there will still be a need for storing data on the file system. + diff --git a/nats_streaming/fault-tolerance/ft.md b/nats-streaming-concepts/ft/README.md similarity index 72% rename from nats_streaming/fault-tolerance/ft.md rename to nats-streaming-concepts/ft/README.md index 34bc078..64a6e6f 100644 --- a/nats_streaming/fault-tolerance/ft.md +++ b/nats-streaming-concepts/ft/README.md @@ -1,15 +1,16 @@ # Fault Tolerance -To minimize the single point of failure, NATS Streaming server can be run in Fault Tolerance mode. It works by having a group of servers with one acting as the active server (accessing the store) and handling all communication with clients, and all others acting as standby servers. +To minimize the single point of failure, NATS Streaming server can be run in Fault Tolerance mode. It works by having a group of servers with one acting as the active server \(accessing the store\) and handling all communication with clients, and all others acting as standby servers. It is important to note that is not possible to run Nats Streaming as Fault Tolerance mode and Clustering mode at the same time. -To start a server in Fault Tolerance (FT) mode, you specify an FT group name. +To start a server in Fault Tolerance \(FT\) mode, you specify an FT group name. Here is an example on how starting 2 servers in FT mode running on the same host and embedding the NATS servers: -``` +```text nats-streaming-server -store file -dir datastore -ft_group "ft" -cluster nats://localhost:6222 -routes nats://localhost:6223 -p 4222 nats-streaming-server -store file -dir datastore -ft_group "ft" -cluster nats://localhost:6223 -routes nats://localhost:6222 -p 4223 ``` + diff --git a/nats_streaming/fault-tolerance/active-server.md b/nats-streaming-concepts/ft/active-server.md similarity index 88% rename from nats_streaming/fault-tolerance/active-server.md rename to nats-streaming-concepts/ft/active-server.md index 6ae7b8d..2ea0013 100644 --- a/nats_streaming/fault-tolerance/active-server.md +++ b/nats-streaming-concepts/ft/active-server.md @@ -4,4 +4,5 @@ There is a single Active server in the group. This server was the first to obtai If the elected server fails to grab this lock because it is already locked, it will go back to standby. -***Only the active server accesses the store and service all clients.*** +_**Only the active server accesses the store and service all clients.**_ + diff --git a/nats_streaming/fault-tolerance/failover.md b/nats-streaming-concepts/ft/failover.md similarity index 99% rename from nats_streaming/fault-tolerance/failover.md rename to nats-streaming-concepts/ft/failover.md index c1dce65..b6fceec 100644 --- a/nats_streaming/fault-tolerance/failover.md +++ b/nats-streaming-concepts/ft/failover.md @@ -7,3 +7,4 @@ The first server that succeeds will become active and go through the process of All other servers that failed to get the store lock will go back to standby mode and stay in this mode until they stop receiving heartbeats from the current active server. It is possible that a standby trying to activate is not able to immediately acquire the store lock. When that happens, it goes back into standby mode, but if it fails to receive heartbeats from an active server, it will try again to acquire the store lock. The interval is random but as of now set to a bit more than a second. + diff --git a/nats_streaming/fault-tolerance/shared-state.md b/nats-streaming-concepts/ft/shared-state.md similarity index 79% rename from nats_streaming/fault-tolerance/shared-state.md rename to nats-streaming-concepts/ft/shared-state.md index 0c6f987..e502aaf 100644 --- a/nats_streaming/fault-tolerance/shared-state.md +++ b/nats-streaming-concepts/ft/shared-state.md @@ -1,3 +1,4 @@ # Shared State -Actual file replication to multiple disks is not handled by the Streaming server. This - if required - needs to be handled by the user. For the FileStore implementation that we currently provide, the data store needs to be mounted by all servers in the FT group (e.g. an NFS Mount, Gluster in Google Cloud or EFS in Amazon). +Actual file replication to multiple disks is not handled by the Streaming server. This - if required - needs to be handled by the user. For the FileStore implementation that we currently provide, the data store needs to be mounted by all servers in the FT group \(e.g. an NFS Mount, Gluster in Google Cloud or EFS in Amazon\). + diff --git a/nats_streaming/fault-tolerance/standby-server.md b/nats-streaming-concepts/ft/standby-server.md similarity index 92% rename from nats_streaming/fault-tolerance/standby-server.md rename to nats-streaming-concepts/ft/standby-server.md index 79e64f3..cefc31b 100644 --- a/nats_streaming/fault-tolerance/standby-server.md +++ b/nats-streaming-concepts/ft/standby-server.md @@ -1,3 +1,4 @@ -# Standby servers +# Standby Servers There can be as many standby servers as you want in the same group. These servers do not access the store and do not receive any data from the streaming clients. They are just running waiting for the detection of the active server failure. + diff --git a/nats_streaming/intro.md b/nats-streaming-concepts/intro.md similarity index 53% rename from nats_streaming/intro.md rename to nats-streaming-concepts/intro.md index f549587..c770310 100644 --- a/nats_streaming/intro.md +++ b/nats-streaming-concepts/intro.md @@ -1,31 +1,31 @@ -# NATS Streaming Concepts +# Introduction NATS Streaming is a data streaming system powered by NATS, and written in the Go programming language. The executable name for the NATS Streaming server is `nats-streaming-server`. NATS Streaming embeds, extends, and interoperates seamlessly with the core NATS platform. The [NATS Streaming server](https://github.com/nats-io/nats-streaming-server) is provided as open source software under the Apache-2.0 license. Synadia actively maintains and supports the NATS Streaming server. -![](/assets/images/nats_streaming.svg) +![](../.gitbook/assets/nats_streaming.svg) ## Features In addition to the features of the core NATS platform, NATS Streaming provides the following: -- **Enhanced message protocol** - NATS Streaming implements its own enhanced message format using [Google Protocol Buffers](https://developers.google.com/protocol-buffers/). These messages are transmitted as binary message payloads via core NATS platform, and thus require no changes to the basic NATS protocol. -- **Message/event persistence** - NATS Streaming offers configurable message persistence: in-memory, flat files or database. The storage subsystem uses a public interface that allows contributors to develop their own custom implementations. -- **At-least-once-delivery** - NATS Streaming offers message acknowledgements between publisher and server (for publish operations) and between subscriber and server (to confirm message delivery). Messages are persisted by the server in memory or secondary storage (or other external storage) and will be redelivered to eligible subscribing clients as needed. -- **Publisher rate limiting** - NATS Streaming provides a connection option called `MaxPubAcksInFlight` that effectively limits the number of unacknowledged messages that a publisher may have in-flight at any given time. When this maximum is reached, further async publish calls will block until the number of unacknowledged messages falls below the specified limit. -- **Rate matching/limiting per subscriber** - Subscriptions may specify a `MaxInFlight` option that designates the maximum number of outstanding acknowledgements (messages that have been delivered but not acknowledged) that NATS Streaming will allow for a given subscription. When this limit is reached, NATS Streaming will suspend delivery of messages to this subscription until the number of unacknowledged messages falls below the specified limit. -- **Historical message replay by subject** - New subscriptions may specify a start position in the stream of messages stored for the subscribed subject's channel. By using this option, message delivery may begin at: - - The earliest message stored for this subject - - The most recently stored message for this subject, prior to the start of the current subscription. This is commonly thought of as "last value" or "initial value" caching. - - A specific date/time in nanoseconds - - An historical offset from the current server date/time, e.g. the last 30 seconds. - - A specific message sequence number -- **Durable subscriptions** - Subscriptions may also specify a "durable name" which will survive client restarts. Durable subscriptions cause the server to track the last acknowledged message sequence number for a client and durable name. When the client restarts/resubscribes, and uses the same client ID and durable name, the server will resume delivery beginning with the earliest unacknowledged message for this durable subscription. - +* **Enhanced message protocol** - NATS Streaming implements its own enhanced message format using [Google Protocol Buffers](https://developers.google.com/protocol-buffers/). These messages are transmitted as binary message payloads via core NATS platform, and thus require no changes to the basic NATS protocol. +* **Message/event persistence** - NATS Streaming offers configurable message persistence: in-memory, flat files or database. The storage subsystem uses a public interface that allows contributors to develop their own custom implementations. +* **At-least-once-delivery** - NATS Streaming offers message acknowledgements between publisher and server \(for publish operations\) and between subscriber and server \(to confirm message delivery\). Messages are persisted by the server in memory or secondary storage \(or other external storage\) and will be redelivered to eligible subscribing clients as needed. +* **Publisher rate limiting** - NATS Streaming provides a connection option called `MaxPubAcksInFlight` that effectively limits the number of unacknowledged messages that a publisher may have in-flight at any given time. When this maximum is reached, further async publish calls will block until the number of unacknowledged messages falls below the specified limit. +* **Rate matching/limiting per subscriber** - Subscriptions may specify a `MaxInFlight` option that designates the maximum number of outstanding acknowledgements \(messages that have been delivered but not acknowledged\) that NATS Streaming will allow for a given subscription. When this limit is reached, NATS Streaming will suspend delivery of messages to this subscription until the number of unacknowledged messages falls below the specified limit. +* **Historical message replay by subject** - New subscriptions may specify a start position in the stream of messages stored for the subscribed subject's channel. By using this option, message delivery may begin at: + * The earliest message stored for this subject + * The most recently stored message for this subject, prior to the start of the current subscription. This is commonly thought of as "last value" or "initial value" caching. + * A specific date/time in nanoseconds + * An historical offset from the current server date/time, e.g. the last 30 seconds. + * A specific message sequence number +* **Durable subscriptions** - Subscriptions may also specify a "durable name" which will survive client restarts. Durable subscriptions cause the server to track the last acknowledged message sequence number for a client and durable name. When the client restarts/resubscribes, and uses the same client ID and durable name, the server will resume delivery beginning with the earliest unacknowledged message for this durable subscription. ## Installation -NATS provides a [server binary](gettingstarted/install.md) for Linux, Mac, and Windows. You can install the server from source on any platform you choose. +NATS provides a [server binary](../nats-streaming-server/install.md) for Linux, Mac, and Windows. You can install the server from source on any platform you choose. ## Usage, Configuration and Administration -NATS Streaming provides a rich set of commands and parameters to configure all aspects of the server. Please refer to the [Configuring](configuring/configuring.md) for further information on usage, configuration, and administration. +NATS Streaming provides a rich set of commands and parameters to configure all aspects of the server. Please refer to the [Configuring](../nats-streaming-server/configuring/) for further information on usage, configuration, and administration. + diff --git a/nats_streaming/monitoring/monitoring.md b/nats-streaming-concepts/monitoring/README.md similarity index 86% rename from nats_streaming/monitoring/monitoring.md rename to nats-streaming-concepts/monitoring/README.md index 7e443a4..4584b7d 100644 --- a/nats_streaming/monitoring/monitoring.md +++ b/nats-streaming-concepts/monitoring/README.md @@ -1,23 +1,26 @@ -## Monitoring NATS Streaming +# Monitoring To monitor the NATS Streaming system, a lightweight HTTP server is used on a dedicated monitoring port. The monitoring server provides several endpoints, all returning a JSON object. -### Enabling from the command line +## Enabling from the command line -To enable the monitoring server, start the NATS Streaming Server with the monitoring flag -m (or -ms) and specify the monitoring port. +To enable the monitoring server, start the NATS Streaming Server with the monitoring flag -m \(or -ms\) and specify the monitoring port. Monitoring options -``` + +```text -m, --http_port PORT HTTP PORT for monitoring -ms,--https_port PORT Use HTTPS PORT for monitoring (requires TLS cert and key) ``` + To enable monitoring via the configuration file, use `http: "host:port"` or `https: "host:port"`. There is no explicit configuration flag for the monitoring interface. For example, after running this: -``` +```text nats-streaming-server -m 8222 ``` + you should see that the NATS Streaming server starts with the HTTP monitoring port enabled: ```bash @@ -30,13 +33,14 @@ you should see that the NATS Streaming server starts with the HTTP monitoring po [19339] 2019/06/24 15:02:38.252248 [INF] Listening for client connections on 0.0.0.0:4222 (...) ``` -You can then point your browser (or curl) to [http://localhost:8222/streaming](http://localhost:8222/streaming) -### Enabling from the configuration file +You can then point your browser \(or curl\) to [http://localhost:8222/streaming](http://localhost:8222/streaming) + +## Enabling from the configuration file To start via the configuration file you can define the monitoring port as follows: -```conf +```text http_port = 8222 ``` diff --git a/nats_streaming/monitoring/endpoints.md b/nats-streaming-concepts/monitoring/endpoints.md similarity index 91% rename from nats_streaming/monitoring/endpoints.md rename to nats-streaming-concepts/monitoring/endpoints.md index fdd042a..07a35f1 100644 --- a/nats_streaming/monitoring/endpoints.md +++ b/nats-streaming-concepts/monitoring/endpoints.md @@ -1,11 +1,12 @@ -### Endpoints +# Endpoints The following sections describe each supported monitoring endpoint: serverz, storez, clientsz, and channelsz. -#### /serverz +## /serverz The endpoint [http://localhost:8222/streaming/serverz](http://localhost:8222/streaming/serverz) reports various general statistics. -``` + +```text { "cluster_id": "test-cluster", "server_id": "JEzjfVQS4JIEzM7lZmWHm9", @@ -24,7 +25,8 @@ The endpoint [http://localhost:8222/streaming/serverz](http://localhost:8222/str ``` In clustering mode, there is an additional field that indicates the RAFT role of the given node. Here is an example: -``` + +```text { "cluster_id": "test-cluster", "server_id": "t9W9zbOIIi5Y9Guppxl0lF", @@ -42,12 +44,14 @@ In clustering mode, there is an additional field that indicates the RAFT role of "total_bytes": 0 } ``` + The possible values are: `Leader`, `Follower` or `Candidate`. -#### /storez +## /storez The endpoint [http://localhost:8222/streaming/storez](http://localhost:8222/streaming/storez) reports information about the store. -``` + +```text { "cluster_id": "test-cluster", "server_id": "8AjZq57k4JY7cfKEvuZ8iF", @@ -66,14 +70,15 @@ The endpoint [http://localhost:8222/streaming/storez](http://localhost:8222/stre } ``` -#### /clientsz +## /clientsz The endpoint [http://localhost:8222/streaming/clientsz](http://localhost:8222/streaming/clientsz) reports more detailed information about the connected clients. It uses a paging mechanism which defaults to 1024 clients. -You can control these via URL arguments (limit and offset). For example: [http://localhost:8222/streaming/clientsz?limit=1&offset=1](http://localhost:8222/streaming/clientsz?limit=1&offset=1). -``` +You can control these via URL arguments \(limit and offset\). For example: [http://localhost:8222/streaming/clientsz?limit=1&offset=1](http://localhost:8222/streaming/clientsz?limit=1&offset=1). + +```text { "cluster_id": "test-cluster", "server_id": "J3Odi0wXYKWKFWz5D5uhH9", @@ -90,8 +95,10 @@ You can control these via URL arguments (limit and offset). For example: [http:/ ] } ``` + You can also report detailed subscription information on a per client basis using `subs=1`. For example: [http://localhost:8222/streaming/clientsz?limit=1&offset=1&subs=1](http://localhost:8222/streaming/clientsz?limit=1&offset=1&subs=1). -``` + +```text { "cluster_id": "test-cluster", "server_id": "J3Odi0wXYKWKFWz5D5uhH9", @@ -124,8 +131,10 @@ You can also report detailed subscription information on a per client basis usin ] } ``` + You can select a specific client based on its client ID with `client=`, and get also get detailed statistics with `subs=1`. For example: [http://localhost:8222/streaming/clientsz?client=me&subs=1](http://localhost:8222/streaming/clientsz?client=me&subs=1). -``` + +```text { "id": "me", "hb_inbox": "_INBOX.HG0uDuNtAPxJQ1lVjIC2sr", @@ -148,10 +157,11 @@ You can select a specific client based on its client ID with `client=`, and } ``` -#### /channelsz +## /channelsz The endpoint [http://localhost:8222/streaming/channelsz](http://localhost:8222/streaming/channelsz) reports the list of channels. -``` + +```text { "cluster_id": "test-cluster", "server_id": "J3Odi0wXYKWKFWz5D5uhH9", @@ -166,10 +176,12 @@ The endpoint [http://localhost:8222/streaming/channelsz](http://localhost:8222/s ] } ``` + It uses a paging mechanism which defaults to 1024 channels. -You can control these via URL arguments (limit and offset). For example: [http://localhost:8222/streaming/channelsz?limit=1&offset=1](http://localhost:8222/streaming/channelsz?limit=1&offset=1). -``` +You can control these via URL arguments \(limit and offset\). For example: [http://localhost:8222/streaming/channelsz?limit=1&offset=1](http://localhost:8222/streaming/channelsz?limit=1&offset=1). + +```text { "cluster_id": "test-cluster", "server_id": "J3Odi0wXYKWKFWz5D5uhH9", @@ -183,8 +195,10 @@ You can control these via URL arguments (limit and offset). For example: [http:/ ] } ``` + You can also get the list of subscriptions with `subs=1`. For example: [http://localhost:8222/streaming/channelsz?limit=1&offset=0&subs=1](http://localhost:8222/streaming/channelsz?limit=1&offset=0&subs=1). -``` + +```text { "cluster_id": "test-cluster", "server_id": "J3Odi0wXYKWKFWz5D5uhH9", @@ -218,8 +232,10 @@ You can also get the list of subscriptions with `subs=1`. For example: [http://l ] } ``` + You can select a specific channel based on its name with `channel=name`. For example: [http://localhost:8222/streaming/channelsz?channel=foo](http://localhost:8222/streaming/channelsz?channel=foo). -``` + +```text { "name": "foo", "msgs": 649234, @@ -228,8 +244,10 @@ You can select a specific channel based on its name with `channel=name`. For exa "last_seq": 649234 } ``` + And again, you can get detailed subscriptions with `subs=1`. For example: [http://localhost:8222/streaming/channelsz?channel=foo&subs=1](http://localhost:8222/streaming/channelsz?channel=foo&subs=1). -``` + +```text { "name": "foo", "msgs": 704770, @@ -267,7 +285,8 @@ And again, you can get detailed subscriptions with `subs=1`. For example: [http: ``` For durables that are currently running, the `is_offline` field is set to `false`. Here is an example: -``` + +```text { "name": "foo", "msgs": 0, @@ -292,8 +311,9 @@ For durables that are currently running, the `is_offline` field is set to `false } ``` -When that same durable goes offline, `is_offline` is be set to `true`. Although the client is possibly no longer connected (and would not appear in the `clientsz` endpoint), the `client_id` field is still displayed here. -``` +When that same durable goes offline, `is_offline` is be set to `true`. Although the client is possibly no longer connected \(and would not appear in the `clientsz` endpoint\), the `client_id` field is still displayed here. + +```text { "name": "foo", "msgs": 0, @@ -317,3 +337,4 @@ When that same durable goes offline, `is_offline` is be set to `true`. Although ] } ``` + diff --git a/nats_streaming/partitioning.md b/nats-streaming-concepts/partitioning.md similarity index 79% rename from nats_streaming/partitioning.md rename to nats-streaming-concepts/partitioning.md index db4676b..01729f8 100644 --- a/nats_streaming/partitioning.md +++ b/nats-streaming-concepts/partitioning.md @@ -1,6 +1,6 @@ # Partitioning -***Note, this feature is incompatible with Clustering mode. Trying to start a server with Partitioning and Clustering enabled will result in a startup error.*** +_**Note, this feature is incompatible with Clustering mode. Trying to start a server with Partitioning and Clustering enabled will result in a startup error.**_ It is possible to limit the list of channels a server can handle. This can be used to: @@ -13,7 +13,7 @@ Channels don't need to override any limit, but they need to be specified for the Here is an example: -``` +```text partitioning: true store_limits: { channels: { @@ -26,14 +26,15 @@ store_limits: { } ``` -When partitioning is enabled, multiple servers with the same cluster ID can coexist on the same NATS network, each server handling its own set of channels. ***Note however that in this mode, state is not replicated as it is in Clustering mode. The only communication between servers is to report if a given channel is handled in more than one server.*** +When partitioning is enabled, multiple servers with the same cluster ID can coexist on the same NATS network, each server handling its own set of channels. _**Note however that in this mode, state is not replicated as it is in Clustering mode. The only communication between servers is to report if a given channel is handled in more than one server.**_ ## Wildcards -NATS Streaming does not support sending or subscribing to wildcard channels (such as `foo.*`). +NATS Streaming does not support sending or subscribing to wildcard channels \(such as `foo.*`\). However, it is possible to use wildcards to define the partition that a server can handle. For instance, with the following configuration: -``` + +```text partitioning: true store_limits: { channels: { @@ -42,11 +43,8 @@ store_limits: { } } ``` -The streaming server would accept subscriptions or published messages to channels such as: -1. `foo.bar` -2. `bar.baz` -3. `bar.baz.bat` -4. ... + +The streaming server would accept subscriptions or published messages to channels such as: 1. `foo.bar` 2. `bar.baz` 3. `bar.baz.bat` 4. ... But would ignore messages or subscriptions on: @@ -60,9 +58,9 @@ But would ignore messages or subscriptions on: When a server starts, it sends its list of channels to all other servers on the same cluster in an attempt to detect duplicate channels. When a server receives this list and finds that it has a channel in common, it will return an error to the emitting server, which will then fail to start. -However, on startup, it is possible that the underlying NATS cluster is not fully formed. The server would not get any response from the rest of the cluster and therefore start successfully and service clients. Anytime a Streaming server detects that a NATS server was added to the NATS cluster, it will resend its list of channels. It means that currently running servers may suddenly fail with a message regarding duplicate channels. Having the same channel on different servers means that a subscription would be created on all servers handling the channel, but only one server will receive and process message acknowledgements. Other servers would then redeliver messages (since they would not get the acknowledgements), which would cause duplicates. +However, on startup, it is possible that the underlying NATS cluster is not fully formed. The server would not get any response from the rest of the cluster and therefore start successfully and service clients. Anytime a Streaming server detects that a NATS server was added to the NATS cluster, it will resend its list of channels. It means that currently running servers may suddenly fail with a message regarding duplicate channels. Having the same channel on different servers means that a subscription would be created on all servers handling the channel, but only one server will receive and process message acknowledgements. Other servers would then redeliver messages \(since they would not get the acknowledgements\), which would cause duplicates. -***In order to avoid issues with channels existing on several servers, it is ultimately the responsibility of the administrator to ensure that channels are unique.*** +_**In order to avoid issues with channels existing on several servers, it is ultimately the responsibility of the administrator to ensure that channels are unique.**_ ## Fault Tolerance and Partitioning @@ -71,7 +69,8 @@ You can easily combine the Fault Tolerance and Partitioning feature. To illustrate, suppose that we want two partitions, one for `foo.>` and one for `bar.>`. The configuration for the first server `foo.conf` would look like: -``` + +```text partitioning: true store_limits: { channels: { @@ -81,7 +80,8 @@ store_limits: { ``` The second configuration `bar.conf` would be: -``` + +```text partitioning: true store_limits: { channels: { @@ -90,30 +90,35 @@ store_limits: { } ``` -If you remember, Fault Tolerance is configured by specifying a name (`ft_group_name`). Suppose there is an NFS mount called `/nss/datastore` on both `host1` and `host2`. +If you remember, Fault Tolerance is configured by specifying a name \(`ft_group_name`\). Suppose there is an NFS mount called `/nss/datastore` on both `host1` and `host2`. Starting an FT pair for the partition `foo` could look like this: -``` + +```text host1$ nats-streaming-server -store file -dir /nss/datastore/foodata -sc foo.conf -ft_group_name foo -cluster nats://host1:6222 -routes nats://host2:6222,nats://host2:6223 host2$ nats-streaming-server -store file -dir /nss/datastore/foodata -sc foo.conf -ft_group_name foo -cluster nats://host2:6222 -routes nats://host1:6222,nats://host1:6223 ``` -Notice that each server on each node points to each other (the `-routes` parameter). The reason why we also point to `6223` will be explained later. They both listen for routes connections on their host's `6222` port. -We now start the FT pair for `bar`. Since we are running from the same machines (we don't have to), we need to use a different port: -``` +Notice that each server on each node points to each other \(the `-routes` parameter\). The reason why we also point to `6223` will be explained later. They both listen for routes connections on their host's `6222` port. + +We now start the FT pair for `bar`. Since we are running from the same machines \(we don't have to\), we need to use a different port: + +```text host1$ nats-streaming-server -store file -dir /nss/datastore/bardata -sc bar.conf -ft_group_name bar -p 4223 -cluster nats://host1:6223 -routes nats://host2:6222,nats://host2:6223 host2$ nats-streaming-server -store file -dir /nss/datastore/bardata -sc bar.conf -ft_group_name bar -p 4223 -cluster nats://host2:6223 -routes nats://host1:6222,nats://host1:6223 ``` + You will notice that the `-routes` parameter points to both `6222` and `6223`, this is so that both partitions belong to the same cluster and be viewed as "one" by a Streaming application connecting to this cluster. Effectively, we have created a full mesh of 4 NATS servers that can all communicate with each other. Two of these servers are backups for servers running on the same FT group. ## Applications behavior -When an application connects, it specifies a cluster ID. If several servers are running with that same cluster ID, the application will be able to publish/subscribe to any channel handled by the cluster (as long as those servers are all connected to the NATS network). +When an application connects, it specifies a cluster ID. If several servers are running with that same cluster ID, the application will be able to publish/subscribe to any channel handled by the cluster \(as long as those servers are all connected to the NATS network\). A published message will be received by only the server that has that channel defined. If no server is handling this channel, no specific error is returned, instead the publish call will timeout. Same goes for message acknowledgements. Only the server handling the subscription on this channel should receive those. -However, other client requests (such as connection and subscription requests) are received by all servers. For connections, all servers handle them and the client library will receive a response from all servers in the cluster, but will use the first one that it received. +However, other client requests \(such as connection and subscription requests\) are received by all servers. For connections, all servers handle them and the client library will receive a response from all servers in the cluster, but will use the first one that it received. For subscriptions, a server receiving the request for a channel that it does not handle will simply ignore the request. Again, if no server handles this channel, the client's subscription request will simply time out. + diff --git a/nats_streaming/relation-to-nats.md b/nats-streaming-concepts/relation-to-nats.md similarity index 85% rename from nats_streaming/relation-to-nats.md rename to nats-streaming-concepts/relation-to-nats.md index 56608b7..c88d8f8 100644 --- a/nats_streaming/relation-to-nats.md +++ b/nats-streaming-concepts/relation-to-nats.md @@ -2,12 +2,13 @@ NATS Streaming Server by default embeds a [NATS](https://github.com/nats-io/nats-server) server. That is, the Streaming server is not a server per-se, but instead, a client to a NATS Server. -It means that Streaming clients are not directly connected to the streaming server, but instead communicate with the streaming server *through* NATS Server. +It means that Streaming clients are not directly connected to the streaming server, but instead communicate with the streaming server _through_ NATS Server. This detail is important when it comes to Streaming clients connections to the Streaming server. Indeed, since there is no direct connection, the server knows if a client is connected based on heartbeats. -***It is therefore strongly recommended for clients to close their connection when the application exits, otherwise the server will consider these clients connected (sending data, etc...) until it detects missing heartbeats.*** +_**It is therefore strongly recommended for clients to close their connection when the application exits, otherwise the server will consider these clients connected \(sending data, etc...\) until it detects missing heartbeats.**_ The streaming server creates internal subscriptions on specific subjects to communicate with its clients and/or other servers. Note that NATS clients and NATS Streaming clients cannot exchange data between each other. That is, if a streaming client publishes on `foo`, a NATS client subscribing on that same subject will not receive the messages. Streaming messages are NATS messages made of a protobuf. The streaming server is expected to send ACKs back to producers and receive ACKs from consumers. If messages were freely exchanged with the NATS clients, this would cause problems. + diff --git a/nats_streaming/store-encryption.md b/nats-streaming-concepts/store-encryption.md similarity index 82% rename from nats_streaming/store-encryption.md rename to nats-streaming-concepts/store-encryption.md index cec4d2e..e9b9632 100644 --- a/nats_streaming/store-encryption.md +++ b/nats-streaming-concepts/store-encryption.md @@ -1,30 +1,34 @@ # Store Encryption -The server can be configured to encrypt a message's payload when storing them, providing encryption at rest. This can be done from the command line or from the configuration file. Check `encrypt` and `encryption_key` in the [Configuring](#configuring) section. +The server can be configured to encrypt a message's payload when storing them, providing encryption at rest. This can be done from the command line or from the configuration file. Check `encrypt` and `encryption_key` in the [Configuring](store-encryption.md#configuring) section. It is recommended to provide the encryption key through the environment variable `NATS_STREAMING_ENCRYPTION_KEY` instead of `encryption_key`. If encryption is enabled and `NATS_STREAMING_ENCRYPTION_KEY` is found, this will take precedence over `encryption_key` value. You can pass this from the command line this way: -``` + +```text $ env NATS_STREAMING_ENCRYPTION_KEY="mykey" nats-streaming-server -store file -dir datastore -encrypt ``` -We currently support two ciphers for encryption: [AES](https://godoc.org/crypto/aes) and [CHACHA](https://godoc.org/golang.org/x/crypto/chacha20poly1305). -The default selected cipher depends on the platform. For ARM, we use `CHACHA`, otherwise we default to `AES`. You can always override that decision by explicitly specifying the cipher like this: -``` +We currently support two ciphers for encryption: [AES](https://godoc.org/crypto/aes) and [CHACHA](https://godoc.org/golang.org/x/crypto/chacha20poly1305). The default selected cipher depends on the platform. For ARM, we use `CHACHA`, otherwise we default to `AES`. You can always override that decision by explicitly specifying the cipher like this: + +```text $ env NATS_STREAMING_ENCRYPTION_KEY="mykey" nats-streaming-server -store file -dir datastore -encrypt -encryption_cipher "CHACHA" ``` + or, to select `AES`: -``` + +```text $ env NATS_STREAMING_ENCRYPTION_KEY="mykey" nats-streaming-server -store file -dir datastore -encrypt -encryption_cipher "AES" ``` Note that only message payload is encrypted, all other data stored by NATS Streaming server is not. -When running in clustering mode (see below), the server uses RAFT, which uses its own log files. Those will be encrypted too. +When running in clustering mode \(see below\), the server uses RAFT, which uses its own log files. Those will be encrypted too. Starting a server with `encrypt` against a datastore that was not encrypted may result in failures when it comes to decrypt a message, which may not happen immediately upon startup. Instead, it will happen when attempting to deliver messages to consumers. However, when possible, the server will detect if the data was not encrypted and return the data without attempting to decrypt it. The server will also detect which cipher was used to encrypt the data and use the proper cipher to decrypt, even if this is not the currently selected cipher. If the data is encrypted with a key and the server is restarted with a different key, the server will fail to decrypt messages when attempting to load them from the store. Performance considerations: As expected, encryption is likely to decrease performance, but by how much is hard to define. In some performance tests on a MacbookPro 2.8 GHz Intel Core i7 with SSD, we have observed as little as 1% decrease to more than 30%. In addition to CPU cycles required for encryption, the encrypted payload is bigger, which result in more data being stored or read. + diff --git a/nats_streaming/store-interface.md b/nats-streaming-concepts/store-interface.md similarity index 83% rename from nats_streaming/store-interface.md rename to nats-streaming-concepts/store-interface.md index bf0f591..982b7c8 100644 --- a/nats_streaming/store-interface.md +++ b/nats-streaming-concepts/store-interface.md @@ -2,14 +2,15 @@ Every store implementation follows the [Store interface](https://github.com/nats-io/nats-streaming-server/blob/master/stores/store.go). -On startup, the server creates a unique instance of the `Store`. The constructor of a store implementation can do some initialization and configuration check, but *must not* access, or attempt to recover, the storage at this point. This is important because when the server runs on Fault Tolerance mode, the storage must be shared across many servers but only one server can be using it. +On startup, the server creates a unique instance of the `Store`. The constructor of a store implementation can do some initialization and configuration check, but _must not_ access, or attempt to recover, the storage at this point. This is important because when the server runs on Fault Tolerance mode, the storage must be shared across many servers but only one server can be using it. -After instantiating the store, the server will then call `Recover()` in order to recover the persisted state. For implementations that do not support persistence, such as the provided `MemoryStore`, this call will simply return `nil` (without error) to indicate that no state was recovered. +After instantiating the store, the server will then call `Recover()` in order to recover the persisted state. For implementations that do not support persistence, such as the provided `MemoryStore`, this call will simply return `nil` \(without error\) to indicate that no state was recovered. The `Store` is used to add/delete clients, create/lookup channels, etc... Creating/looking up a channel will return a `ChannelStore`, which points to two other interfaces, the `SubStore` and `MsgStore`. These stores, for a given channel, handle subscriptions and messages respectively. -If you wish to contribute to a new store type, your implementation must include all these interfaces. For stores that allow recovery (such as file store as opposed to memory store), there are additional structures that have been defined and should be returned by `Recover()`. +If you wish to contribute to a new store type, your implementation must include all these interfaces. For stores that allow recovery \(such as file store as opposed to memory store\), there are additional structures that have been defined and should be returned by `Recover()`. The memory and the provided file store implementations both use a generic store implementation to avoid code duplication. When writing your own store implementation, you can do the same for APIs that don't need to do more than what the generic implementation provides. You can check [MemStore](https://github.com/nats-io/nats-streaming-server/blob/master/stores/memstore.go) and [FileStore](https://github.com/nats-io/nats-streaming-server/blob/master/stores/filestore.go) implementations for more details. + diff --git a/nats_streaming/gettingstarted/changes.md b/nats-streaming-server/changes.md similarity index 59% rename from nats_streaming/gettingstarted/changes.md rename to nats-streaming-server/changes.md index cc6077c..b0c3f0e 100644 --- a/nats_streaming/gettingstarted/changes.md +++ b/nats-streaming-server/changes.md @@ -1,13 +1,11 @@ # Important Changes - * [Version `0.10.0`](#version-0100) - * [Version `0.9.0`](#version-090) - * [Version `0.8.0-beta`](#version-080-beta) - * [Version `0.6.0`](#version-060) - * [Version `0.5.0`](#version-050) - * [Version `0.4.0`](#version-040) - - +* [Version `0.10.0`](changes.md#version-0100) +* [Version `0.9.0`](changes.md#version-090) +* [Version `0.8.0-beta`](changes.md#version-080-beta) +* [Version `0.6.0`](changes.md#version-060) +* [Version `0.5.0`](changes.md#version-050) +* [Version `0.4.0`](changes.md#version-040) ## Version `0.10.0` @@ -15,29 +13,33 @@ The server needs to persist more state for a client connection. Therefore, the S * Changed `AddClient(clientID, hbInbox string)` to `AddClient(info *spb.ClientInfo)` -For SQL Stores, the `Clients` table has been altered to add a `proto` column.
-You can update the SQL table manually or run the provided scripts that create the tables if they don't exists -and alter the `Clients` table adding the new column. For instance, with MySQL, you would run something similar to: +For SQL Stores, the `Clients` table has been altered to add a `proto` column. + You can update the SQL table manually or run the provided scripts that create the tables if they don't exists and alter the `Clients` table adding the new column. For instance, with MySQL, you would run something similar to: -``` +```text mysql -u root nss_db < scripts/mysql.db.sql ``` + The above assumes you are in the NATS Streaming Server directory, and the streaming database is called `nss_db`. Otherwise, from the mysql CLI, you can run the command: -``` + +```text mysql> alter table Clients add proto blob; Query OK, 0 rows affected (0.05 sec) Records: 0 Duplicates: 0 Warnings: 0 ``` + For Postgres, it would be: -``` + +```text nss_db=# alter table Clients add proto bytea; ALTER TABLE ``` If you run the server version with `0.10.0` a database that has not been updated, you would get the following error: -``` + +```text [FTL] STREAM: Failed to start: unable to prepare statement "INSERT INTO Clients (id, hbinbox, proto) VALUES (?, ?, ?)": Error 1054: Unknown column 'proto' in 'field list' ``` @@ -55,62 +57,82 @@ Protocol was added to support replication of deletion of a channel in the cluste The Store interface has been slightly changed to accommodate the clustering feature. * Changed `MstStore.Store()` API to accept a `*pb.MsgProto` instead of a byte array. This is because the server is now assigning the sequence number. -The store implementation should ignore the call if the given sequence number is below or equal to what has been already stored. + + The store implementation should ignore the call if the given sequence number is below or equal to what has been already stored. + * Added `MsgStore.Empty()` API to empty a given channel message store. ## Version `0.6.0` -The Store interface has been heavily modified. Some of the responsibilities have been moved into the server -resulting on deletion of some Store APIs and removal of `UserData` fields in `Client` and `ChannelStore` (renamed `Channel`) objects. +The Store interface has been heavily modified. Some of the responsibilities have been moved into the server resulting on deletion of some Store APIs and removal of `UserData` fields in `Client` and `ChannelStore` \(renamed `Channel`\) objects. ->**NOTE:** Although the interface has changed, the file format of the FileStore implementation has not, which means -that there is backward/forward compatibility between this and previous releases. +> **NOTE:** Although the interface has changed, the file format of the FileStore implementation has not, which means that there is backward/forward compatibility between this and previous releases. The Store interface was updated: * Added error `ErrAlreadyExists` that `CreateChannel()` should return if channel already exists. -* `RecoveredState` has now `Channels` (instead of `Subs`) and is a map of `*RecoveredChannel` keyed by channel name. -* `RecoveredChannel` has a pointer to a `Channel` (formely `ChannelStore`) and an array of pointers to `RecoveredSubscription` objects. +* `RecoveredState` has now `Channels` \(instead of `Subs`\) and is a map of `*RecoveredChannel` keyed by channel name. +* `RecoveredChannel` has a pointer to a `Channel` \(formely `ChannelStore`\) and an array of pointers to `RecoveredSubscription` objects. * `RecoveredSubscription` replaces `RecoveredSubState`. * `Client` no longer stores a `UserData` field. -* `Channel` (formerly `ChannelStore`) no longer stores a `UserData` field. +* `Channel` \(formerly `ChannelStore`\) no longer stores a `UserData` field. * `CreateChannel()` no longer accepts a `userData interface{}` parameter. It returns a `*Channel` and an `error`. If the channel -already exists, the error `ErrAlreadyExists` is returned. + + already exists, the error `ErrAlreadyExists` is returned. + * `LookupChannel()`, `HasChannel()`, `GetChannels()`, `GetChannelsCount()`, `GetClient()`, `GetClients`, `GetClientsCount()` and `MsgsState()` APIs -have all been removed. The server keeps track of clients and channels and therefore does not need those APIs. + + have all been removed. The server keeps track of clients and channels and therefore does not need those APIs. + * `AddClient()` is now simply returning a `*Client` and `error`. It no longer accepts a `userData interface{}` parameter. * `DeleteClient()` now returns an error instead of returning the deleted `*Client`. This will allow the server to -report possible errors. + + report possible errors. The SubStore interface was updated: * `DeleteSub()` has been modified to return an error. This allows the server to report possible errors during deletion -of a subscription. + + of a subscription. The MsgStore interface was updated: * `Lookup()`, `FirstSequence()`, `LastSequence()`, `FirstAndLastSequence()`, `GetSequenceFromTimestamp()`, `FirstMsg()` and `LastMsg()` -have all been modified to return an error. This is so that implementations that may fail to lookup, get the first sequence, etc... -have a way to report the error to the caller. + + have all been modified to return an error. This is so that implementations that may fail to lookup, get the first sequence, etc... + + have a way to report the error to the caller. ## Version `0.5.0` The Store interface was updated. There are 2 news APIs: -* `GetChannels()`: Returns a map of `*ChannelStore`, keyed by channel names.
-The implementation needs to return a copy to make it safe for the caller to manipulate -the map without a risk of concurrent access. +* `GetChannels()`: Returns a map of `*ChannelStore`, keyed by channel names. + + + The implementation needs to return a copy to make it safe for the caller to manipulate + + the map without a risk of concurrent access. + * `GetChannelsCount()`: Returns the number of channels currently stored. ## Version `0.4.0` The Store interface was updated. There are 2 news APIs: -* `Recover()`: The recovery of persistent state was previously done in the constructor of the store implementation.
-It is now separate and specified with this API. The server will first instantiate the store, in -which some initialization or checks can be made.
-If no error is reported, the server will then proceed with calling `Recover()`, which will returned the recovered state.
+* `Recover()`: The recovery of persistent state was previously done in the constructor of the store implementation. + + + It is now separate and specified with this API. The server will first instantiate the store, in + + which some initialization or checks can be made. + + + If no error is reported, the server will then proceed with calling `Recover()`, which will returned the recovered state. + * `GetExclusiveLock()`: In Fault Tolerance mode, when a server is elected leader, it will attempt to get an exclusive -lock to the shared storage before proceeding.
+ + lock to the shared storage before proceeding. Check the [Store interface](https://github.com/nats-io/nats-streaming-server/blob/master/stores/store.go) for more information. + diff --git a/nats-streaming-server/configuring/README.md b/nats-streaming-server/configuring/README.md new file mode 100644 index 0000000..2848f4a --- /dev/null +++ b/nats-streaming-server/configuring/README.md @@ -0,0 +1,10 @@ +# Configuring + +NATS Streaming provides a rich set of commands and parameters to configure all aspects of the server. + +* [Command Line Arguments](cmdline.md) +* [Configuration File](cfgfile.md) +* [Store Limits](storelimits/) +* [Persistence](persistence/) +* [Securing](tls/) + diff --git a/nats-streaming-server/configuring/cfgfile.md b/nats-streaming-server/configuring/cfgfile.md new file mode 100644 index 0000000..c3f7181 --- /dev/null +++ b/nats-streaming-server/configuring/cfgfile.md @@ -0,0 +1,168 @@ +# Configuration file + +You can use a configuration file to configure the options specific to the NATS Streaming Server. + +Use the `-sc` or `-stan_config` command line parameter to specify the file to use. + +For the embedded NATS Server, you can use another configuration file and pass it to the Streaming Server using `-c` or `--config` command line parameters. + +Since most options do not overlap, it is possible to combine all options into a single file and specify this file using either the `-sc` or `-c` command line parameter. + +However, the option named `tls` is common to NATS Server and NATS Streaming Server. If you plan to use a single configuration file and configure TLS, you should have all the streaming configuration included in a `streaming` map. This is actually a good practice regardless if you use TLS or not, to protect against possible addition of new options in NATS Server that would conflict with the names of NATS Streaming options. + +For instance, you could use a single configuration file with such content: + +```text +# Some NATS Server TLS Configuration +listen: localhost:5222 +tls: { + cert_file: "/path/to/server/cert_file" + key_file: "/path/to/server/key_file" + verify: true + timeout: 2 +} + +# NATS Streaming Configuration +streaming: { + cluster_id: my_cluster + + tls: { + client_cert: "/path/to/client/cert_file" + client_key: "/path/to/client/key_file" + } +} +``` + +However, if you want to avoid any possible conflict, simply use two different configuration files. + +Note the order in which options are applied during the start of a NATS Streaming server: + +1. Start with some reasonable default options. +2. If a configuration file is specified, override those options + + with all options defined in the file. This includes options that are defined + + but have no value specified. In this case, the zero value for the type of the + + option will be used. + +3. Any command line parameter override all of the previous set options. + +In general the configuration parameters are the same as the command line arguments. Below is the list of NATS Streaming parameters: + +| Parameter | Meaning | Possible Values | Usage Example | +| :--- | :--- | :--- | :--- | +| cluster\_id | Cluster name | String, underscore possible | `cluster_id: "my_cluster_name"` | +| discover\_prefix | Subject prefix for server discovery by clients | NATS Subject | `discover_prefix: "_STAN.Discovery"` | +| store | Store type | `memory`, `file` or `sql` | `store: "file"` | +| dir | When using a file store, this is the root directory | File path | `dir: "/path/to/storage` | +| sd | Enable debug logging | `true` or `false` | `sd: true` | +| sv | Enable trace logging | `true` or `false` | `sv: true` | +| nats\_server\_url | If specified, connects to an external NATS Server, otherwise starts an embedded one | NATS URL | `nats_server_url: "nats://localhost:4222"` | +| secure | If true, creates a TLS connection to the server but without the need to use TLS configuration \(no NATS Server certificate verification\) | `true` or `false` | `secure: true` | +| tls | TLS Configuration | Map: `tls: { ... }` | [**See details below**](cfgfile.md#tls-configuration) | +| store\_limits | Store Limits | Map: `store_limits: { ... }` | [**See details below**](cfgfile.md#store-limits-configuration) | +| file\_options | File Store specific options | Map: `file_options: { ... }` | [**See details below**](cfgfile.md#file-options-configuration) | +| sql\_options | SQL Store specific options | Map: `sql_options: { ... }` | [**See details below**](cfgfile.md#sql-options-configuration) | +| hb\_interval | Interval at which the server sends an heartbeat to a client | Duration | `hb_interval: "10s"` | +| hb\_timeout | How long the server waits for a heartbeat response from the client before considering it a failed heartbeat | Duration | `hb_timeout: "10s"` | +| hb\_fail\_count | Count of failed heartbeats before server closes the client connection. The actual total wait is: \(fail count + 1\) \* \(hb interval + hb timeout\) | Number | `hb_fail_count: 2` | +| ft\_group | In Fault Tolerance mode, you can start a group of streaming servers with only one server being active while others are running in standby mode. This is the name of this FT group | String | `ft_group: "my_ft_group"` | +| partitioning | If set to true, a list of channels must be defined in store\_limits/channels section. This section then serves two purposes, overriding limits for a given channel or adding it to the partition | `true` or `false` | `partitioning: true` | +| cluster | Cluster Configuration | Map: `cluster: { ... }` | [**See details below**](cfgfile.md#cluster-configuration) | +| encrypt | Specify if server should encrypt messages \(only the payload\) when storing them | `true` or `false` | `encrypt: true` | +| encryption\_cipher | Cipher to use for encryption. Currently support AES and CHAHA \(ChaChaPoly\). Defaults to AES | `AES` or `CHACHA` | `encryption_cipher: "AES"` | +| encryption\_key | Encryption key. It is recommended to specify the key through the `NATS_STREAMING_ENCRYPTION_KEY` environment variable instead | String | `encryption_key: "mykey"` | + +## TLS Configuration + +Note that the Streaming Server uses a connection to a NATS Server, and so the NATS Streaming TLS Configuration is in fact a client-side TLS configuration. + +| Parameter | Meaning | Possible Values | Usage Example | +| :--- | :--- | :--- | :--- | +| client\_cert | Client key for the streaming server | File path | `client_cert: "/path/to/client/cert_file"` | +| client\_key | Client certificate for the streaming server | File path | `client_key: "/path/to/client/key_file"` | +| client\_ca | Client certificate CA for the streaming server | File path | `client_ca: "/path/to/client/ca_file"` | + +## Store Limits Configuration + +| Parameter | Meaning | Possible Values | Usage Example | +| :--- | :--- | :--- | :--- | +| max\_channels | Maximum number of channels, 0 means unlimited | Number >= 0 | `max_channels: 100` | +| max\_subs | Maximum number of subscriptions per channel, 0 means unlimited | Number >= 0 | `max_subs: 100` | +| max\_msgs | Maximum number of messages per channel, 0 means unlimited | Number >= 0 | `max_msgs: 10000` | +| max\_bytes | Total size of messages per channel, 0 means unlimited | Number >= 0 | `max_bytes: 1GB` | +| max\_age | How long messages can stay in the log | Duration | `max_age: "24h"` | +| max\_inactivity | How long without any subscription and any new message before a channel can be automatically deleted | Duration | `max_inactivity: "24h"` | +| channels | A map of channel names with specific limits | Map: `channels: { ... }` | [**See details below**](cfgfile.md#channels) | + +## Channels + +The `channels` section is a map with the key being the channel name. For instance: + +```text + channels: { + "foo": { + max_msgs: 100 + } + } +``` + +For a given channel, the possible parameters are: + +| Parameter | Meaning | Possible Values | Usage Example | +| :--- | :--- | :--- | :--- | +| max\_subs | Maximum number of subscriptions per channel, 0 means unlimited | Number >= 0 | `max_subs: 100` | +| max\_msgs | Maximum number of messages per channel, 0 means unlimited | Number >= 0 | `max_msgs: 10000` | +| max\_bytes | Total size of messages per channel, 0 means unlimited | Bytes | `max_bytes: 1GB` | +| max\_age | How long messages can stay in the log | Duration | `max_age: "24h"` | +| max\_inactivity | How long without any subscription and any new message before a channel can be automatically deleted | Duration | `max_inactivity: "24h"` | + +## File Options Configuration + +| Parameter | Meaning | Possible Values | Usage Example | +| :--- | :--- | :--- | :--- | +| compact | Enable/disable file compaction. Only some of the files \(`clients.dat` and `subs.dat`\) are subject to compaction | `true` or `false` | `compact: true` | +| compact\_fragmentation | Compaction threshold \(in percentage\) | Number >= 0 | `compact_fragmentation: 50` | +| compact\_interval | Minimum interval between attempts to compact files | Expressed in seconds | `compact_interval: 300` | +| compact\_min\_size | Minimum size of a file before compaction can be attempted | Bytes | `compact_min_size: 1GB` | +| buffer\_size | Size of buffers that can be used to buffer write operations | Bytes | `buffer_size: 2MB` | +| crc | Define if CRC of records should be computed on reads | `true` or `false` | `crc: true` | +| crc\_poly | You can select the CRC polynomial. Note that changing the value after records have been persisted would result in server failing to start complaining about data corruption | Number >= 0 | `crc_poly: 3988292384` | +| sync\_on\_flush | Define if server should perform "file sync" operations during a flush | `true` or `false` | `sync_on_flush: true` | +| slice\_max\_msgs | Define the file slice maximum number of messages. If set to 0 and a channel count limit is set, then the server will set a slice count limit automatically | Number >= 0 | `slice_max_msgs: 10000` | +| slice\_max\_bytes | Define the file slice maximum size \(including the size of index file\). If set to 0 and a channel size limit is set, then the server will set a slice bytes limit automatically | Bytes | `slice_max_bytes: 64MB` | +| slice\_max\_age | Define the period of time covered by a file slice, starting at when the first message is stored. If set to 0 and a channel age limit is set, then the server will set a slice age limit automatically | Duration | `slice_max_age: "24h"` | +| slice\_archive\_script | Define the location and name of a script to be invoked when the server discards a file slice due to limits. The script is invoked with the name of the channel, the name of data and index files. It is the responsibility of the script to then remove the unused files | File path | `slice_archive_script: "/home/nats-streaming/archive/script.sh"` | +| file\_descriptors\_limit | Channels translate to sub-directories under the file store's root directory. Each channel needs several files to maintain the state so the need for file descriptors increase with the number of channels. This option instructs the store to limit the concurrent use of file descriptors. Note that this is a soft limit and there may be cases when the store will use more than this number. A value of 0 means no limit. Setting a limit will probably have a performance impact | Number >= 0 | `file_descriptors_limit: 100` | +| parallel\_recovery | When the server starts, the recovery of channels \(directories\) is done sequentially. However, when using SSDs, it may be worth setting this value to something higher than 1 to perform channels recovery in parallel | Number >= 1 | `parallel_recovery: 4` | +| read\_buffer\_size | Size of buffers used to read ahead from message stores. This can significantly speed up sending messages to consumers after messages have been published. Default is 2MB. Set to 0 to disable | Bytes | `read_buffer_size: 2MB` | +| auto\_sync | Interval at which the store should be automatically flushed and sync'ed on disk. Default is every minute. Set to <=0 to disable | Duration | `auto_sync: "2m"` | + +## Cluster Configuration + +| Parameter | Meaning | Possible Values | Usage Example | +| :--- | :--- | :--- | :--- | +| node\_id | ID of the node within the cluster if there is no stored ID | String \(no whitespace\) | `node_id: "node-a"` | +| bootstrap | Bootstrap the cluster if there is no existing state by electing self as leader | `true` or `false` | `bootstrap: true` | +| peers | List of cluster peer node IDs to bootstrap cluster state | List of node IDs | `peers: ["node-b", "node-c"]` | +| log\_path | Directory to store log replication data | File path | `log_path: "/path/to/storage"` | +| log\_cache\_size | Number of log entries to cache in memory to reduce disk IO | Number >= 0 | `log_cache_size: 1024` | +| log\_snapshots | Number of log snapshots to retain | Number >= 0 | `log_snapshots: 1` | +| trailing\_logs | Number of log entries to leave after a snapshot and compaction | Number >= 0 | `trailing_logs: 256` | +| sync | Do a file sync after every write to the replication log and message store | `true` or `false` | `sync: true` | +| raft\_logging | Enable logging from the Raft library \(disabled by default\) | `true` or `false` | `raft_logging: true` | +| raft\_heartbeat\_timeout | Specifies the time in follower state without a leader before attempting an election | Duration | `raft_heartbeat_timeout: "2s"` | +| raft\_election\_timeout | Specifies the time in candidate state without a leader before attempting an election | Duration | `raft_election_timeout: "2s"` | +| raft\_lease\_timeout | Specifies how long a leader waits without being able to contact a quorum of nodes before stepping down as leader | Duration | `raft_lease_timeout: "1s"` | +| raft\_commit\_timeout | Specifies the time without an Apply\(\) operation before sending an heartbeat to ensure timely commit. Due to random staggering, may be delayed as much as 2x this value | Duration | `raft_commit_timeout: "100ms"` | + +## SQL Options Configuration + +| Parameter | Meaning | Possible Values | Usage Example | +| :--- | :--- | :--- | :--- | +| driver | Name of the SQL driver to use | `mysql` or `postgres` | `driver: "mysql"` | +| source | How to connect to the database. This is driver specific | String | `source: "ivan:pwd@/nss_db"` | +| no\_caching | Enable/Disable caching for messages and subscriptions operations. The default is `false`, which means that caching is enabled | `true` or `false` | `no_caching: false` | +| max\_open\_conns | Maximum number of opened connections to the database. Value <= 0 means no limit. The default is 0 \(unlimited\) | Number | `max_open_conns: 5` | + diff --git a/nats_streaming/configuring/cmdline.md b/nats-streaming-server/configuring/cmdline.md similarity index 95% rename from nats_streaming/configuring/cmdline.md rename to nats-streaming-server/configuring/cmdline.md index dd71cf9..3d5cbd9 100644 --- a/nats_streaming/configuring/cmdline.md +++ b/nats-streaming-server/configuring/cmdline.md @@ -1,16 +1,16 @@ -# Command Line Arguments +# Command line arguments The NATS Streaming Server accepts command line arguments to control its behavior. There is a set of parameters specific to the NATS Streaming Server and some to the embedded NATS Server. -***Note about parameters types*** +_**Note about parameters types**_ | Type | Remark | -|:----|:----| -|``| For booleans, either simply specify the parameter with value to enable (e.g `-SD`), or specify `=false` to disable| -|`` | You can specify as a number `1024` or as a size `1KB`| -|`` | Values must be expressed in the form `_h_m_s`, such as `1h` or `20s` or `1h30m`, or `1.5h`, etc...| +| :--- | :--- | +| `` | For booleans, either simply specify the parameter with value to enable \(e.g `-SD`\), or specify `=false` to disable | +| `` | You can specify as a number `1024` or as a size `1KB` | +| `` | Values must be expressed in the form `_h_m_s`, such as `1h` or `20s` or `1h30m`, or `1.5h`, etc... | -``` +```text Usage: nats-streaming-server [options] Streaming Server Options: @@ -121,4 +121,5 @@ Common Options: -h, --help Show this message -v, --version Show version --help_tls TLS help -``` \ No newline at end of file +``` + diff --git a/nats_streaming/configuring/persistence.md b/nats-streaming-server/configuring/persistence/README.md similarity index 80% rename from nats_streaming/configuring/persistence.md rename to nats-streaming-server/configuring/persistence/README.md index 1b122c5..bf70824 100644 --- a/nats_streaming/configuring/persistence.md +++ b/nats-streaming-server/configuring/persistence/README.md @@ -1,3 +1,4 @@ # Persistence -By default, the NATS Streaming Server stores its state in memory, which means that if the streaming server is stopped, all state is lost. Still, this level of persistence allows applications to stop and later resume the stream of messages, and protect against applications disconnect (network or applications crash). +By default, the NATS Streaming Server stores its state in memory, which means that if the streaming server is stopped, all state is lost. Still, this level of persistence allows applications to stop and later resume the stream of messages, and protect against applications disconnect \(network or applications crash\). + diff --git a/nats-streaming-server/configuring/persistence/filestore/README.md b/nats-streaming-server/configuring/persistence/filestore/README.md new file mode 100644 index 0000000..538a160 --- /dev/null +++ b/nats-streaming-server/configuring/persistence/filestore/README.md @@ -0,0 +1,71 @@ +# File Store + +For a higher level of message delivery, the server should be configured with a file store. NATS Streaming Server comes with a basic file store implementation. Various file store implementations may be added in the future. + +To start the server with a file store, you need to provide two parameters: + +```bash +nats-streaming-server -store file -dir datastore +``` + +The parameter `-store` indicates what type of store to use, in this case `file`. The other \(`-dir`\) indicates in which directory the state should be stored. + +The first time the server is started, it will create two files in this directory, one containing some server related information \(`server.dat`\) another to record clients information \(`clients.dat`\). + +When a streaming client connects, it uses a client identification, which the server registers in this file. When the client disconnects, the client is cleared from this file. + +When the client publishes or subscribe to a new subject \(also called channel\), the server creates a sub-directory whose name is the subject. For instance, if the client subscribes to `foo`, and assuming that you started the server with `-dir datastore`, then you will find a directory called `datastore/foo`. In this directory you will find several files: one to record subscriptions information \(`subs.dat`\), and a series of files that logs the messages `msgs.1.dat`, etc... + +The number of sub-directories, which again correspond to channels, can be limited by the configuration parameter `-max_channels`. When the limit is reached, any new subscription or message published on a new channel will produce an error. + +On a given channel, the number of subscriptions can also be limited with the configuration parameter `-max_subs`. A client that tries to create a subscription on a given channel \(subject\) for which the limit is reached will receive an error. + +Finally, the number of stored messages for a given channel can also be limited with the parameter `-max_msgs` and/or `-max_bytes`. However, for messages, the client does not get an error when the limit is reached. The oldest messages are discarded to make room for the new messages. + +## Options + +As described in the [Configuring](https://github.com/nats-io/nats.docs/tree/51fc56e3090645f7cedb242415e2d5361e1807e7/nats_streaming/configuring/cfgfile.html#configuration-file) section, there are several options that you can use to configure a file store. + +Regardless of channel limits, you can configure message logs to be split in individual files \(called file slices\). You can configure those slices by number of messages it can contain \(`--file_slice_max_msgs`\), the size of the file - including the corresponding index file \(`--file_slice_max_bytes`\), or the period of time that a file slice should cover - starting at the time the first message is stored in that slice \(`--file_slice_max_age`\). The default file store options are defined such that only the slice size is configured to 64MB. + +> **Note**: If you don't configure any slice limit but you do configure channel limits, then the server will automatically set some limits for file slices. + +When messages accumulate in a channel, and limits are reached, older messages are removed. When the first file slice becomes empty, the server removes this file slice \(and corresponding index file\). + +However, if you specify a script \(`--file_slice_archive_script`\), then the server will rename the slice files \(data and index\) with a `.bak` extension and invoke the script with the channel name, data and index file names. + The files are left in the channel's directory and therefore it is the script responsibility to delete those files when done. At any rate, those files will not be recovered on a server restart, but having lots of unused files in the directory may slow down the server restart. + +For instance, suppose the server is about to delete file slice `datastore/foo/msgs.1.dat` \(and `datastore/foo/msgs.1.idx`\), and you have configured the script `/home/nats-streaming/archive_script.sh`. The server will invoke: + +```bash +/home/nats-streaming/archive_script.sh foo datastore/foo/msgs.1.dat.bak datastore/foo/msgs.2.idx.bak +``` + +Notice how the files have been renamed with the `.bak` extension so that they are not going to be recovered if the script leave those files in place. + +As previously described, each channel corresponds to a sub-directory that contains several files. It means that the need for file descriptors increase with the number of channels. In order to scale to ten or hundred thousands of channels, the option `fds_limit` \(or command line parameter `--file_fds_limit`\) may be considered to limit the total use of file descriptors. + +Note that this is a soft limit. It is possible for the store to use more file descriptors than the given limit if the number of concurrent read/writes to different channels is more than the said limit. It is also understood that this may affect performance since files may need to be closed/re-opened as needed. + +## Recovery Errors + +We have added the ability for the server to truncate any file that may otherwise report an `unexpected EOF` error during the recovery process. + +Since dataloss is likely to occur, the default behavior for the server on startup is to report recovery error and stop. It will now print the content of the first corrupted record before exiting. + +With the `-file_truncate_bad_eof` parameter, the server will still print those bad records but truncate each file at the position of the first corrupted record in order to successfully start. + +To prevent the use of this parameter as the default value, this option is not available in the configuration file. Moreover, the server will fail to start if started more than once with that parameter. + This flag may help recover from a store failure, but since data may be lost in that process, we think that the operator needs to be aware and make an informed decision. + +Note that this flag will not help with file corruption due to bad CRC for instance. You have the option to disable CRC on recovery with the `-file_crc=false` option. + +Let's review the impact and suggested steps for each of the server's corrupted files: + +* `server.dat`: This file contains meta data and NATS subjects used to communicate with client applications. If a corruption is reported with this file, we would suggest that you stop all your clients, stop the server, remove this file, restart the server. This will create a new `server.dat` file, but will not attempt to recover the rest of the channels because the server assumes that there is no state. So you should stop and restart the server once more. Then, you can restart all your clients. +* `clients.dat`: This contains information about client connections. If the file is truncated to move past an `unexpected EOF` error, this can result in no issue at all, or in client connections not being recovered, which means that the server will not know about possible running clients, and therefore it will not try to deliver any message to those non recovered clients, or reject incoming published messages from those clients. It is also possible that the server recovers a client connection that was actually closed. In this case, the server may attempt to deliver or redeliver messages unnecessarily. +* `subs.dat`: This is a channel's subscriptions file \(under the channel's directory\). If this file is truncated and some records are lost, it may result in no issue at all, or in client applications not receiving their messages since the server will not know about them. It is also possible that acknowledged messages get redelivered \(since their ack may have been lost\). +* `msgs..dat`: This is a channel's message log \(several per channel\). If one of those files is truncated, then message loss occurs. With the `unexpected EOF` errors, it is likely that only the last "file slice" of a channel will be affected. Nevertheless, if a lower sequence file slice is truncated, then gaps in message sequence will occur. So it would be possible for a channel to have now messages 1..100, 110..300 for instance, with messages 101 to 109 missing. Again, this is unlikely since we expect the unexpected end-of-file errors to occur on the last slice. + +For _Clustered_ mode, this flag would work only for the NATS Streaming specific store files. As you know, NATS Streaming uses RAFT for consensus, and RAFT uses its own logs. You could try the option if the server reports `unexpected EOF` errors for NATS Streaming file stores, however, you may want to simply delete all NATS Streaming and RAFT stores for the failed node and restart it. By design, the other nodes in the cluster have replicated the data, so this node will become a follower and catchup with the rest of the cluster, getting the data from the current leader and recreating its local stores. + diff --git a/nats-streaming-server/configuring/persistence/filestore/options.md b/nats-streaming-server/configuring/persistence/filestore/options.md new file mode 100644 index 0000000..b4382b0 --- /dev/null +++ b/nats-streaming-server/configuring/persistence/filestore/options.md @@ -0,0 +1,2 @@ +# Options + diff --git a/nats-streaming-server/configuring/persistence/filestore/recovery-errors.md b/nats-streaming-server/configuring/persistence/filestore/recovery-errors.md new file mode 100644 index 0000000..4fe8d75 --- /dev/null +++ b/nats-streaming-server/configuring/persistence/filestore/recovery-errors.md @@ -0,0 +1,2 @@ +# Recovery Errors + diff --git a/nats_streaming/configuring/sqlstore.md b/nats-streaming-server/configuring/persistence/sqlstore/README.md similarity index 50% rename from nats_streaming/configuring/sqlstore.md rename to nats-streaming-server/configuring/persistence/sqlstore/README.md index 647872b..7a0e59a 100644 --- a/nats_streaming/configuring/sqlstore.md +++ b/nats-streaming-server/configuring/persistence/sqlstore/README.md @@ -2,85 +2,75 @@ Using a SQL Database for persistence is another option. -In order to do so, `-store` simply needs to be set to `sql` and `-sql_driver` set to `mysql` or `postgres` -(the two drivers supported at the moment). The parameter `-sql_source` is driver specific, but generally -contains the information required to connect to a specific database on the given SQL database server. +In order to do so, `-store` simply needs to be set to `sql` and `-sql_driver` set to `mysql` or `postgres` \(the two drivers supported at the moment\). The parameter `-sql_source` is driver specific, but generally contains the information required to connect to a specific database on the given SQL database server. -Note that the NATS Streaming Server does not need root privileges to connect to the database since it does not create -the database, tables or indexes. This has to be done by the Database Administrator. +Note that the NATS Streaming Server does not need root privileges to connect to the database since it does not create the database, tables or indexes. This has to be done by the Database Administrator. -We provide 2 files (`scripts/mysql.db.sql` and `scripts/postgres.db.sql`) that can be used to create the tables and indexes to the -database of your choice. However, administrators are free to configure and optimize the database as long as the name of tables -and columns are preserved, since the NATS Streaming Server is going to issue SQL statements based on those. +We provide 2 files \(`scripts/mysql.db.sql` and `scripts/postgres.db.sql`\) that can be used to create the tables and indexes to the database of your choice. However, administrators are free to configure and optimize the database as long as the name of tables and columns are preserved, since the NATS Streaming Server is going to issue SQL statements based on those. Here is an example of creating an user `nss` with password `password` for the MySQL database: -``` +```text mysql -u root -e "CREATE USER 'nss'@'localhost' IDENTIFIED BY 'password'; GRANT ALL PRIVILEGES ON *.* TO 'nss'@'localhost'; CREATE DATABASE nss_db;" ``` -The above gives all permissions to user `nss`. Once this user is created, we can then create the tables using this user -and selecting the `nss_db` database. We then execute all the SQL statements creating the tables from the sql file that -is provided in this repo: +The above gives all permissions to user `nss`. Once this user is created, we can then create the tables using this user and selecting the `nss_db` database. We then execute all the SQL statements creating the tables from the sql file that is provided in this repo: -``` +```text mysql -u nss -p -D nss_db -e "$(cat ./scripts/mysql.db.sql)" ``` ## Example - Postgres + Run a local dockerized instance of postgres if you do not already have one: -``` +```text ID=$(docker run -d -e POSTGRES_PASSWORD=password -p 5432:5432 postgres) ``` -[Optional] Drop any previous tables to clear data from previous sessions: +\[Optional\] Drop any previous tables to clear data from previous sessions: -``` +```text cat scripts/drop_postgres.db.sql | docker exec -i $ID psql -h 127.0.1.1 -U postgres ``` Run the appropriate database migrations for Postgres: -``` +```text cat scripts/postgres.db.sql | docker exec -i $ID psql -h 127.0.1.1 -U postgres ``` -Run the nats streaming server with postgres at the sql_source: +Run the nats streaming server with postgres at the sql\_source: -``` +```text DOCKER_BRIDGE_IP=$(docker inspect --format '{{(index .IPAM.Config 0).Gateway}}' bridge) docker run -d --name nats-streaming -p 4222:4222 -p 8222:32768 nats-streaming-local -SDV --store sql --sql_driver postgres --sql_source="user=postgres password=postgres host=$DOCKER_BRIDGE_IP port=5432 sslmode=disable" ``` ## Read and Write Timeouts -Sometimes, it is possible that a DB connection between the streaming server and the DB server is stale but the connection is not dropped. -This would cause the server to block while trying to store or lookup a message, or any other operation involving the database. -Because of internal locking in the store implementation, this could cause the server to seemingly be unresponsive. +Sometimes, it is possible that a DB connection between the streaming server and the DB server is stale but the connection is not dropped. This would cause the server to block while trying to store or lookup a message, or any other operation involving the database. Because of internal locking in the store implementation, this could cause the server to seemingly be unresponsive. -To mitigate that, you can pass `readTimeout` and `writeTimeout` options to the `sql_source` when starting the server. The MySQL driver had always had those options, but we have extended the Postgres driver that we use to provide those options in NATS Streaming `v0.16.0`. -You pass the values as a duration, for instance `5s` for 5 seconds. +To mitigate that, you can pass `readTimeout` and `writeTimeout` options to the `sql_source` when starting the server. The MySQL driver had always had those options, but we have extended the Postgres driver that we use to provide those options in NATS Streaming `v0.16.0`. You pass the values as a duration, for instance `5s` for 5 seconds. Here is what a `sql_source` would look like for `MySQL` driver: -``` + +```text nats-streaming-server -store sql -sql_driver mysql -sql_source "nss:password@/nss_db?readTimeout=5s&writeTimeout=5s" .. ``` + Or, for `Postgres` driver: -``` + +```text nats-streaming-server -store sql -sql_driver postgres -sql_source "dbname=nss_db readTimeout=5s writeTimeout=5s sslmode=disable" .. ``` + Be careful to not make those values too small otherwise you could cause unwanted failures. ## Options -Aside from the driver and datasource, the available options are the maximum number of opened connections to the database (`max_open_conns`) -that you may need to set to avoid errors due to `too many opened files`. +Aside from the driver and datasource, the available options are the maximum number of opened connections to the database \(`max_open_conns`\) that you may need to set to avoid errors due to `too many opened files`. -The other option is `no_caching` which is a boolean that enables/disables caching. By default caching is enabled. It means -that some operations are buffered in memory before being sent to the database. For storing messages, this still offers the -guarantee that if a producer gets an OK ack back, the message will be successfully persisted in the database. +The other option is `no_caching` which is a boolean that enables/disables caching. By default caching is enabled. It means that some operations are buffered in memory before being sent to the database. For storing messages, this still offers the guarantee that if a producer gets an OK ack back, the message will be successfully persisted in the database. + +For subscriptions, the optimization may lead to messages possibly redelivered if the server were to be restarted before some of the operations were "flushed" to the database. The performance improvement is significant to justify the risk of getting redelivered messages \(which is always possible with NATS Streaming regardless of this option\). Still, if you want to ensure that each operation is immediately committed to the database, you should set `no_caching` to true. -For subscriptions, the optimization may lead to messages possibly redelivered if the server were to be restarted before -some of the operations were "flushed" to the database. The performance improvement is significant to justify the risk -of getting redelivered messages (which is always possible with NATS Streaming regardless of this option). Still, -if you want to ensure that each operation is immediately committed to the database, you should set `no_caching` to true. diff --git a/nats-streaming-server/configuring/persistence/sqlstore/options.md b/nats-streaming-server/configuring/persistence/sqlstore/options.md new file mode 100644 index 0000000..b4382b0 --- /dev/null +++ b/nats-streaming-server/configuring/persistence/sqlstore/options.md @@ -0,0 +1,2 @@ +# Options + diff --git a/nats-streaming-server/configuring/persistence/sqlstore/read-and-write-timeouts.md b/nats-streaming-server/configuring/persistence/sqlstore/read-and-write-timeouts.md new file mode 100644 index 0000000..be5b2aa --- /dev/null +++ b/nats-streaming-server/configuring/persistence/sqlstore/read-and-write-timeouts.md @@ -0,0 +1,2 @@ +# Read and Write Timeouts + diff --git a/nats_streaming/configuring/storelimits.md b/nats-streaming-server/configuring/storelimits/README.md similarity index 70% rename from nats_streaming/configuring/storelimits.md rename to nats-streaming-server/configuring/storelimits/README.md index 246d93c..c27616e 100644 --- a/nats_streaming/configuring/storelimits.md +++ b/nats-streaming-server/configuring/storelimits/README.md @@ -1,15 +1,12 @@ # Store Limits -The `store_limits` section in the configuration file (or the command line parameters -`-mc`, `-mm`, etc..) allow you to configure the global limits. +The `store_limits` section in the configuration file \(or the command line parameters `-mc`, `-mm`, etc..\) allow you to configure the global limits. -These limits offer some upper bounds on the size of the storage. By multiplying -the limits per channel with the maximum number of channels, you will get a total limit. +These limits offer some upper bounds on the size of the storage. By multiplying the limits per channel with the maximum number of channels, you will get a total limit. -It is not the case, though, if you override limits of some channels. Indeed, it is possible -to define specific limits per channel. Here is how: +It is not the case, though, if you override limits of some channels. Indeed, it is possible to define specific limits per channel. Here is how: -``` +```text ... store_limits: { # Override some global limits @@ -66,50 +63,35 @@ store_limits: { ... ``` -Note that the number of defined channels cannot be greater than the stores' maximum number -of channels. ***This is true only for channels without wildcards.*** +Note that the number of defined channels cannot be greater than the stores' maximum number of channels. _**This is true only for channels without wildcards.**_ -Channels limits can override global limits by being either higher, lower or even set to -unlimited. +Channels limits can override global limits by being either higher, lower or even set to unlimited. -***An unlimited value applies to the specified limit, not to the whole channel.*** +_**An unlimited value applies to the specified limit, not to the whole channel.**_ -That is, in the configuration above, `baz` has the maximum number of messages set -to 0, which means ignored or unlimited. Yet, other limits such as max bytes, max age -and max subscriptions (inherited in this case) still apply. What that means is that -the store will not check the number of messages but still check the other limits. +That is, in the configuration above, `baz` has the maximum number of messages set to 0, which means ignored or unlimited. Yet, other limits such as max bytes, max age and max subscriptions \(inherited in this case\) still apply. What that means is that the store will not check the number of messages but still check the other limits. -For a truly unlimited channel *all* limits need to be set to 0. +For a truly unlimited channel _all_ limits need to be set to 0. ## Limits Inheritance -When starting the server from the command line, global limits that are not specified -(configuration file or command line parameters) are inherited from default limits -selected by the server. +When starting the server from the command line, global limits that are not specified \(configuration file or command line parameters\) are inherited from default limits selected by the server. -Per-channel limits that are not explicitly configured inherit from the corresponding -global limit (which can itself be inherited from default limit). +Per-channel limits that are not explicitly configured inherit from the corresponding global limit \(which can itself be inherited from default limit\). -If a per-channel limit is set to 0 in the configuration file (or negative value -programmatically), then it becomes unlimited, regardless of the corresponding -global limit. +If a per-channel limit is set to 0 in the configuration file \(or negative value programmatically\), then it becomes unlimited, regardless of the corresponding global limit. -On startup the server displays the store limits. Notice the `*` at the right of a -limit to indicate that the limit was inherited from the default store limits. +On startup the server displays the store limits. Notice the `*` at the right of a limit to indicate that the limit was inherited from the default store limits. -For channels that have been configured, their name is displayed and only the -limits being specifically set are displayed to minimize the output. +For channels that have been configured, their name is displayed and only the limits being specifically set are displayed to minimize the output. ## Wildcards -Wildcards are allowed for channel configuration. Limits for `foo.>` -will apply to any channel that starts with `foo` (but has at least one more token). -If `foo.bar.>` is specified, it will inherit from `foo.>` and from global limits. +Wildcards are allowed for channel configuration. Limits for `foo.>` will apply to any channel that starts with `foo` \(but has at least one more token\). If `foo.bar.>` is specified, it will inherit from `foo.>` and from global limits. -Below is what would be displayed with the above store limits configuration. Notice -how `foo.bar.>` is indented compared to `foo.>` to show the inheritance. +Below is what would be displayed with the above store limits configuration. Notice how `foo.bar.>` is indented compared to `foo.>` to show the inheritance. -``` +```text [INF] STREAM: Starting nats-streaming-server[test-cluster] version 0.16.0 [INF] STREAM: ServerID: bFHdJP9hesjHIR0RheCl7W [INF] STREAM: Go version: go1.11.13 @@ -146,4 +128,5 @@ how `foo.bar.>` is indented compared to `foo.>` to show the inheritance. [INF] STREAM: |-> Messages 50 [INF] STREAM: |-> Bytes 1.00 KB [INF] STREAM: ----------------------------------- -``` \ No newline at end of file +``` + diff --git a/nats-streaming-server/configuring/storelimits/limits-inheritance.md b/nats-streaming-server/configuring/storelimits/limits-inheritance.md new file mode 100644 index 0000000..7eac902 --- /dev/null +++ b/nats-streaming-server/configuring/storelimits/limits-inheritance.md @@ -0,0 +1,2 @@ +# Limits inheritance + diff --git a/nats_streaming/configuring/tls.md b/nats-streaming-server/configuring/tls/README.md similarity index 80% rename from nats_streaming/configuring/tls.md rename to nats-streaming-server/configuring/tls/README.md index 54cdc30..2ef75cb 100644 --- a/nats_streaming/configuring/tls.md +++ b/nats-streaming-server/configuring/tls/README.md @@ -1,9 +1,8 @@ -# Securing NATS Streaming Server - +# Securing ## Authenticating Users -To enable user authentication from the command line, you can use the same mechanism as the NATS Server (`nats-server`). You pass in the `—user ` and `—pass ` commands, or `--auth` parameters, and the NATS streaming server will automatically use these credentials. Or you can use a configuration file with a single user or token. +To enable user authentication from the command line, you can use the same mechanism as the NATS Server \(`nats-server`\). You pass in the `—user ` and `—pass ` commands, or `--auth` parameters, and the NATS streaming server will automatically use these credentials. Or you can use a configuration file with a single user or token. When using a configuration file with multi-user authorization, you must use the `—user` and `—pass` parameters with the NATS streaming server, matching a user in the configuration file, in order to specify which user the NATS streaming server should authenticate with to it's embedded NATS server. @@ -17,7 +16,7 @@ That means two sets of TLS configuration parameters must be used: TLS server par The streaming server specifies it's TLS client certificates with the following three parameters: -```sh +```bash -tls_client_key Client key for the streaming server -tls_client_cert Client certificate for the streaming server -tls_client_cacert Client certificate CA for the streaming server @@ -27,44 +26,49 @@ These could be the same certificates used with your NATS streaming clients. The embedded NATS server specifies TLS server certificates with these: -```sh +```bash --tlscert Server certificate file --tlskey Private key for server certificate --tlscacert Client certificate CA for verification ``` -The server parameters are used the same way you'd [secure a typical NATS server](../../nats_server/tls.md). +The server parameters are used the same way you'd [secure a typical NATS server](../../../nats-server/configuration/securing_nats/tls.md). Proper usage of the NATS Streaming Server requires the use of both client and server parameters. For example: -```sh +```bash % nats-streaming-server -tls_client_cert client-cert.pem -tls_client_key client-key.pem -tls_client_cacert ca.pem -tlscert server-cert.pem -tlskey server-key.pem -tlscacert ca.pem ``` -Further TLS related functionality can be found in [Securing NATS > TLS](../../nats_server/tls.md). Note that if specifying cipher suites is required, a configuration file for the embedded NATS server can be passed through the `-config` command line parameter. +Further TLS related functionality can be found in [Securing NATS > TLS](../../../nats-server/configuration/securing_nats/tls.md). Note that if specifying cipher suites is required, a configuration file for the embedded NATS server can be passed through the `-config` command line parameter. ### Connecting to Remote NATS Server with TLS Enabled -If that is the case, it is not necessary to configure the server-side TLS parameters. You only need to specify the client-side parameters (`-tls_client_cert`, etc...). +If that is the case, it is not necessary to configure the server-side TLS parameters. You only need to specify the client-side parameters \(`-tls_client_cert`, etc...\). However, NATS Streaming Server uses the NATS Server command line parsing code and currently would not allow specifying the client-side parameters alone. The server would fail to start with a message similar to this: -```sh + +```bash $ nats-streaming-server -tls_ca_cert test/certs/ca.pem TLS Server certificate must be present and valid ``` The solution is to include the required client-side parameters in a configuration file, say `c.conf`: -``` + +```text streaming { tls { client_ca: "test/certs/ca.pem" } } ``` + And then start the server with this configuration file: -```sh + +```bash $ nats-streaming-server -c c.conf ``` + diff --git a/nats-streaming-server/configuring/tls/authenticating-users.md b/nats-streaming-server/configuring/tls/authenticating-users.md new file mode 100644 index 0000000..9df2db4 --- /dev/null +++ b/nats-streaming-server/configuring/tls/authenticating-users.md @@ -0,0 +1,2 @@ +# Authenticating Users + diff --git a/nats-streaming-server/configuring/tls/tls.md b/nats-streaming-server/configuring/tls/tls.md new file mode 100644 index 0000000..df03d05 --- /dev/null +++ b/nats-streaming-server/configuring/tls/tls.md @@ -0,0 +1,2 @@ +# TLS + diff --git a/developer/streaming/embedding.md b/nats-streaming-server/embedding.md similarity index 94% rename from developer/streaming/embedding.md rename to nats-streaming-server/embedding.md index 3ab441e..60087a7 100644 --- a/developer/streaming/embedding.md +++ b/nats-streaming-server/embedding.md @@ -1,16 +1,16 @@ -# Embedding NATS Streaming +# Embedding NATS Streaming Server Embedding a NATS Streaming Server in your own code is easy. Simply import: -``` +```text stand "github.com/nats-io/nats-streaming-server/server" ``` -(Note: we chose `stand` here, but you don't have to use that name) +\(Note: we chose `stand` here, but you don't have to use that name\) Then if you want to use default options, it is as simple as doing: -``` +```text s, err := stand.RunServer("mystreamingserver") ``` @@ -18,13 +18,13 @@ If you want a more advance configuration, then you need to pass options. For ins First import the stores package so we have access to the store type. -``` +```text stores "github.com/nats-io/nats-streaming-server/stores" ``` Then get the default options and override some of them: -``` +```text opts := stand.GetDefaultOptions() opts.StoreType = stores.TypeFile opts.FilestoreDir = "datastore" @@ -35,7 +35,7 @@ However, since the NATS Streaming Server project vendors NATS Server that is use If you were to import `github.com/nats-io/nats-server/server`, instantiate a NATS `Options` structure, configure it and pass it to the second argument of `RunServerWithOpts`, you would get a compiler error. For instance doing this does not work: -``` +```text import ( natsd "github.com/nats-io/nats-server/server" stand "github.com/nats-io/nats-streaming-server/server" @@ -52,13 +52,13 @@ import ( You would get: -``` +```text ./myapp.go:36:35: cannot use nopts (type *"myapp/vendor/github.com/nats-io/nats-server/server".Options) as type *"myapp/vendor/github.com/nats-io/nats-streaming-server/vendor/github.com/nats-io/gnatsd/server".Options in argument to "myapp/vendor/github.com/nats-io/nats-streaming-server/server".RunServerWithOpts ``` To workaround this issue, the NATS Streaming Server package provides a function `NewNATSOptions()` that is suitable for this approach: -``` +```text nopts := stand.NewNATSOptions() nopts.Port = 4223 @@ -69,7 +69,7 @@ That will work. But, if you want to do advanced NATS configuration that requires types or interfaces that belong to the NATS Server package, then this approach won't work. In this case, you need to run the NATS Server independently and have the NATS Streaming Server connect to it. -``` +```text // This configure the NATS Server using natsd package nopts := &natsd.Options{} nopts.HTTPPort = 8222 @@ -108,4 +108,5 @@ But, if you want to do advanced NATS configuration that requires types or interf } ``` -The above process may seem involved, but only if you use very advanced NATS Server options. \ No newline at end of file +The above process may seem involved, but only if you use very advanced NATS Server options. + diff --git a/nats_streaming/gettingstarted/install.md b/nats-streaming-server/install.md similarity index 94% rename from nats_streaming/gettingstarted/install.md rename to nats-streaming-server/install.md index 3cba2e6..e87ae5a 100644 --- a/nats_streaming/gettingstarted/install.md +++ b/nats-streaming-server/install.md @@ -1,8 +1,8 @@ -# NATS Streaming Server Installation +# Installing NATS philosophy is simplicity. -The best way to get the NATS Streaming Server is to use one of the pre-built release binaries which are available for OSX, Linux (x86-64/ARM), Windows. +The best way to get the NATS Streaming Server is to use one of the pre-built release binaries which are available for OSX, Linux \(x86-64/ARM\), Windows. Of course you can build the latest version of the server from the master branch. The master branch will always build and pass tests, but may not work correctly in your environment. First you will need at least Go version 1.11+ installed on your machine to build the NATS Streaming Server. @@ -11,12 +11,14 @@ Installation is just decompressing a zip file and copying the binary to an appro ## Installing via a Package Manager On Mac OS: -``` + +```text > brew install nats-streaming-server ``` Via Docker: -``` + +```text > docker pull nats-streaming ``` @@ -25,7 +27,8 @@ Via Docker: You can find the latest release of `nats-streaming-server` [here](https://github.com/nats-io/nats-streaming-server/releases/latest). Download the zip file matching your systems architecture, and unzip. For this example, assuming version 0.14.2 of the server, and a Linux AMD64: -``` + +```text > curl -L https://github.com/nats-io/nats-streaming-server/releases/download/v0.14.2/nats-streaming-server-v0.14.2-linux-amd64.zip -o nats-streaming-server.zip > unzip nats-streaming-server.zip -d tmp @@ -34,7 +37,7 @@ Archive: nats-streaming-server.zip inflating: tmp/nats-streaming-server-v0.14.2-linux-amd64/README.md inflating: tmp/nats-streaming-server-v0.14.2-linux-amd64/LICENSE inflating: tmp/nats-streaming-server-v0.14.2-linux-amd64/nats-streaming-server - + > cp tmp/nats-streaming-server-v0.14.2-linux-amd64/nats-streaming-server /usr/local/bin ``` @@ -42,27 +45,29 @@ Archive: nats-streaming-server.zip If you have go installed, installing the binary is easy: -``` +```text > go get github.com/nats-io/nats-streaming-server ``` This mechanism will install a build of master, which almost certainly will not be a released version. If you are a developer and want to play with the latest, this is the easiest way of obtaining it. You can run the test suite from the `nats-streaming-server` root directory: -``` -go test -v -p=1 ./... + +```text +go test -v -p=1 ./... ``` Some of the store tests require a SQL server to be running. To skip those, use this command instead: -``` + +```text go test -v -p=1 ./... -sql=false ``` ## Testing Your Installation -To test your installation (provided the executable is visible to your shell): +To test your installation \(provided the executable is visible to your shell\): -``` +```text > nats-streaming-server [58061] 2019/05/22 13:56:45.463562 [INF] STREAM: Starting nats-streaming-server[test-cluster] version 0.14.2 [58061] 2019/05/22 13:56:45.463639 [INF] STREAM: ServerID: Avb51sMf9imRPVVwv6Ts0v @@ -85,3 +90,4 @@ To test your installation (provided the executable is visible to your shell): [58061] 2019/05/22 13:56:45.749686 [INF] STREAM: Inactivity : unlimited * [58061] 2019/05/22 13:56:45.749690 [INF] STREAM: ---------------------------------- ``` + diff --git a/nats_streaming/gettingstarted/process-signaling.md b/nats-streaming-server/process-signaling.md similarity index 52% rename from nats_streaming/gettingstarted/process-signaling.md rename to nats-streaming-server/process-signaling.md index ef6237c..6cf2f50 100644 --- a/nats_streaming/gettingstarted/process-signaling.md +++ b/nats-streaming-server/process-signaling.md @@ -2,15 +2,15 @@ On Unix systems, the NATS Streaming Server responds to the following signals: -| Signal | Result | -| --------------- | ------------------------------------- | -| SIGKILL | Kills the process immediately | -| SIGINT, SIGTERM | Stops the server gracefully | -| SIGUSR1 | Reopens the log file for log rotation | +| Signal | Result | +| :--- | :--- | +| SIGKILL | Kills the process immediately | +| SIGINT, SIGTERM | Stops the server gracefully | +| SIGUSR1 | Reopens the log file for log rotation | The `nats-streaming-server` binary can be used to send these signals to run NATS Streaming Servers using the `-sl` flag: -```sh +```bash # Reopen log file for log rotation nats-streaming-server -sl reopen @@ -20,8 +20,9 @@ nats-streaming-server -sl quit If there are multiple `nats-streaming-server` processes running, specify a PID: -```sh +```bash nats-streaming-server -sl quit= ``` -See the [Windows Service](#windows-service) section for information on signaling the NATS Streaming Server on Windows. +See the [Windows Service](process-signaling.md#windows-service) section for information on signaling the NATS Streaming Server on Windows. + diff --git a/nats_streaming/gettingstarted/run.md b/nats-streaming-server/run.md similarity index 81% rename from nats_streaming/gettingstarted/run.md rename to nats-streaming-server/run.md index c24918b..644a51e 100644 --- a/nats_streaming/gettingstarted/run.md +++ b/nats-streaming-server/run.md @@ -1,11 +1,11 @@ -# Getting Started with NATS Streaming +# Running This tutorial demonstrates NATS Streaming using example [Go NATS Streaming clients](https://github.com/nats-io/stan.go.git). ## Prerequisites -- [Set up your Git environment](https://help.github.com/articles/set-up-git/). -- [Set up your Go environment](https://golang.org/doc/install). +* [Set up your Git environment](https://help.github.com/articles/set-up-git/). +* [Set up your Go environment](https://golang.org/doc/install). ## Setup @@ -13,8 +13,8 @@ Download and install the [NATS Streaming Server](https://github.com/nats-io/nats Clone the following repositories: -- NATS Streaming Server: `git clone https://github.com/nats-io/nats-streaming-server.git` -- NATS Streaming Client: `git clone https://github.com/nats-io/stan.go.git` +* NATS Streaming Server: `git clone https://github.com/nats-io/nats-streaming-server.git` +* NATS Streaming Client: `git clone https://github.com/nats-io/stan.go.git` ## Start the NATS Streaming Server @@ -24,14 +24,14 @@ Run the binary that you downloaded, for example: `$ ./nats-streaming-server` Or, run from source: -```sh +```bash > cd $GOPATH/src/github.com/nats-io/nats-streaming-server > go run nats-streaming-server.go ``` You should see the following, indicating that the NATS Streaming Server is running: -```sh +```bash > go run nats-streaming-server.go [59232] 2019/05/22 14:24:54.426344 [INF] STREAM: Starting nats-streaming-server[test-cluster] version 0.14.2 [59232] 2019/05/22 14:24:54.426423 [INF] STREAM: ServerID: 3fpvAuXHo3C66Rkd4rmfFX @@ -59,7 +59,7 @@ You should see the following, indicating that the NATS Streaming Server is runni Publish several messages. For each publication you should get a result. -```sh +```bash > cd $GOPATH/src/github.com/nats-io/stan.go/examples/stan-pub > go run main.go foo "msg one" Published [foo] : 'msg one' @@ -73,7 +73,7 @@ Published [foo] : 'msg three' Use the `--all` flag to receive all published messages. -```sh +```bash > cd $GOPATH/src/github.com/nats-io/stan.go/examples/stan-sub > go run main.go --all -c test-cluster -id myID foo Connected to nats://localhost:4222 clusterID: [test-cluster] clientID: [myID] @@ -86,11 +86,12 @@ Listening on [foo], clientID=[myID], qgroup=[] durable=[] ## Explore other subscription options -```sh - --seq Start at seqno - --all Deliver all available messages - --last Deliver starting with last published message - --since Deliver messages in last interval (e.g. 1s, 1hr, https://golang.org/pkg/time/#ParseDuration) - --durable Durable subscriber name - --unsubscribe Unsubscribe the durable on exit +```bash + --seq Start at seqno + --all Deliver all available messages + --last Deliver starting with last published message + --since Deliver messages in last interval (e.g. 1s, 1hr, https://golang.org/pkg/time/#ParseDuration) + --durable Durable subscriber name + --unsubscribe Unsubscribe the durable on exit ``` + diff --git a/nats_streaming/swarm.md b/nats-streaming-server/swarm.md similarity index 79% rename from nats_streaming/swarm.md rename to nats-streaming-server/swarm.md index da3b3d5..249d772 100644 --- a/nats_streaming/swarm.md +++ b/nats-streaming-server/swarm.md @@ -1,20 +1,18 @@ -# Using NATS Streaming with Docker Swarm +# Docker Swarm -#### Step 1: +## Step 1: -Create an overlay network for the NATS & NATS Streaming cluster (in this example, `nats-streaming-example`). -Notice we added the `--attachable` option which will allow other containers to join the network which will be -done at the end to confirm that can connect to the cluster. +Create an overlay network for the NATS & NATS Streaming cluster \(in this example, `nats-streaming-example`\). Notice we added the `--attachable` option which will allow other containers to join the network which will be done at the end to confirm that can connect to the cluster. -```sh +```bash % docker network create --driver overlay --attachable nats-streaming-example ``` -#### Step 2: +## Step 2: Next create the NATS cluster which will be used by the NATS Streaming cluster. -```sh +```bash for i in `seq 1 3`; do sudo docker service create --network nats-streaming-example \ --name nats-cluster-node-$i nats:1.1.0 \ @@ -23,11 +21,11 @@ for i in `seq 1 3`; do done ``` -#### Step 3: +## Step 3: Now that there is a NATS cluster available to connect, create the NATS Streaming cluster of three nodes as follows: -```sh +```bash for i in `seq 1 3`; do sudo docker service create --network nats-streaming-example \ --name nats-streaming-node-$i nats-streaming:0.9.2 \ @@ -37,14 +35,11 @@ for i in `seq 1 3`; do done ``` -#### Step 4: +## Step 4: -Next, confirm that it is possible to publish and replay messages via NATS Streaming by attaching a container -to the same network where both NATS and NATS Streaming exist. Below you can find an example session of doing so, -note that even though the client is only connecting to `nats://nats-cluster-node-1:4222` the NATS cluster will -be routing the messages so that they will be processed to the NATS Streaming cluster service. +Next, confirm that it is possible to publish and replay messages via NATS Streaming by attaching a container to the same network where both NATS and NATS Streaming exist. Below you can find an example session of doing so, note that even though the client is only connecting to `nats://nats-cluster-node-1:4222` the NATS cluster will be routing the messages so that they will be processed to the NATS Streaming cluster service. -```sh +```bash $ sudo docker run --network nats-streaming-example -it golang:latest root@d12f9f3fcdde:/go# cd src/github.com/nats-io/stan.go/ @@ -66,3 +61,4 @@ Listening on [hello], clientID=[17010], qgroup=[] durable=[] [#2] Received on [hello]: 'sequence:2 subject:"hello" data:"world" timestamp:1526948604613783399 ' [#3] Received on [hello]: 'sequence:3 subject:"hello" data:"world" timestamp:1526948606124258269 ' ``` + diff --git a/nats_streaming/gettingstarted/windows-service.md b/nats-streaming-server/windows-service.md similarity index 97% rename from nats_streaming/gettingstarted/windows-service.md rename to nats-streaming-server/windows-service.md index 62f3ff2..3c487ee 100644 --- a/nats_streaming/gettingstarted/windows-service.md +++ b/nats-streaming-server/windows-service.md @@ -3,26 +3,32 @@ The NATS Streaming Server supports running as a Windows service. There is currently no installer and instead users should use `sc.exe` to install the service. Here is how to create and start a NATS Streaming Server named `nats-streaming-server`. Note that the server flags should be passed in when creating the service. -```sh + +```bash sc.exe create nats-streaming-server binPath="\"\nats-streaming-server.exe\" [NATS Streaming flags]" sc.exe start nats-streaming-server ``` You can create several instances, giving it a unique name. For instance, this is how you would create two services, named `nss1` and `nss2`, each one with its own set of parameters. -``` + +```text sc.exe create nss1 binPath="\"c:\nats-io\nats-streaming\nats-streaming-server.exe\" --syslog --syslog_name=nss1 -p 4222" sc.exe create nss2 binPath="\"c:\nats-io\nats-streaming\nats-streaming-server.exe\" --syslog --syslog_name=nss2 -p 4223" ``` + By default, when no logfile is specified, the server will use the system log. The default event source name is `NATS-Streaming-Server`. However, you can specify the name you want, which is especially useful when installing more than one service as described above. Once the service is running, it can be controlled using `sc.exe` or `nats-streaming-server.exe -sl`: -```batch +```text REM Stop the server nats-streaming-server.exe -sl quit ``` + The above commands will default to controlling the service named `nats-streaming-server`. If the service has another name, it can be specified like this: -```batch + +```text nats-streaming-server.exe -sl quit= ``` + diff --git a/nats_tools/mkpasswd.md b/nats-tools/mkpasswd.md similarity index 83% rename from nats_tools/mkpasswd.md rename to nats-tools/mkpasswd.md index aa7a44a..8e6b2e9 100644 --- a/nats_tools/mkpasswd.md +++ b/nats-tools/mkpasswd.md @@ -1,28 +1,30 @@ -### `mkpasswd`: Protect Passwords with bcrypt +# mkpasswd The server supports hashing of passwords and authentication tokens using `bcrypt`. To take advantage of this, simply replace the plaintext password in the configuration with its `bcrypt` hash, and the server will automatically utilize `bcrypt` as needed. -A utility for creating `bcrypt` hashes is included with the nats-server distribution (`util/mkpasswd.go`). Running it with no arguments will generate a new secure password along with the associated hash. This can be used for a password or a token in the configuration. +A utility for creating `bcrypt` hashes is included with the nats-server distribution \(`util/mkpasswd.go`\). Running it with no arguments will generate a new secure password along with the associated hash. This can be used for a password or a token in the configuration. ## Installing `mkpasswd` If you have [go installed](https://golang.org/doc/install), you can easily install the `mkpasswd` tool by doing: -``` +```text > go get github.com/nats-server/util/mkpasswd ``` -Alternatively, you can: +Alternatively, you can: -``` +```text > git clone git@github.com:nats-io/nats-server > cd nats-server/util/mkpasswd > go install mkpasswd.go ``` ## Generating bcrypted passwords + With `mkpasswd` installed: -``` + +```text > mkpasswd pass: #IclkRPHUpsTmACWzmIGXr bcrypt hash: $2a$11$3kIDaCxw.Glsl1.u5nKa6eUnNDLV5HV9tIuUp7EHhMt6Nm9myW1aS @@ -30,7 +32,7 @@ bcrypt hash: $2a$11$3kIDaCxw.Glsl1.u5nKa6eUnNDLV5HV9tIuUp7EHhMt6Nm9myW1aS If you already have a password selected, you can supply the `-p` flag on the command line, enter your desired password, and a `bcrypt` hash will be generated for it: -``` +```text > mkpasswd -p Enter Password: ******* Reenter Password: ****** @@ -39,7 +41,7 @@ bcrypt hash: $2a$11$3kIDaCxw.Glsl1.u5nKa6eUnNDLV5HV9tIuUp7EHhMt6Nm9myW1aS To use the password on the server, add the hash into the server configuration file's authorization section. -``` +```text authorization { user: derek password: $2a$11$3kIDaCxw.Glsl1.u5nKa6eUnNDLV5HV9tIuUp7EHhMt6Nm9myW1aS @@ -47,3 +49,4 @@ To use the password on the server, add the hash into the server configuration fi ``` Note the client will still have to provide the plain text version of the password, the server however will only store the hash to verify that the password is correct when supplied. + diff --git a/nats_tools/nas/README.md b/nats-tools/nas/README.md similarity index 91% rename from nats_tools/nas/README.md rename to nats-tools/nas/README.md index 29084fd..ca0d63c 100644 --- a/nats_tools/nas/README.md +++ b/nats-tools/nas/README.md @@ -1,10 +1,10 @@ -## NATS Account Server +# nats-account-server The [NATS Account Server](https://github.com/nats-io/nats-account-server) is an HTTP server that hosts and vends JWTs for nats-server 2.0 account authentication. The server supports an number of stores which enable it to serve JWTs from: -- a directory -- an [NSC](../nsc/nsc.md) directory -- memory (for testing purposes) +* a directory +* an [NSC](../nsc/nsc.md) directory +* memory \(for testing purposes\) The server can operate in a _READ ONLY_ mode where it serves content from a directory, or in notification mode, where it can notify a NATS server that a JWT in the store has been modified, updating the NATS server with the updated JWT. @@ -12,8 +12,9 @@ The server supports replica mode, which allows load balancing, fault tolerance a The account server can host activation tokens as well as account JWTs. These tokens are used when one account needs to give permission to another account to access a private export. Tokens can be configured as full tokens, or URLs. By hosting them in the account server you can avoid the copy/paste process of embedding tokens. They can also be updated more easily on expiration. -### Memory Resolver +## Memory Resolver For very simple installations, where JWTs are mostly static, the NATS server also supports a _Memory Resolver_ that can be configured statically in the server's configuration file. You can learn more about how to configure the [memory resolver here](mem_resolver.md). + diff --git a/nats_tools/nas/dir_store.md b/nats-tools/nas/dir_store.md similarity index 91% rename from nats_tools/nas/dir_store.md rename to nats-tools/nas/dir_store.md index 0abdda1..c0ee83c 100644 --- a/nats_tools/nas/dir_store.md +++ b/nats-tools/nas/dir_store.md @@ -1,9 +1,8 @@ -## Directory Store +# Directory Store +## NATS Account Server Configuration -### NATS Account Server Configuration - -``` +```text OperatorJWTPath: "/users/synadia/.nsc/nats/AAA/AAA.jwt", http { port: 9090 @@ -19,7 +18,7 @@ The server configuration specifies the `OperatorJWTPath` which is used to valida Starting the server: -``` +```text > nats-account-server -c nas.conf 2019/05/31 12:35:23.430128 [INF] loading configuration from "/Users/synadia/Desktop/nats_jwt_doc/as_dir/nas.conf" 2019/05/31 12:35:23.430417 [INF] starting NATS Account server, version 0.0-dev @@ -33,15 +32,15 @@ Starting the server: 2019/05/31 12:35:23.437966 [INF] resolver: URL(http://localhost:9090/jwt/v1/accounts/) ``` -On a new store, the server doesn't have any JWTs. This means that any nats-server that attempts to resolve accounts will fail. To add JWTs to the server, you can use a tool like [`curl` to post request](#add/using-curl-to-add-or-update-accounts). But it is much easier if you use `nsc` to update the nats-account-server. +On a new store, the server doesn't have any JWTs. This means that any nats-server that attempts to resolve accounts will fail. To add JWTs to the server, you can use a tool like [`curl` to post request](dir_store.md#add/using-curl-to-add-or-update-accounts). But it is much easier if you use `nsc` to update the nats-account-server. -### Using NSC to And or Update Accounts +## Using NSC to And or Update Accounts The `nsc` tool has built-in facilities to `push` JWTs related to an operator. The tool also performs validation of your JWTs to ensure that you push JWTs that will validate correctly. If your operator doesn't have any entities, now it is a good time to add some: -``` +```text > nsc add account -n A Generated account key - private key stored "~/.nkeys/AAA/accounts/A/A.nk" Success! - added account "A" @@ -63,23 +62,25 @@ Success! - added account "B" With the account and a couple of users in place, let's push all the accounts to the nats-account-server: -``` +```text > nsc push -A successfully pushed all accounts [A,B] ``` Quick checking of the store directory, shows that the JWTs have been sharded by their public keys: -``` + +```text > tree as_store as_store ├── 27 -│   └── ACVEO3LPVRGE5W262FCYF3OMGQFJIW252AX75FEE6BUY752BFVDADN27.jwt +│ └── ACVEO3LPVRGE5W262FCYF3OMGQFJIW252AX75FEE6BUY752BFVDADN27.jwt └── TY └── ADDVBX4VPWSNEDLWH5Y6ITASMXS3QY3L6KRNZ6VIQJ6Q3FRGR43NFHTY.jwt ``` Quick check on nsc to verify the ids of the accounts on nsc, match the files: -``` + +```text > nsc list accounts -W ╭─────────────────────────────────────────────────────────────────╮ │ Accounts │ @@ -91,12 +92,11 @@ Quick check on nsc to verify the ids of the accounts on nsc, match the files: ╰──────┴──────────────────────────────────────────────────────────╯ ``` +## Using Curl to Add or Update Accounts - -### Using Curl to Add or Update Accounts - -``` +```text > curl -i -X POST localhost:9090/jwt/v1/accounts/AC7PO3MREV26U3LFZFP5BN3HAI32X3PKLBRVMPAETLEHWPQEUG7EJY4H --data-binary @/Users/synadia/.nsc/nats/Test/accounts/TestAccount/TestAccount.jwt -H "Content-Type: text/text" ``` -Note that the `@` before the file name is required for `curl` to read the specified file, and use it as the payload. Otherwise, it will simply post the path specified, which will result in an update error. \ No newline at end of file +Note that the `@` before the file name is required for `curl` to read the specified file, and use it as the payload. Otherwise, it will simply post the path specified, which will result in an update error. + diff --git a/nats_tools/nas/inspecting_jwts.md b/nats-tools/nas/inspecting_jwts.md similarity index 68% rename from nats_tools/nas/inspecting_jwts.md rename to nats-tools/nas/inspecting_jwts.md index 3294e4d..00aad8a 100644 --- a/nats_tools/nas/inspecting_jwts.md +++ b/nats-tools/nas/inspecting_jwts.md @@ -1,12 +1,10 @@ -## Inspecting a JWT from the `nats-account-server` +# Inspecting JWTs Let’s say that you know the account for a stream that you are interested in, but you don't know all the details for creating an import. If you know and have access to a nats-account-server, you can help yourself. The nats-account-server can decode a JWT and give you human readable values that you can use. -The endpoint for retrieving an account JWT is: -`/jwt/v1/accounts/`. To decode a JWT add the query string `?decode=true`. +The endpoint for retrieving an account JWT is: `/jwt/v1/accounts/`. To decode a JWT add the query string `?decode=true`. - -```json +```javascript > curl http://localhost:9090/jwt/v1/accounts/AC7PO3MREV26U3LFZFP5BN3HAI32X3PKLBRVMPAETLEHWPQEUG7EJY4H\?decode=true { "typ": "jwt", @@ -29,12 +27,13 @@ The endpoint for retrieving an account JWT is: ], … ``` + As you can see from above, the JWT is decoded. The standard JWT claim field abbreviated names may be a little terse, so here's a list of the more important ones: -- `jti` is the _JWT ID_. All JWTs have one and they are unique. -- `iat` is _Issued At_ - the UNIX date (number of seconds since 1970) when the JWT was issued. -- `iss` is the _Issuer_. For NATS JWTs it is the public key of the issuer. In the example above the entity is an account, so the issuer will be an operator. Thus the id will always start with the letter `O`. -- `sub` is the _Subject_ of the claim. In NATS JWTs it is the public key of the entity of the claim is for. In the example above, it is an Account, so the issuer will always start with the letter `A`. +* `jti` is the _JWT ID_. All JWTs have one and they are unique. +* `iat` is _Issued At_ - the UNIX date \(number of seconds since 1970\) when the JWT was issued. +* `iss` is the _Issuer_. For NATS JWTs it is the public key of the issuer. In the example above the entity is an account, so the issuer will be an operator. Thus the id will always start with the letter `O`. +* `sub` is the _Subject_ of the claim. In NATS JWTs it is the public key of the entity of the claim is for. In the example above, it is an Account, so the issuer will always start with the letter `A`. +On the example above, we see that there is one export in this account, it is public \(`token_req` is `false` or not set\), and it is a `stream`. So this account exports a public stream. With that information you can create an import on the public stream. -On the example above, we see that there is one export in this account, it is public (`token_req` is `false` or not set), and it is a `stream`. So this account exports a public stream. With that information you can create an import on the public stream. \ No newline at end of file diff --git a/nats_tools/nas/mem_resolver.md b/nats-tools/nas/mem_resolver.md similarity index 89% rename from nats_tools/nas/mem_resolver.md rename to nats-tools/nas/mem_resolver.md index 17dd682..1fdd678 100644 --- a/nats_tools/nas/mem_resolver.md +++ b/nats-tools/nas/mem_resolver.md @@ -1,15 +1,14 @@ -## Memory Resolver +# Memory Resolver The `MEMORY` resolver is a built-in resolver for JWTs. It is mostly used by test setups but can be used to test the simplest of environments where there is one or very few accounts, and the account JWTs don't change often. The basic configuration for the server requires: -- The operator JWT -- `resolver` set to `MEMORY` -- `resolver_preload` set to an object where account public keys are mapped to account JWTs. +* The operator JWT +* `resolver` set to `MEMORY` +* `resolver_preload` set to an object where account public keys are mapped to account JWTs. - -### Create Required Entities +## Create Required Entities Let's create the setup: @@ -51,37 +50,36 @@ Generated user creds file "~/.nkeys/memory/accounts/A/users/TA.creds" Success! - added user "TA" to "A" ``` -### Create the Server Config +## Create the Server Config The `nsc` tool can generate a configuration file automatically. You provide a path to the server configuration and operator jwt. The `nsc` tool will copy the operator JWT to the file specified, and generate the server config for you: -``` +```text > nsc generate config --mem-resolver --config-file /tmp/server.conf --operator-jwt /tmp/memory.jwt Success!! - generated "/tmp/server.conf" generated "/tmp/memory.jwt" ``` -If you require additional settings, you may want to consider using [`include`](/nats_server/configuration.md#include-directive) in your main configuration, to reference the generated files. Otherwise, you can start a server and reference the generated configuration: +If you require additional settings, you may want to consider using [`include`](../../nats-server/configuration/#include-directive) in your main configuration, to reference the generated files. Otherwise, you can start a server and reference the generated configuration: -``` +```text > nats-server -c /tmp/server.conf ``` -You can then [test it](#testing-the-configuration). +You can then [test it](mem_resolver.md#testing-the-configuration). - -### Manual Server Config +## Manual Server Config While generating a configuration file is easy, you may want to craft one by hand to know the details. With the entities created, and a standard location for the `.nsc` directory. You can reference the operator JWT and the account JWT in a server configuration. Remember that your configuration will be in `$NSC_HOME/nats//.jwt` for the operator. The account JWT will be in `$NSC_HOME/nats//accounts//.jwt` For the configuration you'll need: -- The path to the operator JWT -- A copy of the contents of the account JWT file +* The path to the operator JWT +* A copy of the contents of the account JWT file The format of the file is: -``` +```text operator: resolver: MEMORY resolver_preload: { @@ -102,13 +100,14 @@ ACSU3Q6LTLBVLGAQUONAGXJHVNWGSKKAUA7IY5TB4Z7PLEKSR5O6JTGR: eyJ0eXAiOiJqd3QiLCJhbG ``` Save the config at server.conf and start the server: + ```text > nats-server -c server.conf ``` -You can then [test it](#testing-the-configuration). +You can then [test it](mem_resolver.md#testing-the-configuration). -### Testing the Configuration +## Testing the Configuration To test the configuration, simply use one of the standard tools: @@ -116,3 +115,4 @@ To test the configuration, simply use one of the standard tools: > nats-pub -creds ~/.nkeys/memory/accounts/A/users/TA.creds hello world Published [hello] : 'world' ``` + diff --git a/nats_tools/nas/nas_conf.md b/nats-tools/nas/nas_conf.md similarity index 90% rename from nats_tools/nas/nas_conf.md rename to nats-tools/nas/nas_conf.md index e9953f5..8c13ff2 100644 --- a/nats_tools/nas/nas_conf.md +++ b/nats-tools/nas/nas_conf.md @@ -1,20 +1,19 @@ -## Configuration +# Basics Basic configuration revolves around 4 settings: -- The store to read JWTs from -- The HTTP/S configuration -- NATS (for cases where updates are enabled) -- Logging +* The store to read JWTs from +* The HTTP/S configuration +* NATS \(for cases where updates are enabled\) +* Logging For complete information on please refer to the project's [Github](https://github.com/nats-io/nats-account-server). - -### `nsc` Configuration +## `nsc` Configuration For a basic usage of the server you can specify the `-nsc` flag, and specify the path to an operator in your environment. -> If you have not yet created an operator or accounts, you'll need to do so before continuing. See [NSC](../nsc/README.md) +> If you have not yet created an operator or accounts, you'll need to do so before continuing. See [NSC](../nsc/) You can easily locate the path by running `nsc env` to print your `nsc` settings: @@ -64,11 +63,11 @@ operator: /Users/synadia/.nsc/nats/Test/Test.jwt resolver: URL(http://localhost:9090/jwt/v1/accounts/) ``` -Note that servers you create with the `-nsc` option (or store option) are read-only. This means that the server will not accept POST requests to update the JWT store. +Note that servers you create with the `-nsc` option \(or store option\) are read-only. This means that the server will not accept POST requests to update the JWT store. -### Directory Configuration +## Directory Configuration -You can start a server using a plain directory. In this case you'll be responsible for adding any JWT that you want resolved. +You can start a server using a plain directory. In this case you'll be responsible for adding any JWT that you want resolved. > The server looks for account JWTs by using the public key of the account as the file name followed by the extension `.jwt`. The server will not introspect the JWTs, so if you don't name the files correctly, it will fail to find them or serve a JWT that doesn't match the requested account. @@ -92,69 +91,68 @@ operator: /Users/synadia/.nsc/nats/Test/Test.jwt resolver: URL(http://localhost:9090/jwt/v1/accounts/) ``` -### Configuration File +## Configuration File While the `-nsc` and `-dir` store flags are sufficient for some very simple developer setups, any production or non-read-only server will require a configuration file. Let's take a look at the configuration options: -#### Configuration Options +### Configuration Options | Option | Description | -| :- | :- | +| :--- | :--- | | `http` | An `http` configuration block specifying HTTP options. | | `logging` | A `logging` configuration block specifying server logging options. | | `nats` | A `nats` configuration block specifying NATS connection information for the account server to push JWT changes to a NATS server. | -| `operatorjwtpath` | The path to an operator JWT. Required for non-read-only servers. Only JWTs signed by the operator (or one of it's signing keys) are accepted. | +| `operatorjwtpath` | The path to an operator JWT. Required for non-read-only servers. Only JWTs signed by the operator \(or one of it's signing keys\) are accepted. | | `store` | A `store` configuration block specifying store options. | | `systemaccountjwtpath` | Path to an Account JWT that should be returned as the system account. | | `primary` | URL for the primary, `protocol://host:port`. | | `replicationtimeout` | Timeout, in milliseconds, used by the replica when talking to the primary, defaults to `5000`. | -#### `store` Configuration +### `store` Configuration | Option | Description | -| :- | :- | +| :--- | :--- | | `dir` | Configures a directory as a store. | | `nsc` | Configures an nsc read-only store. The value should be the path to an operator _directory_. Option is mutually exlusive with `dir`. | | `readonly` | If `true`, the store will not accept POST requests. Note that to receive requests, the store must also have `operatorjwtpath` specified as a root option. | | `shard` | If `true`, JWTs are sharded in the store directory. | - - -### `logging` Options +## `logging` Options | Option | Description | -| :- | :- | +| :--- | :--- | | `time` | If `true`, a timestamp is added to log messages. | | `debug` | If `true`, debug messages are logged. | | `trace` | If `true`, trace messages are logged. | | `colors` | If `true`, messages are logged using ANSI color escape sequences. | | `pid` | If `true`, the process id for the server is added to log messages. | -### `http` Options +## `http` Options | Option | Description | -| :- | :- | +| :--- | :--- | | `host` | Interface to listen for requests on. | | `port` | Port to listen for requests on. | | `readtimeout` | Max amount of time in milliseconds to wait for a http read operation to complete. | | `writetimeout` | Max amount of time in milliseconds to wait for a http write operation to complete. | - -### `nats` Options +## `nats` Options | Option | Description | -| :- | :- | +| :--- | :--- | | `servers` | List of NATS servers for the account server to use when connecting to a NATS server to publish updates. | | `connecttimeout` | Max amount of time in milliseconds to wait for a NATS connection. | | `reconnecttimewait` | Amount of time in milliseconds to between NATS server reconnect attempts. | | `tls` | A `tls` configuration block. | | `usercredentials` | A credentials _creds_ file for connecting to the NATS server. Account must be a member of a system account. | -### `tls` Options +## `tls` Options + | Option | Description | -| :- | :- | +| :--- | :--- | | `root` | filepath to the CA certificate. | | `cert` | filepath to the certificate. | | `cert` | filepath to the certificate key. | + diff --git a/nats_tools/nas/notifications.md b/nats-tools/nas/notifications.md similarity index 85% rename from nats_tools/nas/notifications.md rename to nats-tools/nas/notifications.md index 1286446..0d41727 100644 --- a/nats_tools/nas/notifications.md +++ b/nats-tools/nas/notifications.md @@ -1,11 +1,12 @@ -## Store Notifications +# Update Notifications The `nats-account-server` can notify a nats-server about JWT updates, enabling the NATS server to update itself to the newly updated JWT. -To push notifications, the nats-account-server makes use of [system accounts](/sys_accounts/README.md). +To push notifications, the nats-account-server makes use of [system accounts](../../nats-server/nats_admin/sys_accounts/). Here's a nats-account-server configuration with updates enabled: -``` + +```text operatorjwtpath: "/users/synadia/.nsc/nats/AAA/AAA.jwt", systemaccountjwtpath: "/users/synadia/.nsc/nats/AAA/accounts/SYS/SYS.jwt" http { @@ -24,20 +25,21 @@ nats { The above configuration: -- Sets the `operatorjwtpath` to verify pushed JWTs are signed by the operator -- Sets the `systemaccountjwtpath` so that the `nats-server` can ask for the system account (which the nats-account-server will trigger when it connects to the nats-server) +* Sets the `operatorjwtpath` to verify pushed JWTs are signed by the operator +* Sets the `systemaccountjwtpath` so that the `nats-server` can ask for the system account \(which the nats-account-server will trigger when it connects to the nats-server\) The `nats` section: -- Sets the `servers` with a list of NATS urls -- Sets `usercredentials` to the credentials file for the system account user that issues notifications. + +* Sets the `servers` with a list of NATS urls +* Sets `usercredentials` to the credentials file for the system account user that issues notifications. When the account server starts: -- It makes a connection to the NATS server using the `usercredentials` of the system account. +* It makes a connection to the NATS server using the `usercredentials` of the system account. The NATS server configuration looks like: -``` +```text operator: /users/synadia/.nsc/nats/AAA/AAA.jwt resolver: URL(http://localhost:9090/jwt/v1/accounts/) system_account: AAUR7CJU5WTR2RROXOJJFTJFJQPZ6B4VF2NOX6OQ6SQMPIKLQYQ7T37U @@ -45,20 +47,19 @@ system_account: AAUR7CJU5WTR2RROXOJJFTJFJQPZ6B4VF2NOX6OQ6SQMPIKLQYQ7T37U It specifies: -- The `operator` JWT -- The `resolver` URL where the nats-account-server will create requests. Note the nats-account-server log prints the exact value you should provide for this setting: +* The `operator` JWT +* The `resolver` URL where the nats-account-server will create requests. Note the nats-account-server log prints the exact value you should provide for this setting: -``` +```text ... 2019/05/31 16:47:50.519361 [INF] configure the nats-server with: 2019/05/31 16:47:50.519368 [INF] resolver: URL(http://localhost:9090/jwt/v1/accounts/) ... ``` - The nats-account-server has to be running before that nats-server starts, as currently, the nats-server will verify that it can connect to the resolver on startup. -``` +```text > nats-account-server -c nas_not.conf 2019/05/31 18:00:26.327583 [INF] loading configuration from "/Users/synadia/Desktop/nats_jwt_doc/as_dir/nas_not.conf" 2019/05/31 18:00:26.327833 [INF] starting NATS Account server, version 0.0-dev @@ -80,7 +81,7 @@ The nats-account-server has to be running before that nats-server starts, as cur Then start the NATS server: -``` +```text > nats-server -c /tmp/server.conf [57440] 2019/05/31 18:01:29.940149 [INF] Starting nats-server version 1.4.1 [57440] 2019/05/31 18:01:29.940234 [INF] Git commit [not set] @@ -90,15 +91,16 @@ Then start the NATS server: At this point, you have both servers running. You can submit updates to the nats-account-server using `nsc`: -``` +```text > nsc push -A successfully pushed all accounts [A, B, SYS] ``` The account server should show the updates in its log: -``` +```text 2019/05/31 18:02:29.702044 [INF] updated JWT for account - ACVEO3LPVRGE - GSO7ZQPXXNTBBEEGXFFLFXZLCGOA5ABUOADZBPASYGCDIEJ6QQPQ 2019/05/31 18:02:29.702988 [INF] updated JWT for account - ADDVBX4VPWSN - VPBI4OHVJ7ITKX6S2RWHHJ3BB6JFZ7NPJN33JH6L752T2YI2QJKA 2019/05/31 18:02:29.703745 [INF] updated JWT for account - AAUR7CJU5WTR - NHEPTVMURCQEURAWHX6LUUMO4KCQUAP4JCLIQANP3JTNPMG3IFWQ ``` + diff --git a/nats_tools/nats_top/README.md b/nats-tools/nats_top/README.md similarity index 84% rename from nats_tools/nats_top/README.md rename to nats-tools/nats_top/README.md index 2809a23..21067f6 100644 --- a/nats_tools/nats_top/README.md +++ b/nats-tools/nats_top/README.md @@ -1,10 +1,12 @@ +# nats-top + ## NATS TOP [nats-top](https://github.com/nats-io/nats-top) is a [top](http://man7.org/linux/man-pages/man1/top.1.html)-like tool for monitoring nats-server servers. The nats-top tool provides a dynamic real-time view of a NATS server. nats-top can display a variety of system summary information about the NATS server, such as subscription, pending bytes, number of messages, and more, in real time. For example: -```sh +```bash nats-top nats-server version 0.6.4 (uptime: 31m42s) @@ -25,7 +27,7 @@ Connections: 4 nats-top can be installed using `go get`. For example: -```sh +```bash go get github.com/nats-io/nats-top ``` @@ -35,7 +37,7 @@ NOTE: You may have to run the above command as user `sudo` depending on your set Once installed, nats-top can be run with the command `nats-top` and optional arguments. -```sh +```bash nats-top [-s server] [-m monitor] [-n num_connections] [-d delay_in_secs] [-sort by] ``` @@ -43,12 +45,12 @@ nats-top [-s server] [-m monitor] [-n num_connections] [-d delay_in_secs] [-sort Optional arguments inclde the following: -| Option | Description | -|-----------------------|-----------------------------------------------| -| `-m monitor` | Monitoring http port from nats-server. | -| `-n num_connections` | Limit the connections requested to the server (default 1024). | -| `-d delay_in_secs` | Screen refresh interval (default 1 second). | -| `-sort by` | Field to use for sorting the connections (see below). | +| Option | Description | +| :--- | :--- | +| `-m monitor` | Monitoring http port from nats-server. | +| `-n num_connections` | Limit the connections requested to the server \(default 1024\). | +| `-d delay_in_secs` | Screen refresh interval \(default 1 second\). | +| `-sort by` | Field to use for sorting the connections \(see below\). | ## Commands @@ -78,4 +80,5 @@ Use the `q` command to quit nats-top. ### Tutorial -For a walkthrough with `nats-top` check out the [tutorial](tutorial.md). \ No newline at end of file +For a walkthrough with `nats-top` check out the [tutorial](https://github.com/nats-io/nats.docs/tree/51fc56e3090645f7cedb242415e2d5361e1807e7/nats_tools/nats_top/tutorial.md). + diff --git a/nats_tools/nats_top/nats-top-tutorial.md b/nats-tools/nats_top/nats-top-tutorial.md similarity index 84% rename from nats_tools/nats_top/nats-top-tutorial.md rename to nats-tools/nats_top/nats-top-tutorial.md index b5ac7ef..2ed8645 100644 --- a/nats_tools/nats_top/nats-top-tutorial.md +++ b/nats-tools/nats_top/nats-top-tutorial.md @@ -1,39 +1,39 @@ -## NATS TOP Tutorial +# Tutorial You can use [nats-top](https://github.com/nats-io/nats-top) to monitor in realtime NATS server connections and message statistics. -#### Prerequisites +## Prerequisites -- [Set up your Go environment](https://golang.org/doc/install) -- [Installed the NATS server](/nats_server/installation.md) +* [Set up your Go environment](https://golang.org/doc/install) +* [Installed the NATS server](../../nats-server/installation.md) -#### 1. Install nats-top +## 1. Install nats-top -```sh +```bash % go get github.com/nats-io/nats-top ``` You may need to run the following instead: -```sh +```bash % sudo -E go get github.com/nats-io/nats-top ``` -#### 2. Start the NATS server with monitoring enabled +## 2. Start the NATS server with monitoring enabled -```sh +```bash % nats-server -m 8222 ``` -#### 3. Start nats-top +## 3. Start nats-top -```sh +```bash % nats-top ``` Result: -```sh +```bash nats-server version 0.6.6 (uptime: 2m2s) Server: Load: CPU: 0.0% Memory: 6.3M Slow Consumers: 0 @@ -44,15 +44,15 @@ Connections: 0 HOST CID SUBS PENDING MSGS_TO MSGS_FROM BYTES_TO BYTES_FROM LANG VERSION ``` -#### 4. Run NATS client programs +## 4. Run NATS client programs Run some NATS client programs and exchange messages. -For the best experience, you will want to run multiple subscribers, at least 2 or 3. Refer to the [example pub-sub clients](/nats_server/clients.md). +For the best experience, you will want to run multiple subscribers, at least 2 or 3. Refer to the [example pub-sub clients](../../nats-server/clients.md). -#### 5. Check nats-top for statistics +## 5. Check nats-top for statistics -```sh +```bash nats-server version 0.6.6 (uptime: 30m51s) Server: Load: CPU: 0.0% Memory: 10.3M Slow Consumers: 0 @@ -66,11 +66,11 @@ Connections: 3 ::1:58953 39 1 0 21 0 105 0 go 1.1.0 ``` -#### 6. Sort nats-top statistics +## 6. Sort nats-top statistics -In nats-top, enter the command `o` followed by the option, such as `bytes_to`. You see that nats-top sorts the BYTES_TO column in ascending order. +In nats-top, enter the command `o` followed by the option, such as `bytes_to`. You see that nats-top sorts the BYTES\_TO column in ascending order. -```sh +```bash nats-server version 0.6.6 (uptime: 45m40s) Server: Load: CPU: 0.0% Memory: 10.4M Slow Consumers: 0 @@ -84,7 +84,7 @@ Connections: 3 ::1:59342 90 1 0 0 0 0 0 go 1.1.0 ``` -#### 7. Use different sort options +## 7. Use different sort options Use some different sort options to explore nats-top, such as: @@ -92,11 +92,11 @@ Use some different sort options to explore nats-top, such as: You can also set the sort option on the command line using the `-sort` flag. For example: `nats-top -sort bytes_to`. -#### 8. Display the registered subscriptions. +## 8. Display the registered subscriptions. In nats-top, enter the command `s` to toggle displaying connection subscriptions. When enabled, you see the subscription subject in nats-top table: -```sh +```bash nats-server version 0.6.6 (uptime: 1h2m23s) Server: Load: CPU: 0.0% Memory: 10.4M Slow Consumers: 0 @@ -110,21 +110,21 @@ Connections: 3 ::1:59817 124 1 0 0 0 0 0 go 1.1.0 foo ``` -#### 9. Quit nats-top +## 9. Quit nats-top Use the `q` command to quit nats-top. -#### 10. Restart nats-top with a specified query +## 10. Restart nats-top with a specified query For example, to query for the connection with largest number of subscriptions: -```sh +```bash % nats-top -n 1 -sort subs ``` Result: nats-top displays only the client connection with the largest number of subscriptions: -```sh +```bash nats-server version 0.6.6 (uptime: 1h7m0s) Server: Load: CPU: 0.0% Memory: 10.4M Slow Consumers: 0 @@ -135,3 +135,4 @@ Connections: 3 HOST CID SUBS PENDING MSGS_TO MSGS_FROM BYTES_TO BYTES_FROM LANG VERSION ::1:59708 115 1 0 6 0 48 0 go 1.1.0 ``` + diff --git a/nats_tools/natsbench.md b/nats-tools/natsbench.md similarity index 85% rename from nats_tools/natsbench.md rename to nats-tools/natsbench.md index 3944323..f53591a 100644 --- a/nats_tools/natsbench.md +++ b/nats-tools/natsbench.md @@ -1,111 +1,111 @@ -## Benchmarking +# nats-bench NATS is fast and lightweight and places a priority on performance. NATS provides tools for measuring performance. In this tutorial you learn how to benchmark and tune NATS on your systems and environment. -#### Prerequisites +## Prerequisites -- [Set up your Go environment](https://golang.org/doc/install) -- [Install the NATS server](/nats_server/installation.md) +* [Set up your Go environment](https://golang.org/doc/install) +* [Install the NATS server](../nats-server/installation.md) -#### Start the NATS server with monitoring enabled +## Start the NATS server with monitoring enabled -```sh +```bash % nats-server -m 8222 ``` Verify that the NATS server starts successfully, as well as the HTTP monitor: -```sh +```bash [18541] 2016/10/31 13:26:32.037819 [INF] Starting nats-server version 0.9.4 [18541] 2016/10/31 13:26:32.037912 [INF] Starting http monitor on 0.0.0.0:8222 [18541] 2016/10/31 13:26:32.037997 [INF] Listening for client connections on 0.0.0.0:4222 [18541] 2016/10/31 13:26:32.038020 [INF] Server is ready ``` -#### Installing and running the benchmark utility +## Installing and running the benchmark utility -The NATS benchmark can be installed and run via Go. Ensure your golang environment is setup. +The NATS benchmark can be installed and run via Go. Ensure your golang environment is setup. There are two approaches; you can either install the `nats-bench` utility in the directory specified in your `GOBIN` environment variable: -```sh +```bash % go install $GOPATH/src/github.com/nats-io/nats.go/examples/nats-bench/main.go ``` ... or you can simply run it via `go run`: -```sh +```bash % go run $GOPATH/src/github.com/nats-io/nats.go/examples/nats-bench/main.go ``` -*On windows use the % environment variable syntax, replacing `$GOPATH` with `%GOPATH%`.* +_On windows use the % environment variable syntax, replacing `$GOPATH` with `%GOPATH%`._ For the purpose of this tutorial, we'll assume that you chose the first option, and that you've added the `GOBIN` environment variable to your `PATH`. The `nats-bench` utility is straightforward to use. The options are as follows: -```sh +```bash % nats-bench -h Usage: nats-bench [-s server (nats://localhost:4222)] [--tls] [-np NUM_PUBLISHERS] [-ns NUM_SUBSCRIBERS] [-n NUM_MSGS] [-ms MESSAGE_SIZE] [-csv csvfile] ``` The options are self-explanatory. Each publisher or subscriber runs in its own go routine with its own NATS connection. -#### Run a publisher throughput test +## Run a publisher throughput test Let's run a test to see how fast a single publisher can publish one million 16 byte messages to the NATS server. -```sh +```bash % nats-bench -np 1 -n 100000 -ms 16 foo ``` The output tells you the number of messages and the number of payload bytes that the client was able to publish per second: -```sh +```bash Starting benchmark [msgs=100000, msgsize=16, pubs=1, subs=0] Pub stats: 7,055,644 msgs/sec ~ 107.66 MB/sec ``` Now increase the number of messages published: -```sh +```bash % nats-bench -np 1 -n 10000000 -ms 16 foo Starting benchmark [msgs=10000000, msgsize=16, pubs=1, subs=0] Pub stats: 7,671,570 msgs/sec ~ 117.06 MB/sec ``` -#### Run a publish/subscribe throughput test +## Run a publish/subscribe throughput test When using both publishers and subscribers, `nats-bench` reports aggregate, as well as individual publish and subscribe throughput performance. Let's look at throughput for a single publisher with a single subscriber: -```sh +```bash % nats-bench -np 1 -ns 1 -n 100000 -ms 16 foo ``` Note that the output shows the aggregate throughput as well as the individual publisher and subscriber performance: -```sh +```bash Starting benchmark [msgs=100000, msgsize=16, pubs=1, subs=1] NATS Pub/Sub stats: 2,009,230 msgs/sec ~ 30.66 MB/sec Pub stats: 1,076,537 msgs/sec ~ 16.43 MB/sec Sub stats: 1,004,615 msgs/sec ~ 15.33 MB/sec - ``` +``` -#### Run a 1:N throughput test +## Run a 1:N throughput test When specifying multiple publishers, or multiple subscribers, `nats-bench` will also report statistics for each publisher and subscriber individually, along with min/max/avg and standard deviation. Let's increase both the number of messages, and the number of subscribers.: -```sh +```bash % nats-bench -np 1 -ns 5 -n 10000000 -ms 16 foo ``` Output: -```sh +```bash Starting benchmark [msgs=10000000, msgsize=16, pubs=1, subs=5] NATS Pub/Sub stats: 5,730,851 msgs/sec ~ 87.45 MB/sec Pub stats: 955,279 msgs/sec ~ 14.58 MB/sec @@ -118,19 +118,19 @@ NATS Pub/Sub stats: 5,730,851 msgs/sec ~ 87.45 MB/sec min 955,150 | avg 955,154 | max 955,157 | stddev 2 msgs ``` -#### Run a N:M throughput test +## Run a N:M throughput test -When more than 1 publisher is specified, `nats-bench` evenly distributes the total number of messages (`-n`) across the number of publishers (`-np`). +When more than 1 publisher is specified, `nats-bench` evenly distributes the total number of messages \(`-n`\) across the number of publishers \(`-np`\). Now let's increase the number of publishers and examine the output: -```sh +```bash % nats-bench -np 5 -ns 5 -n 10000000 -ms 16 foo ``` The output: -```sh +```bash Starting benchmark [msgs=10000000, msgsize=16, pubs=5, subs=5] NATS Pub/Sub stats: 6,716,465 msgs/sec ~ 102.49 MB/sec Pub stats: 1,119,653 msgs/sec ~ 17.08 MB/sec @@ -147,4 +147,5 @@ NATS Pub/Sub stats: 6,716,465 msgs/sec ~ 102.49 MB/sec [4] 1,119,444 msgs/sec ~ 17.08 MB/sec (10000000 msgs) [5] 1,119,430 msgs/sec ~ 17.08 MB/sec (10000000 msgs) min 1,119,430 | avg 1,119,449 | max 1,119,466 | stddev 12 msgs - ``` +``` + diff --git a/nats_tools/nk.md b/nats-tools/nk.md similarity index 70% rename from nats_tools/nk.md rename to nats-tools/nk.md index 5acdde9..1f3270c 100644 --- a/nats_tools/nk.md +++ b/nats-tools/nk.md @@ -1,4 +1,4 @@ -# NK +# nk `nk` is a command line tool that generates `nkeys`. NKeys are a highly secure public-key signature system based on [Ed25519](https://ed25519.cr.yp.to/). @@ -6,24 +6,25 @@ With NKeys the server can verify identity without ever storing secrets on the se > NKey is an awesome replacement for token authentication, because a connecting client will have to prove it controls the private key for the authorized public key. -### Installing nk +## Installing nk -To get started with NKeys, you’ll need the `nk` tool from https://github.com/nats-io/nkeys/tree/master/nk repository. If you have _go_ installed, enter the following at a command prompt: +To get started with NKeys, you’ll need the `nk` tool from [https://github.com/nats-io/nkeys/tree/master/nk](https://github.com/nats-io/nkeys/tree/master/nk) repository. If you have _go_ installed, enter the following at a command prompt: ```bash > go get github.com/nats-io/nk ``` -### Generating NKeys and Configuring the Server +## Generating NKeys and Configuring the Server To generate a _User_ NKEY: -``` +```text > nk -gen user -pubout SUACSSL3UAHUDXKFSNVUZRF5UHPMWZ6BFDTJ7M6USDXIEDNPPQYYYCU3VY UDXU4RCSJNZOIQHZNWXHXORDPRTGNJAHAHFRGZNEEJCPQTT2M7NLCNF4 ``` -The first output line starts with the letter `S` for _Seed_. The second letter `U` stands for _User_. Seeds are private keys; you should treat them as secrets and guard them with care. +The first output line starts with the letter `S` for _Seed_. The second letter `U` stands for _User_. Seeds are private keys; you should treat them as secrets and guard them with care. + +The second line starts with the letter `U` for _User_, and is a public key which can be safely shared. -The second line starts with the letter `U` for _User_, and is a public key which can be safely shared. diff --git a/nats-tools/nsc/README.md b/nats-tools/nsc/README.md new file mode 100644 index 0000000..1dd0554 --- /dev/null +++ b/nats-tools/nsc/README.md @@ -0,0 +1,43 @@ +# nsc + +NATS account configurations are built using the `nsc` tool. The NSC tool allows you to: + +* Create and edit Operators, Accounts, Users +* Manage subscribe and publish permissions for Users +* Add and delete Exports and Imports +* Generate Activation tokens +* Generate User credential files +* Describe Operators, Accounts, Users, and Activations +* Push account JWTs to a server or pull account JWTs from a server + +## Installation + +Installing `nsc` is easy: + +```text +curl -L https://raw.githubusercontent.com/nats-io/nsc/master/install.py | python +``` + +The script will download the latest version of `nsc` and install it into your system. + +## Tutorials + +You can find various task-oriented tutorials to working with the tool here: + +* [Basic Usage](nsc.md) +* [Configuring Streams](streams.md) +* [Configuring Services](services.md) +* [Signing Keys](signing_keys.md) +* [Revoking Users or Activations](revocation.md) +* [Working with Managed Operators](managed.md) + +## Tool Documentation + +For more specific browsing of the tool syntax, check out the `nsc` tool documentation. It can be found within the tool itself: + +```text +> nsc help +``` + +Or an online version [here](https://nats-io.github.io/nsc). + diff --git a/nats_tools/nsc/managed.md b/nats-tools/nsc/managed.md similarity index 92% rename from nats_tools/nsc/managed.md rename to nats-tools/nsc/managed.md index f5f5865..5e5e80e 100644 --- a/nats_tools/nsc/managed.md +++ b/nats-tools/nsc/managed.md @@ -1,8 +1,8 @@ -# Working with Managed Operators +# Managed Operators You can use `nsc` to administer multiple operators. Operators can be thought of as the owners of nats-servers, and fall into two categories: local and managed. The key difference, pardon the pun, is that managed operators are ones which you don't have the nkey for. An example of a managed operator is the Synadia service called NGS. Synadia has the keys. -Accounts, as represented by their JWTs, are signed by the operator. Some operators may use local copies of JWTs, others may use the [nats-account-server](../nas/README.md) to manage their JWTs. Synadia uses a custom server for their JWTs that works similarly to the open-sourced account server. +Accounts, as represented by their JWTs, are signed by the operator. Some operators may use local copies of JWTs, others may use the [nats-account-server](../nas/) to manage their JWTs. Synadia uses a custom server for their JWTs that works similarly to the open-sourced account server. There are a few special commands when dealing with server based operators: @@ -31,7 +31,7 @@ or % nsc init -o synadia -n alpha ``` -In the second case you can use the name of an existing operator, or a well known one (currently only "synadia"). +In the second case you can use the name of an existing operator, or a well known one \(currently only "synadia"\). Once you add a managed operator you can add accounts to it normally, with the caveat that new accounts are pushed and pulled as described above. @@ -57,3 +57,4 @@ You can also set one or more service urls. These allow the `nsc tool` actions li nsc edit operator -n nats://localhost:4222 nsc tool pub hello world ``` + diff --git a/nats_tools/nsc/nsc.md b/nats-tools/nsc/nsc.md similarity index 92% rename from nats_tools/nsc/nsc.md rename to nats-tools/nsc/nsc.md index af29b8c..a088df9 100644 --- a/nats_tools/nsc/nsc.md +++ b/nats-tools/nsc/nsc.md @@ -1,22 +1,20 @@ -# NSC +# Basics NATS uses JWTs to armor the various identity and authorization artifacts. These JWTs are created with the `nsc` tool. NSC simplifies the tasks of creating and managing identities and other JWT artifacts. There’s a logical hierarchy to the entities: -- `Operators` are responsible for running nats-servers, and signing account JWTs that set the limits on what an account can do, such as the number of connections, data limits, etc. - -- `Accounts` are responsible for issuing user JWTs, and for declaring what subjects can be exported to other accounts, and what subjects they import from other accounts and what the local subjects for those imports are. - -- `Users` are issued by an account, and encode limits regarding usage and authorization over the subject space. +* `Operators` are responsible for running nats-servers, and signing account JWTs that set the limits on what an account can do, such as the number of connections, data limits, etc. +* `Accounts` are responsible for issuing user JWTs, and for declaring what subjects can be exported to other accounts, and what subjects they import from other accounts and what the local subjects for those imports are. +* `Users` are issued by an account, and encode limits regarding usage and authorization over the subject space. NSC allows you to create, edit, delete these entities, and will be central to all account based configuration. In this guide, you’ll run end-to-end on some of the configuration scenarios: -- generate JWTs -- make JWTs accessible to a nats-server -- configure a nats-server to use JWTs +* generate JWTs +* make JWTs accessible to a nats-server +* configure a nats-server to use JWTs Let’s run through the process of creating some identities and JWTs and work through the process. @@ -48,7 +46,7 @@ As you can see there is a setting for the nkeys folder and the nsc home. By defa You can easily change the home and keys locations by setting `NSC_HOME` and `NKEYS_PATH` respectively in your environment to your desired locations. The environment itself is stored in the `NSC_HOME`. Operator folders are in the stores directory which can be inside `NSC_HOME` or external to it. -> The $NKEYS_PATH stores secrets. Since nkeys relies on cryptographic signatures to prove identity, anyone with access to your private keys will be able to assume your identity. With that said, treat them as secrets and guard them carefully. +> The $NKEYS\_PATH stores secrets. Since nkeys relies on cryptographic signatures to prove identity, anyone with access to your private keys will be able to assume your identity. With that said, treat them as secrets and guard them carefully. ## Creating an Operator @@ -62,7 +60,7 @@ Success! - added operator "Test" With the above incantation, the tool generated an NKEY for the operator, stored the private key safely in `~/.nkeys/Test/Test.nk`. The file contains a single line, with the seed value for the NKEY. - > You can tell the key is a seed if it starts with the letter `S`. The type of the key is will be the second letter an `O`, `A` or `U` for _Operator_, _Account_ or _User_. If the key does not start with an `S` you have instead a public key. +> You can tell the key is a seed if it starts with the letter `S`. The type of the key is will be the second letter an `O`, `A` or `U` for _Operator_, _Account_ or _User_. If the key does not start with an `S` you have instead a public key. The tool also created a JWT with all default settings for the operator test, and stored it in `~/.nsc/nats/Test/Test.jwt`. The `~/.nsc/nats/Test` directory will also contain a directory where accounts related to this operator will live. @@ -104,7 +102,7 @@ With an operator, we are ready to create our first account. Let’s create an account called `TestAccount`: -``` +```text > nsc add account -n TestAccount Generated account key - private key stored “~/.nkeys/Test/accounts/TestAccount/TestAccount.nk" Success! - added account "TestAccount" @@ -137,9 +135,9 @@ As we did with the operator, we can describe the account: ╰───────────────────────────┴─────────────────────────╯ ``` -Again, specifying the `-W` flag will print the complete account ID (the public key identifying the account). +Again, specifying the `-W` flag will print the complete account ID \(the public key identifying the account\). -Note that the issuer for the account is the ID for the operator (the public key identifying the operator). +Note that the issuer for the account is the ID for the operator \(the public key identifying the operator\). Now we are ready to add a user. @@ -154,7 +152,7 @@ Generated user creds file "~/.nkeys/Test/accounts/TestAccount/users/TestUser.cre Success! - added user "TestUser" to "TestAccount" ``` -Note that when we added the user, we got a message telling us about a `.creds` file being created. The `.creds` file contains the JWT describing the user, and the private (seed) key for the user. This file is formatted in a special way for use by nats client libraries. Client libraries can extract the JWT and seed key, and connect to a server expecting JWT authentication, provide the JWT and use the private key to sign the nonce to verify its identity. +Note that when we added the user, we got a message telling us about a `.creds` file being created. The `.creds` file contains the JWT describing the user, and the private \(seed\) key for the user. This file is formatted in a special way for use by nats client libraries. Client libraries can extract the JWT and seed key, and connect to a server expecting JWT authentication, provide the JWT and use the private key to sign the nonce to verify its identity. And let’s describe it: @@ -196,7 +194,7 @@ The account server has options to enable you to use an nsc directory directly. L > nats-account-server -nsc ~/.nsc/nats/Test ``` -Above we pointed the account server to our nsc data directory (more specifically to the `Test` operator that we created earlier). By default, the server listens on the localhost at port 9090. +Above we pointed the account server to our nsc data directory \(more specifically to the `Test` operator that we created earlier\). By default, the server listens on the localhost at port 9090. You can also run the account server with a data directory that is not your nsc folder. In this mode you can upload account JWTs to the server. See the help for `nsc push` for more information about how to push JWTs to the account server. @@ -246,7 +244,7 @@ Published [hello] : 'NATS' Subscriber shows: ```text -[#1] Received on [hello]: ’NATS’ + ``` ## User Authorization @@ -314,3 +312,4 @@ Success! - added user "TestClient" to "TestAccount" ``` The client has the opposite permissions of the service. It can publish on the request subject `req.a`, and receive replies on an inbox. + diff --git a/nats_tools/nsc/revocation.md b/nats-tools/nsc/revocation.md similarity index 99% rename from nats_tools/nsc/revocation.md rename to nats-tools/nsc/revocation.md index 5de05ef..1473892 100644 --- a/nats_tools/nsc/revocation.md +++ b/nats-tools/nsc/revocation.md @@ -26,3 +26,4 @@ Available Commands: Both add commands take the flag `--at` which defaults to 0, for now, which can be used to set the unix timestamp as described above. By default revocations are at the current time, but you can set them in the past for situations where you know when a problem occurred and was fixed. Deleting a revocation is permanent and can allow an old activation or user JWT to be valid again. Therefore delete should only be used if you are sure the tokens in question have expired. + diff --git a/nats_tools/nsc/services.md b/nats-tools/nsc/services.md similarity index 98% rename from nats_tools/nsc/services.md rename to nats-tools/nsc/services.md index 876f86d..bdad96f 100644 --- a/nats_tools/nsc/services.md +++ b/nats-tools/nsc/services.md @@ -48,14 +48,13 @@ To review the service export: Importing a service enables you to send requests to the remote _Account_. To import a Service, you have to create an _Import_. To create an import you need to know: -- The exporting account’s public key -- The subject the service is listening on -- You can map the service’s subject to a different subject -- Self-imports are not valid; you can only import services from other accounts. +* The exporting account’s public key +* The subject the service is listening on +* You can map the service’s subject to a different subject +* Self-imports are not valid; you can only import services from other accounts. To learn how to inspect a JWT from an account server, [check this article](../nas/inspecting_jwts.md). - ```text > nsc add import --src-account AC7PO3MREV26U3LFZFP5BN3HAI32X3PKLBRVMPAETLEHWPQEUG7EJY4H --remote-subject help --service Success! - added service import "help" @@ -99,6 +98,7 @@ Verifying our work: To test the service, we can install the `nats-req` and `nats-rply` tools: Set up a process to handle the request: + ```text > go get github.com/nats-io/nats.go/examples/nats-rply @@ -107,6 +107,7 @@ Listening on [help] ``` Send the request: + ```text > go get github.com/nats-io/nats.go/examples/nats-req > nats-req -creds ~/.nkeys/Test/accounts/AccountB/users/userb.creds help me @@ -114,11 +115,13 @@ Published [help] : 'me' ``` The service receives the request: + ```text -[#1] Received on [help]: 'me' + ``` And the response is received by the requestor: + ```text Received [_INBOX.v6KAX0v1bu87k49hbg3dgn.StIGJF0D] : 'I will help' ``` @@ -128,6 +131,7 @@ Received [_INBOX.v6KAX0v1bu87k49hbg3dgn.StIGJF0D] : 'I will help' If you want to create a service that is only accessible to accounts you designate you can create a _private_ service. The export will be visible in your account, but subscribing accounts will require an authorization token that must be created by you and generated specifically for the requesting account. Let’s create an account and user for our stream client: + ```text > nsc add account --name AccountB Generated account key - private key stored “~/.nkeys/Test/accounts/AccountB/AccountB" @@ -225,7 +229,7 @@ When decoded it looks like this: ╰─────────────────┴─────────────────────────╯ ``` -The token can be shared directly with the client account. +The token can be shared directly with the client account. > If you manage many tokens for many accounts, you may want to host activation tokens on a web server and share the URL with the account. The benefit to the hosted approach is that any updates to the token would be available to the importing account whenever their account is updated, provided the URL you host them in is stable. @@ -264,7 +268,6 @@ As with streams, importing a private service is more natural than a public one b ╰─────────┴─────────┴─────────────────┴─────────┴─────────┴──────────────┴────────╯ ``` - ### Testing the Private Service Start the replier: @@ -274,19 +277,22 @@ Start the replier: Listening on [help.>] ``` - Send a request: + ```text > nats-req -creds ~/.nkeys/Test/accounts/AccountB/users/userb.creds help me Published [help] : 'me' ``` The service receives the message: + ```text -[#1] Received on [help.AAL5Q2B3SM]: 'me' + ``` The requester receives its response: + ```text Received [_INBOX.N3IiqWbiAQfPoINCBpBrUM.ZjBNtkB3] : 'I will help' ``` + diff --git a/nats_tools/nsc/signing_keys.md b/nats-tools/nsc/signing_keys.md similarity index 93% rename from nats_tools/nsc/signing_keys.md rename to nats-tools/nsc/signing_keys.md index c734bcd..bd06e0f 100644 --- a/nats_tools/nsc/signing_keys.md +++ b/nats-tools/nsc/signing_keys.md @@ -4,22 +4,22 @@ As previously discussed, NKEYs are identities, and if someone gets a hold of an NATS has a strategies to let you deal with scenarios where your private keys escape out in the wild. -The first and most important line of defense is _Signing Keys_. _Signing Keys_ allow you have multiple NKEY identities of the same kind (Operator or Account) that have the same degree of trust as the standard _Issuer_ nkey. +The first and most important line of defense is _Signing Keys_. _Signing Keys_ allow you have multiple NKEY identities of the same kind \(Operator or Account\) that have the same degree of trust as the standard _Issuer_ nkey. The concept behind the signing key is that you can issue a JWT for an operator or an account that lists multiple nkeys. Typically the issuer will match the _Subject_ of the entity issuing the JWT. With SigningKeys, a JWT is considered valid if it is signed by the _Subject_ of the _Issuer_ or one of its signing keys. This enables guarding the private key of the Operator or Account more closely while allowing _Accounts_, _Users_ or _Activation Tokens_ be signed using alternate private keys. -If an issue should arise where somehow a signing key escapes into the wild, you would remove the compromised signing key from the entity, add a new one, and reissue the entity. When a JWT is validated, if the signing key is missing, the operation is rejected. You are also on the hook to re-issue all JWTs (accounts, users, activation tokens) that were signed with the compromised signing key. +If an issue should arise where somehow a signing key escapes into the wild, you would remove the compromised signing key from the entity, add a new one, and reissue the entity. When a JWT is validated, if the signing key is missing, the operation is rejected. You are also on the hook to re-issue all JWTs \(accounts, users, activation tokens\) that were signed with the compromised signing key. -This is effectively a large hammer. You can mitigate the process a bit by having a larger number of signing keys and then rotating the signing keys to get a distribution you can easily handle in case of a compromise. In a future release, we’ll have a revocation process were you can invalidate a single JWT by its unique JWT ID (JTI). For now a sledge hammer you have. +This is effectively a large hammer. You can mitigate the process a bit by having a larger number of signing keys and then rotating the signing keys to get a distribution you can easily handle in case of a compromise. In a future release, we’ll have a revocation process were you can invalidate a single JWT by its unique JWT ID \(JTI\). For now a sledge hammer you have. With greater security process, there’s greater complexity. With that said, `nsc` doesn’t track public or private signing keys. As these are only identities that when in use presume a manual use. That means that you the user will have to track and manage your private keys more closely. Let’s get a feel for the workflow. We are going to: -- Create an operator with a signing key -- Create an account with a signing key -- The account will be signed using the operator’s signing key -- Create an user with the account’s signing key +* Create an operator with a signing key +* Create an account with a signing key +* The account will be signed using the operator’s signing key +* Create an user with the account’s signing key All signing key operations revolve around the global `nsc` flag `-K` or `--private-key`. Whenever you want to modify an entity, you have to supply the parent key so that the JWT is signed. Normally this happens automatically but in the case of signing keys, you’ll have to supply the flag by hand. @@ -29,7 +29,6 @@ Creating the operator: > nsc add operator -n O2 Generated operator key - private key stored "/Users/synadia/.nkeys/O2/O2.nk" Success! - added operator "O2" - ``` To add a signing key we have to first generate one with `nk`. `NSC` doesn’t at this time offer a way to generate keys that are not associated with an entity. This means that you will have to generate and store the secrets yourself: @@ -43,7 +42,7 @@ ODMYCI5TSZY6MFLOBBQ2RNRBRAXRKJKAC5UACRC6H6CJXCLR2STTGAAQ > On a production environment private keys should be saved to a file and always referenced from the secured file. -Now we are going to edit the operator by adding a signing key with the `--sk` flag providing the generated operator public key (the one starting with `O`): +Now we are going to edit the operator by adding a signing key with the `--sk` flag providing the generated operator public key \(the one starting with `O`\): ```text > nsc edit operator --sk ODMYCI5TSZY6MFLOBBQ2RNRBRAXRKJKAC5UACRC6H6CJXCLR2STTGAAQ @@ -119,7 +118,7 @@ Success! - edited account "A" ╰───────────────────────────┴─────────────────────────╯ ``` -We can see that the signing key `ABHYL27UAHHQ` was added to the account. Also the issuer is the operator signing key (specified by the `-K`). +We can see that the signing key `ABHYL27UAHHQ` was added to the account. Also the issuer is the operator signing key \(specified by the `-K`\). Now let’s create a user and signing it with account signing key starting with `ABHYL27UAHHQ`. @@ -148,3 +147,4 @@ Success! - added user "U" to "A" ``` As expected, the issuer is now the signing key we generated earlier. To map the user to the actual account, an `Issuer Account` field was added to the JWT that identifies the public key of account _A_. + diff --git a/nats_tools/nsc/streams.md b/nats-tools/nsc/streams.md similarity index 98% rename from nats_tools/nsc/streams.md rename to nats-tools/nsc/streams.md index 9fea104..fcf9786 100644 --- a/nats_tools/nsc/streams.md +++ b/nats-tools/nsc/streams.md @@ -52,10 +52,10 @@ Messages this account publishes on `a.b.c.>` will be forwarded to all accounts t Importing a stream enables you to receive messages that are published by a different _Account_. To import a Stream, you have to create an _Import_. To create an _Import_ you need to know: -- The exporting account’s public key -- The subject where the stream is published -- You can map the stream’s subject to a different subject -- Self-imports are not valid; you can only import streams from other accounts. +* The exporting account’s public key +* The subject where the stream is published +* You can map the stream’s subject to a different subject +* Self-imports are not valid; you can only import streams from other accounts. To learn how to inspect a JWT from an account server, [check this article](../nas/inspecting_jwts.md). @@ -147,12 +147,12 @@ Like before we defined an export, but this time we added the `--private` flag. ╰──────┴────────┴─────────┴────────╯ ``` - ### Generating an Activation Token For a foreign account to _import_ a private stream, you have to generate an activation token. The activation token in addition to granting permissions to the account, it also allows you to subset the exported stream’s subject. Let’s create an account and user for our stream client: + ```text > nsc add account --name AccountB Generated account key - private key stored “~/.nkeys/Test/accounts/AccountB/AccountB" @@ -204,7 +204,7 @@ When decoded it looks like this: ╰─────────────────┴─────────────────────────╯ ``` -The token can be shared directly with the client account. +The token can be shared directly with the client account. > If you manage many tokens for many accounts, you may want to host activation tokens on a web server and share the URL with the account. The benefit to the hosted approach is that any updates to the token would be available to the importing account whenever their account is updated, provided the URL you host them in is stable. @@ -252,22 +252,26 @@ nsc describe account ### Testing the Private Stream Start the `nats-account-server`: + ```text > nats-account-server -nsc ~/.nsc/nats/Test ``` Create a config for the nats server `server.conf`: + ```text operator: /Users/synadia/.nsc/nats/Test/Test.jwt resolver: URL(http://localhost:9090/jwt/v1/accounts/) ``` Start the `nats-server`: + ```text > nats-server -c server.conf ``` Start the subscriber for the client account: + ```text > nats-sub -creds ~/.nkeys/Test/accounts/AccountB/users/userb.creds ">" Listening on [>] @@ -288,7 +292,6 @@ Published [a.b.c.d] : 'hello' The subscriber as expected prints a message on the stream that it was allowed to receive: ```text -[#1] Received on [a.b.c.d.a.b.c.d]: 'hello' + ``` - diff --git a/nats_admin/README.md b/nats_admin/README.md deleted file mode 100644 index dd1ece3..0000000 --- a/nats_admin/README.md +++ /dev/null @@ -1,7 +0,0 @@ -# Managing a NATS Server - -Managing a NATS server is simple, typical lifecycle operations include: - -- [Sending signals](signals.md) to a server to reload a configuration or rotate log files -- [Upgrading](upgrading_cluster.md) a server (or cluster) -- Understanding [slow consumers](slow_consumers.md) \ No newline at end of file diff --git a/nats_admin/slow_consumers.md b/nats_admin/slow_consumers.md deleted file mode 100644 index ce3daea..0000000 --- a/nats_admin/slow_consumers.md +++ /dev/null @@ -1,111 +0,0 @@ -# Slow Consumers - -To support resiliency and high availability, NATS provides built-in mechanisms to automatically prune the registered listener interest graph that is used to keep track of subscribers, including slow consumers and lazy listeners. NATS automatically handles a slow consumer. If a client is not processing messages quick enough, the NATS server cuts it off. To support scaling, NATS provides for auto-pruning of client connections. If a subscriber does not respond to ping requests from the server within the [ping-pong interval](/nats_protocol/nats-protocol.md#PINGPONG), the client is cut off (disconnected). The client will need to have reconnect logic to reconnect with the server. - -In core NATS, consumers that cannot keep up are handled differently from many other messaging systems: NATS favors the approach of protecting the system as a whole over accommodating a particular consumer to ensure message delivery. - -__What is a slow consumer?__ - -A slow consumer is a subscriber that cannot keep up with the message flow delivered from the NATS server. This is a common case in distributed systems because it is often easier to generate data than it is to process it. When consumers cannot process data fast enough, back pressure is applied to the rest of the system. NATS has mechanisms to reduce this back pressure. - -NATS identifies slow consumers in the client or the server, providing notification through registered callbacks, log messages, and statistics in the server's monitoring endpoints. - -__What happens to slow consumers?__ - -When detected at the client, the application is notified and messages are dropped to allow the consumer to continue and reduce potential back pressure. When detected in the server, the server will disconnect the connection with the slow consumer to protect itself and the integrity of the messaging system. - -## Slow consumers identified in the client - -A [client can detect it is a slow consumer](/developer/events/slow.md) on a local connection and notify the application through use of the asynchronous error callback. It is better to catch a slow consumer locally in the client rather than to allow the server to detect this condition. This example demonstrates how to define and register an asynchronous error handler that will handle slow consumer errors. - -```go -func natsErrHandler(nc *nats.Conn, sub *nats.Subscription, natsErr error) { - fmt.Printf("error: %v\n", natsErr) - if natsErr == nats.ErrSlowConsumer { - pendingMsgs, _, err := sub.Pending() - if err != nil { - fmt.Printf("couldn't get pending messages: %v", err) - return - } - fmt.Printf("Falling behind with %d pending messages on subject %q.\n", - pendingMsgs, sub.Subject) - // Log error, notify operations... - } - // check for other errors -} - -// Set the error handler when creating a connection. -nc, err := nats.Connect("nats://localhost:4222", - nats.ErrorHandler(natsErrHandler)) -``` - -With this example code and default settings, a slow consumer error would generate output something like this: - -```sh -error: nats: slow consumer, messages dropped -Falling behind with 65536 pending messages on subject "foo". -``` - -Note that if you are using a synchronous subscriber, `Subscription.NextMsg(timeout time.Duration)` will also return an error indicating there was a slow consumer and messages have been dropped. - -## Slow consumers identified by the server - -When a client does not process messages fast enough, the server will buffer messages in the outbound connection to the client. When this happens and the server cannot write data fast enough to the client, in order to protect itself, it will designate a subscriber as a "slow consumer" and may drop the associated connection. - -When the server initiates a slow consumer error, you'll see the following in the server output: - -```sh -[54083] 2017/09/28 14:45:18.001357 [INF] ::1:63283 - cid:7 - Slow Consumer Detected -``` - -The server will also keep count of the number of slow consumer errors encountered, available through the monitoring `varz` endpoint in the `slow_consumers` field. - -## Handling slow consumers - -Apart from using [NATS streaming](/nats_streaming/intro.md/) or optimizing your consuming application, there are a few options available: scale, meter, or tune NATS to your environment. - -__Scaling with queue subscribers__ - -This is ideal if you do not rely on message order. Ensure your NATS subscription belongs to a [queue group](/developer/concepts/queue.md/), then scale as required by creating more instances of your service or application. This is a great approach for microservices - each instance of your microservice will receive a portion of the messages to process, and simply add more instances of your service to scale. No code changes, configuration changes, or downtime whatsoever. - -__Create a subject namespace that can scale__ - -You can distribute work further through the subject namespace, with some forethought in design. This approach is useful if you need to preserve message order. The general idea is to publish to a deep subject namespace, and consume with wildcard subscriptions while giving yourself room to expand and distribute work in the future. - -For a simple example, if you have a service that receives telemetry data from IoT devices located throughout a city, you can publish to a subject namespace like `Sensors.North`, `Sensors.South`, `Sensors.East` and `Sensors.West`. Initially, you'll subscribe to `Sensors.>` to process everything in one consumer. As your enterprise grows and data rates exceed what one consumer can handle, you can replace your single consumer with four consuming applications to subscribe to each subject representing a smaller segment of your data. Note that your publishing applications remain untouched. - -__Meter the publisher__ - -A less favorable option may be to meter the publisher. There are several ways to do this varying from simply slowing down your publisher to a more complex approach periodically issuing a blocking request/reply to match subscriber rates. - -__Tune NATS through configuration__ - -The NATS server can be tuned to determine how much data can be buffered before a consumer is considered slow, and some officially supported clients allow buffer sizes to be adjusted. Decreasing buffer sizes will let you identify slow consumers more quickly. Increasing buffer sizes is not typically recommended unless you are handling temporary bursts of data. Often, increasing buffer capacity will only *postpone* slow consumer problems. - -### Server Configuration - -The NATS server has a write deadline it uses to write to a connection. When this write deadline is exceeded, a client is considered to have a slow consumer. If you are encountering slow consumer errors in the server, you can increase the write deadline to buffer more data. - -The `write_deadline` configuration option in the NATS server configuration file will tune this: - -```ascii -write_deadline: 2s -``` - - Tuning this parameter is ideal when you have bursts of data to accommodate. **_Be sure you are not just postponing a slow consumer error._** - -### Client Configuration - -Most officially supported clients have an internal buffer of pending messages and will notify your application through an asynchronous error callback if a local subscription is not catching up. Receiving an error locally does not necessarily mean that the server will have identified a subscription as a slow consumer. - -This buffer can be configured through setting the pending limits after a subscription has been created: - -```go -if err := sub.SetPendingLimits(1024*500, 1024*5000); err != nil { - log.Fatalf("Unable to set pending limits: %v", err) -} -``` - -The default subscriber pending message limit is `65536`, and the default subscriber pending byte limit is `65536*1024` - -If the client reaches this internal limit, it will drop messages and continue to process new messages. This is aligned with NATS at most once delivery. It is up to your application to detect the missing messages and recover from this condition. diff --git a/nats_protocol/nats-protocol.md b/nats_protocol/nats-protocol.md deleted file mode 100644 index ee669d5..0000000 --- a/nats_protocol/nats-protocol.md +++ /dev/null @@ -1,317 +0,0 @@ -## Client Protocol - -The wire protocol used to communicate between the NATS server and clients is a simple, text-based publish/subscribe style protocol. Clients connect to and communicate with `nats-server` (the NATS server) through a regular TCP/IP socket using a small set of protocol operations that are terminated by a new line. - -Unlike traditional messaging systems that use a binary message format that require an API to consume, the text-based NATS protocol makes it easy to implement clients in a wide variety of programming and scripting languages. In fact, refer to the topic [NATS Protocol Demo](nats-protocol-demo.md) to play with the NATS protocol for yourself using telnet. - -The NATS server implements a [zero allocation byte parser](https://youtu.be/ylRKac5kSOk?t=10m46s) that is fast and efficient. - -## Protocol conventions - -**Control line w/Optional Content**: Each interaction between the client and server consists of a control, or protocol, line of text followed, optionally by message content. Most of the protocol messages don't require content, only `PUB` and `MSG` include payloads. - -**Field Delimiters**: The fields of NATS protocol messages are delimited by whitespace characters '` `' (space) or `\t` (tab). Multiple whitespace characters will be treated as a single field delimiter. - -**Newlines**: NATS uses `CR` followed by `LF` (`CR+LF`, `\r\n`, `0x0D0A`) to terminate protocol messages. This newline sequence is also used to mark the end of the message payload in a `PUB` or `MSG` protocol message. - -**Subject names**: Subject names, including reply subject (INBOX) names, are case-sensitive and must be non-empty alphanumeric strings with no embedded whitespace. All ascii alphanumeric characters except spaces/tabs and separators which are "." and ">" are allowed. Subject names can be optionally token-delimited using the dot character (`.`), e.g.: - -`FOO`, `BAR`, `foo.bar`, `foo.BAR`, `FOO.BAR` and `FOO.BAR.BAZ` are all valid subject names - -`FOO. BAR`, `foo. .bar` and`foo..bar` are *not* valid subject names - -A subject is comprised of 1 or more tokens. Tokens are separated by "." and can be any non space ascii alphanumeric character. The full wildcard token ">" is only valid as the last token and matches all tokens past that point. A token wildcard, "*" matches any token in the position it was listed. Wildcard tokens should only be used in a wildcard capacity and not part of a literal token. - -**Character Encoding**: Subject names should be ascii characters for maximum interoperability. Due to language constraints and performance, some clients may support UTF-8 subject names, as may the server. No guarantees of non-ASCII support are provided. - -**Wildcards**: NATS supports the use of wildcards in subject subscriptions. - -- The asterisk character (`*`) matches a single token at any level of the subject. -- The greater than symbol (`>`), also known as the _full wildcard_, matches one or more tokens at the tail of a subject, and must be the last token. The wildcarded subject `foo.>` will match `foo.bar` or `foo.bar.baz.1`, but not `foo`. -- Wildcards must be a separate token (`foo.*.baz` or `foo.>` are syntactically valid; `foo*.bar`, `f*o.b*r` and `foo>` are not) - -For example, the wildcard subscriptions `foo.*.quux` and `foo.>` both match `foo.bar.quux`, but only the latter matches `foo.bar.baz`. With the full wildcard, -it is also possible to express interest in every subject that may exist in NATS: `sub > 1`, limited of course by authorization settings. - -## Protocol messages - -The following table briefly describes the NATS protocol messages. NATS protocol operation names are case insensitive, thus `SUB foo 1\r\n` and `sub foo 1\r\n` are equivalent. - -Click the name to see more detailed information, including syntax: - -| OP Name | Sent By | Description -| -------------------- |:-------------- |:-------------------------------------------- -| [`INFO`](#info) | Server | Sent to client after initial TCP/IP connection -| [`CONNECT`](#connect)| Client | Sent to server to specify connection information -| [`PUB`](#pub) | Client | Publish a message to a subject, with optional reply subject -| [`SUB`](#sub) | Client | Subscribe to a subject (or subject wildcard) -| [`UNSUB`](#unsub) | Client | Unsubscribe (or auto-unsubscribe) from subject -| [`MSG`](#msg) | Server | Delivers a message payload to a subscriber -| [`PING`](#pingpong) | Both | PING keep-alive message -| [`PONG`](#pingpong) | Both | PONG keep-alive response -| [`+OK`](#okerr) | Server | Acknowledges well-formed protocol message in `verbose` mode -| [`-ERR`](#okerr) | Server | Indicates a protocol error. May cause client disconnect. - -The following sections explain each protocol message. - -## INFO - -#### Description - -As soon as the server accepts a connection from the client, it will send information about itself and the configuration and security requirements that are necessary for the client to successfully authenticate with the server and exchange messages. - -When using the updated client protocol (see [`CONNECT`](#connect) below), `INFO` messages can be sent anytime by the server. This means clients with that protocol level need to be able to asynchronously handle `INFO` messages. - -#### Syntax - -`INFO {["option_name":option_value],...}` - -The valid options are as follows: - -- `server_id`: The unique identifier of the NATS server -- `version`: The version of the NATS server -- `go`: The version of golang the NATS server was built with -- `host`: The IP address used to start the NATS server, by default this will be `0.0.0.0` and can be configured with `-client_advertise host:port` -- `port`: The port number the NATS server is configured to listen on -- `max_payload`: Maximum payload size, in bytes, that the server will accept from the client. -- `proto`: An integer indicating the protocol version of the server. The server version 1.2.0 sets this to `1` to indicate that it supports the "Echo" feature. -- `client_id`: An optional unsigned integer (64 bits) representing the internal client identifier in the server. This can be used to filter client connections in monitoring, correlate with error logs, etc... -- `auth_required`: If this is set, then the client should try to authenticate upon connect. -- `tls_required`: If this is set, then the client must perform the TLS/1.2 handshake. Note, this used to be `ssl_required` and has been updated along with the protocol from SSL to TLS. -- `tls_verify`: If this is set, the client must provide a valid certificate during the TLS handshake. -- `connect_urls` : An optional list of server urls that a client can connect to. - -##### connect_urls - -The `connect_urls` field is a list of urls the server may send when a client first connects, and when there are changes to server cluster topology. This field is considered optional, and may be omitted based on server configuration and client protocol level. - -When a NATS server cluster expands, an `INFO` message is sent to the client with an updated `connect_urls` list. This cloud-friendly feature asynchronously notifies a client of known servers, allowing it to connect to servers not originally configured. - -The `connect_urls` will contain a list of strings with an IP and port, looking like this: ```"connect_urls":["10.0.0.184:4333","192.168.129.1:4333","192.168.192.1:4333"]``` - -#### Example - -Below you can see a sample connection string from a telnet connection to the `demo.nats.io` site. - -```sh -% telnet demo.nats.io 4222 - -Trying 107.170.221.32... -Connected to demo.nats.io. -Escape character is '^]'. -INFO {"server_id":"Zk0GQ3JBSrg3oyxCRRlE09","version":"1.2.0","proto":1,"go":"go1.10.3","host":"0.0.0.0","port":4222,"max_payload":1048576,"client_id":2392} -``` - -## CONNECT - -#### Description - -The `CONNECT` message is the client version of the [`INFO`](#info) message. Once the client has established a TCP/IP socket connection with the NATS server, and an [`INFO`](#info) message has been received from the server, the client may send a `CONNECT` message to the NATS server to provide more information about the current connection as well as security information. - -#### Syntax - -`CONNECT {["option_name":option_value],...}` - -The valid options are as follows: - -* `verbose`: Turns on [`+OK`](#okerr) protocol acknowledgements. -* `pedantic`: Turns on additional strict format checking, e.g. for properly formed subjects -* `tls_required`: Indicates whether the client requires an SSL connection. -* `auth_token`: Client authorization token (if `auth_required` is set) -* `user`: Connection username (if `auth_required` is set) -* `pass`: Connection password (if `auth_required` is set) -* `name`: Optional client name -* `lang`: The implementation language of the client. -* `version`: The version of the client. -* `protocol`: *optional int*. Sending `0` (or absent) indicates client supports original protocol. Sending `1` indicates that the client supports dynamic reconfiguration of cluster topology changes by asynchronously receiving [`INFO`](#info) messages with known servers it can reconnect to. -* `echo`: Optional boolean. If set to `true`, the server (version 1.2.0+) will not send originating messages from this connection to its own subscriptions. Clients should set this to `true` only for server supporting this feature, which is when `proto` in the `INFO` protocol is set to at least `1`. - -#### Example - -Here is an example from the default string of the Go client: - -``` -[CONNECT {"verbose":false,"pedantic":false,"tls_required":false,"name":"","lang":"go","version":"1.2.2","protocol":1}]\r\n -``` - -Most clients set `verbose` to `false` by default. This means that the server should not confirm each message it receives on this connection with a [`+OK`](#okerr) back to the client. - -## PUB - -#### Description - -The `PUB` message publishes the message payload to the given subject name, optionally supplying a reply subject. If a reply subject is supplied, it will be delivered to eligible subscribers along with the supplied payload. Note that the payload itself is optional. To omit the payload, set the payload size to 0, but the second CRLF is still required. - -#### Syntax - -`PUB [reply-to] <#bytes>\r\n[payload]\r\n` - -where: - -- `subject`: The destination subject to publish to -- `reply-to`: The optional reply inbox subject that subscribers can use to send a response back to the publisher/requestor -- `#bytes`: The payload size in bytes -- `payload`: The message payload data - -#### Example - -To publish the ASCII string message payload "Hello NATS!" to subject FOO: - -`PUB FOO 11\r\nHello NATS!\r\n` - -To publish a request message "Knock Knock" to subject FRONT.DOOR with reply subject INBOX.22: - -`PUB FRONT.DOOR INBOX.22 11\r\nKnock Knock\r\n` - -To publish an empty message to subject NOTIFY: - -`PUB NOTIFY 0\r\n\r\n` - -## SUB - -#### Description - -`SUB` initiates a subscription to a subject, optionally joining a distributed queue group. - -#### Syntax - -`SUB [queue group] \r\n` - -where: - -- `subject`: The subject name to subscribe to -- `queue group`: If specified, the subscriber will join this queue group -- `sid`: A unique alphanumeric subscription ID, generated by the client - -#### Example - -To subscribe to the subject `FOO` with the connection-unique subscription identifier (sid) `1`: - -`SUB FOO 1\r\n` - -To subscribe the current connection to the subject `BAR` as part of distribution queue group `G1` with sid `44`: - -`SUB BAR G1 44\r\n` - -## UNSUB - -#### Description - -`UNSUB` unsubcribes the connection from the specified subject, or auto-unsubscribes after the specified number of messages has been received. - -#### Syntax - -`UNSUB [max_msgs]` - -where: - -* `sid`: The unique alphanumeric subscription ID of the subject to unsubscribe from -* `max_msgs`: An optional number of messages to wait for before automatically unsubscribing - -#### Example - -The following examples concern subject `FOO` which has been assigned sid `1`. To unsubscribe from `FOO`: - -`UNSUB 1\r\n` - -To auto-unsubscribe from `FOO` after 5 messages have been received: - -`UNSUB 1 5\r\n` - -## MSG - -#### Description - -The `MSG` protocol message is used to deliver an application message to the client. - -#### Syntax - -`MSG [reply-to] <#bytes>\r\n[payload]\r\n` - -where: - -* `subject`: Subject name this message was received on -* `sid`: The unique alphanumeric subscription ID of the subject -* `reply-to`: The inbox subject on which the publisher is listening for responses -* `#bytes`: Size of the payload in bytes -* `payload`: The message payload data - -#### Example - -The following message delivers an application message from subject `FOO.BAR`: - -`MSG FOO.BAR 9 11\r\nHello World\r\n` - -To deliver the same message along with a reply inbox: - -`MSG FOO.BAR 9 INBOX.34 11\r\nHello World\r\n` - -## PING/PONG - -#### Description - -`PING` and `PONG` implement a simple keep-alive mechanism between client and server. Once a client establishes a connection to the NATS server, the server will continuously send `PING` messages to the client at a configurable interval. If the client fails to respond with a `PONG` message within the configured response interval, the server will terminate its connection. If your connection stays idle for too long, it is cut off. - -If the server sends a ping request, you can reply with a pong message to notify the server that you are still interested. You can also ping the server and will receive a pong reply. The ping/pong interval is configurable. - -The server uses normal traffic as a ping/pong proxy, so a client that has messages flowing may not receive a ping from the server. - -#### Syntax - -`PING\r\n` - -`PONG\r\n` - -#### Example - -The following example shows the demo server pinging the client and finally shutting it down. - -``` -telnet demo.nats.io 4222 - -Trying 107.170.221.32... -Connected to demo.nats.io. -Escape character is '^]'. -INFO {"server_id":"Zk0GQ3JBSrg3oyxCRRlE09","version":"1.2.0","proto":1,"go":"go1.10.3","host":"0.0.0.0","port":4222,"max_payload":1048576,"client_id":2392} -PING -PING --ERR 'Stale Connection' -Connection closed by foreign host. -``` - -## +OK/ERR - -#### Description - -When the `verbose` connection option is set to `true` (the default value), the server acknowledges each well-formed protocol message from the client with a `+OK` message. Most NATS clients set the `verbose` option to `false` using the [`CONNECT`](#connect) message - -The `-ERR` message is used by the server indicate a protocol, authorization, or other runtime connection error to the client. Most of these errors result in the server closing the connection. - -Handling of these errors usually has to be done asynchronously. - -#### Syntax - -`+OK` - -`-ERR ` - -Some protocol errors result in the server closing the connection. Upon receiving these errors, the connection is no longer valid and the client should clean up relevant resources. These errors include: - -- `-ERR 'Unknown Protocol Operation'`: Unknown protocol error -- `-ERR 'Attempted To Connect To Route Port'`: Client attempted to connect to a route port instead of the client port -- `-ERR 'Authorization Violation'`: Client failed to authenticate to the server with credentials specified in the [`CONNECT`](#connect) message -- `-ERR 'Authorization Timeout'`: Client took too long to authenticate to the server after establishing a connection (default 1 second) -- `-ERR 'Invalid Client Protocol'`: Client specified an invalid protocol version in the [`CONNECT`](#connect) message -- `-ERR 'Maximum Control Line Exceeded'`: Message destination subject and reply subject length exceeded the maximum control line value specified by the `max_control_line` server option. The default is 1024 bytes. -- `-ERR 'Parser Error'`: Cannot parse the protocol message sent by the client -- `-ERR 'Secure Connection - TLS Required'`: The server requires TLS and the client does not have TLS enabled. -- `-ERR 'Stale Connection'`: The server hasn't received a message from the client, including a `PONG` in too long. -- `-ERR 'Maximum Connections Exceeded`': This error is sent by the server when creating a new connection and the server has exceeded the maximum number of connections specified by the `max_connections` server option. The default is 64k. -- `-ERR 'Slow Consumer'`: The server pending data size for the connection has reached the maximum size (default 10MB). -- `-ERR 'Maximum Payload Violation'`: Client attempted to publish a message with a payload size that exceeds the `max_payload` size configured on the server. This value is supplied to the client upon connection in the initial [`INFO`](#info) message. The client is expected to do proper accounting of byte size to be sent to the server in order to handle this error synchronously. - -Protocol error messages where the connection remains open are listed below. The client should not close the connection in these cases. - -- `-ERR 'Invalid Subject'`: Client sent a malformed subject (e.g. `sub foo. 90`) -- `-ERR 'Permissions Violation for Subscription to '`: The user specified in the [`CONNECT`](#connect) message does not have permission to subscribe to the subject. -- `-ERR 'Permissions Violation for Publish to '`: The user specified in the [`CONNECT`](#connect) message does not have permissions to publish to the subject. diff --git a/nats_server/securing_nats.md b/nats_server/securing_nats.md deleted file mode 100644 index c1753b8..0000000 --- a/nats_server/securing_nats.md +++ /dev/null @@ -1,7 +0,0 @@ -## Securing NATS - -The NATS server provides several forms of security: - -- Connections can be [_encrypted_ with TLS](tls.md) -- Client connections can require [_authentication_](auth_intro.md) -- Clients can require [_authorization_](authorization.md) for subjects the publish or subscribe to diff --git a/nats_streaming/channels/channels.md b/nats_streaming/channels/channels.md deleted file mode 100644 index f38ef3f..0000000 --- a/nats_streaming/channels/channels.md +++ /dev/null @@ -1,7 +0,0 @@ -# Channels - -Channels are at the heart of the NATS Streaming Server. Channels are subjects clients send data to and consume from. - -***Note: NATS Streaming server does not support wildcard for channels, that is, one cannot subscribe on `foo.*`, or `>`, etc...*** - -The number of channels can be limited (and is by default) through configuration. Messages produced to a channel are stored in a message log inside this channel. \ No newline at end of file diff --git a/nats_streaming/channels/message-log.md b/nats_streaming/channels/message-log.md deleted file mode 100644 index 058f632..0000000 --- a/nats_streaming/channels/message-log.md +++ /dev/null @@ -1,5 +0,0 @@ -# Message Log - -You can view a message log as a First In First Out (FIFO) queue. Messages are appended to the end of the log. If a limit is set globally for all channels, or specifically for this channel, when the limit is reached, older messages are removed to make room for the new ones. - -But except for the administrative size/age limit set for a message log, messages are not removed due to consumers consuming them. In fact, messages are stored regardless of the presence of subscriptions on that channel. diff --git a/nats_streaming/channels/subscriptions/regular.md b/nats_streaming/channels/subscriptions/regular.md deleted file mode 100644 index a3be9c6..0000000 --- a/nats_streaming/channels/subscriptions/regular.md +++ /dev/null @@ -1,3 +0,0 @@ -# Regular - -The state of these subscriptions is removed when they are unsubscribed or closed (which is equivalent for this type of subscription) or the client connection is closed (explicitly by the client, or closed by the server due to timeout). They do, however, survive a *server* failure (if running with a persistent store). diff --git a/nats_streaming/configuring/cfgfile.md b/nats_streaming/configuring/cfgfile.md deleted file mode 100644 index 63d09b7..0000000 --- a/nats_streaming/configuring/cfgfile.md +++ /dev/null @@ -1,163 +0,0 @@ -# Configuration File - -You can use a configuration file to configure the options specific to the NATS Streaming Server. - -Use the `-sc` or `-stan_config` command line parameter to specify the file to use. - -For the embedded NATS Server, you can use another configuration file and pass it to the Streaming Server using `-c` or `--config` command line parameters. - -Since most options do not overlap, it is possible to combine all options into a single file and specify this file using either the `-sc` or `-c` command line parameter. - -However, the option named `tls` is common to NATS Server and NATS Streaming Server. If you plan to use a single configuration file and configure TLS, -you should have all the streaming configuration included in a `streaming` map. This is actually a good practice regardless if you use TLS -or not, to protect against possible addition of new options in NATS Server that would conflict with the names of NATS Streaming options. - -For instance, you could use a single configuration file with such content: -``` -# Some NATS Server TLS Configuration -listen: localhost:5222 -tls: { - cert_file: "/path/to/server/cert_file" - key_file: "/path/to/server/key_file" - verify: true - timeout: 2 -} - -# NATS Streaming Configuration -streaming: { - cluster_id: my_cluster - - tls: { - client_cert: "/path/to/client/cert_file" - client_key: "/path/to/client/key_file" - } -} -``` - -However, if you want to avoid any possible conflict, simply use two different configuration files. - -Note the order in which options are applied during the start of a NATS Streaming server: - -1. Start with some reasonable default options. -2. If a configuration file is specified, override those options - with all options defined in the file. This includes options that are defined - but have no value specified. In this case, the zero value for the type of the - option will be used. -3. Any command line parameter override all of the previous set options. - -In general the configuration parameters are the same as the command line arguments. Below is the list of NATS Streaming parameters: - -| Parameter | Meaning | Possible Values | Usage Example | -|:----|:----|:----|:----| -| cluster_id | Cluster name | String, underscore possible | `cluster_id: "my_cluster_name"` | -| discover_prefix | Subject prefix for server discovery by clients | NATS Subject | `discover_prefix: "_STAN.Discovery"` | -| store | Store type | `memory`, `file` or `sql` | `store: "file"` | -| dir | When using a file store, this is the root directory | File path | `dir: "/path/to/storage` | -| sd | Enable debug logging | `true` or `false` | `sd: true` | -| sv | Enable trace logging | `true` or `false` | `sv: true` | -| nats_server_url | If specified, connects to an external NATS Server, otherwise starts an embedded one | NATS URL | `nats_server_url: "nats://localhost:4222"` | -| secure | If true, creates a TLS connection to the server but without the need to use TLS configuration (no NATS Server certificate verification) | `true` or `false` | `secure: true` | -| tls | TLS Configuration | Map: `tls: { ... }` | [**See details below**](#tls-configuration) | -| store_limits | Store Limits | Map: `store_limits: { ... }` | [**See details below**](#store-limits-configuration) | -| file_options | File Store specific options | Map: `file_options: { ... }` | [**See details below**](#file-options-configuration) | -| sql_options | SQL Store specific options | Map: `sql_options: { ... }` | [**See details below**](#sql-options-configuration) | -| hb_interval | Interval at which the server sends an heartbeat to a client | Duration | `hb_interval: "10s"` | -| hb_timeout | How long the server waits for a heartbeat response from the client before considering it a failed heartbeat | Duration | `hb_timeout: "10s"` | -| hb_fail_count | Count of failed heartbeats before server closes the client connection. The actual total wait is: (fail count + 1) * (hb interval + hb timeout) | Number | `hb_fail_count: 2` | -| ft_group | In Fault Tolerance mode, you can start a group of streaming servers with only one server being active while others are running in standby mode. This is the name of this FT group | String | `ft_group: "my_ft_group"` | -| partitioning | If set to true, a list of channels must be defined in store_limits/channels section. This section then serves two purposes, overriding limits for a given channel or adding it to the partition | `true` or `false` | `partitioning: true` | -| cluster | Cluster Configuration | Map: `cluster: { ... }` | [**See details below**](#cluster-configuration) | -| encrypt | Specify if server should encrypt messages (only the payload) when storing them | `true` or `false` | `encrypt: true` | -| encryption_cipher | Cipher to use for encryption. Currently support AES and CHAHA (ChaChaPoly). Defaults to AES | `AES` or `CHACHA` | `encryption_cipher: "AES"` | -| encryption_key | Encryption key. It is recommended to specify the key through the `NATS_STREAMING_ENCRYPTION_KEY` environment variable instead | String | `encryption_key: "mykey"` | - -## TLS Configuration - -Note that the Streaming Server uses a connection to a NATS Server, and so the NATS Streaming TLS Configuration -is in fact a client-side TLS configuration. - -| Parameter | Meaning | Possible Values | Usage Example | -|:----|:----|:----|:----| -| client_cert | Client key for the streaming server | File path | `client_cert: "/path/to/client/cert_file"` | -| client_key | Client certificate for the streaming server | File path | `client_key: "/path/to/client/key_file"` | -| client_ca | Client certificate CA for the streaming server | File path | `client_ca: "/path/to/client/ca_file"` | - -## Store Limits Configuration - -| Parameter | Meaning | Possible Values | Usage Example | -|:----|:----|:----|:----| -| max_channels | Maximum number of channels, 0 means unlimited | Number >= 0 | `max_channels: 100` | -| max_subs | Maximum number of subscriptions per channel, 0 means unlimited | Number >= 0 | `max_subs: 100` | -| max_msgs | Maximum number of messages per channel, 0 means unlimited | Number >= 0 | `max_msgs: 10000` | -| max_bytes | Total size of messages per channel, 0 means unlimited | Number >= 0 | `max_bytes: 1GB` | -| max_age | How long messages can stay in the log | Duration | `max_age: "24h"` | -| max_inactivity | How long without any subscription and any new message before a channel can be automatically deleted | Duration | `max_inactivity: "24h"` | -| channels | A map of channel names with specific limits | Map: `channels: { ... }` | [**See details below**](#channels) | - -## Channels - -The `channels` section is a map with the key being the channel name. For instance: -``` - channels: { - "foo": { - max_msgs: 100 - } - } -``` -For a given channel, the possible parameters are: - -| Parameter | Meaning | Possible Values | Usage Example | -|:----|:----|:----|:----| -| max_subs | Maximum number of subscriptions per channel, 0 means unlimited | Number >= 0 | `max_subs: 100` | -| max_msgs | Maximum number of messages per channel, 0 means unlimited | Number >= 0 | `max_msgs: 10000` | -| max_bytes | Total size of messages per channel, 0 means unlimited | Bytes | `max_bytes: 1GB` | -| max_age | How long messages can stay in the log | Duration | `max_age: "24h"` | -| max_inactivity | How long without any subscription and any new message before a channel can be automatically deleted | Duration | `max_inactivity: "24h"` | - -## File Options Configuration - -| Parameter | Meaning | Possible Values | Usage Example | -|:----|:----|:----|:----| -| compact | Enable/disable file compaction. Only some of the files (`clients.dat` and `subs.dat`) are subject to compaction | `true` or `false` | `compact: true` | -| compact_fragmentation | Compaction threshold (in percentage) | Number >= 0 | `compact_fragmentation: 50` | -| compact_interval | Minimum interval between attempts to compact files | Expressed in seconds | `compact_interval: 300` | -| compact_min_size | Minimum size of a file before compaction can be attempted | Bytes | `compact_min_size: 1GB` | -| buffer_size | Size of buffers that can be used to buffer write operations | Bytes | `buffer_size: 2MB` | -| crc | Define if CRC of records should be computed on reads | `true` or `false` | `crc: true` | -| crc_poly | You can select the CRC polynomial. Note that changing the value after records have been persisted would result in server failing to start complaining about data corruption | Number >= 0 | `crc_poly: 3988292384` | -| sync_on_flush | Define if server should perform "file sync" operations during a flush | `true` or `false` | `sync_on_flush: true` | -| slice_max_msgs | Define the file slice maximum number of messages. If set to 0 and a channel count limit is set, then the server will set a slice count limit automatically | Number >= 0 | `slice_max_msgs: 10000` | -| slice_max_bytes | Define the file slice maximum size (including the size of index file). If set to 0 and a channel size limit is set, then the server will set a slice bytes limit automatically | Bytes | `slice_max_bytes: 64MB` | -| slice_max_age | Define the period of time covered by a file slice, starting at when the first message is stored. If set to 0 and a channel age limit is set, then the server will set a slice age limit automatically | Duration | `slice_max_age: "24h"` | -| slice_archive_script | Define the location and name of a script to be invoked when the server discards a file slice due to limits. The script is invoked with the name of the channel, the name of data and index files. It is the responsibility of the script to then remove the unused files | File path | `slice_archive_script: "/home/nats-streaming/archive/script.sh"` | -| file_descriptors_limit | Channels translate to sub-directories under the file store's root directory. Each channel needs several files to maintain the state so the need for file descriptors increase with the number of channels. This option instructs the store to limit the concurrent use of file descriptors. Note that this is a soft limit and there may be cases when the store will use more than this number. A value of 0 means no limit. Setting a limit will probably have a performance impact | Number >= 0 | `file_descriptors_limit: 100` | -| parallel_recovery | When the server starts, the recovery of channels (directories) is done sequentially. However, when using SSDs, it may be worth setting this value to something higher than 1 to perform channels recovery in parallel | Number >= 1 | `parallel_recovery: 4` | -| read_buffer_size | Size of buffers used to read ahead from message stores. This can significantly speed up sending messages to consumers after messages have been published. Default is 2MB. Set to 0 to disable | Bytes | `read_buffer_size: 2MB` | -| auto_sync | Interval at which the store should be automatically flushed and sync'ed on disk. Default is every minute. Set to <=0 to disable | Duration | `auto_sync: "2m"` | - -## Cluster Configuration - -| Parameter | Meaning | Possible Values | Usage Example | -|:----|:----|:----|:----| -| node_id | ID of the node within the cluster if there is no stored ID | String (no whitespace) | `node_id: "node-a"` | -| bootstrap | Bootstrap the cluster if there is no existing state by electing self as leader | `true` or `false` | `bootstrap: true` | -| peers | List of cluster peer node IDs to bootstrap cluster state | List of node IDs | `peers: ["node-b", "node-c"]` | -| log_path | Directory to store log replication data | File path | `log_path: "/path/to/storage"` | -| log_cache_size | Number of log entries to cache in memory to reduce disk IO | Number >= 0 | `log_cache_size: 1024` | -| log_snapshots | Number of log snapshots to retain | Number >= 0 | `log_snapshots: 1` | -| trailing_logs | Number of log entries to leave after a snapshot and compaction | Number >= 0 | `trailing_logs: 256` | -| sync | Do a file sync after every write to the replication log and message store | `true` or `false` | `sync: true` | -| raft_logging | Enable logging from the Raft library (disabled by default) | `true` or `false` | `raft_logging: true` | -| raft_heartbeat_timeout | Specifies the time in follower state without a leader before attempting an election | Duration | `raft_heartbeat_timeout: "2s"` | -| raft_election_timeout | Specifies the time in candidate state without a leader before attempting an election | Duration | `raft_election_timeout: "2s"` | -| raft_lease_timeout | Specifies how long a leader waits without being able to contact a quorum of nodes before stepping down as leader | Duration | `raft_lease_timeout: "1s"` | -| raft_commit_timeout | Specifies the time without an Apply() operation before sending an heartbeat to ensure timely commit. Due to random staggering, may be delayed as much as 2x this value | Duration | `raft_commit_timeout: "100ms"` | - -## SQL Options Configuration - -| Parameter | Meaning | Possible Values | Usage Example | -|:----|:----|:----|:----| -| driver | Name of the SQL driver to use | `mysql` or `postgres` | `driver: "mysql"` | -| source | How to connect to the database. This is driver specific | String | `source: "ivan:pwd@/nss_db"` | -| no_caching | Enable/Disable caching for messages and subscriptions operations. The default is `false`, which means that caching is enabled | `true` or `false` | `no_caching: false` | -| max_open_conns | Maximum number of opened connections to the database. Value <= 0 means no limit. The default is 0 (unlimited) | Number | `max_open_conns: 5` | diff --git a/nats_streaming/configuring/configuring.md b/nats_streaming/configuring/configuring.md deleted file mode 100644 index 9c44dcc..0000000 --- a/nats_streaming/configuring/configuring.md +++ /dev/null @@ -1,9 +0,0 @@ -# Configuration and Administration - -NATS Streaming provides a rich set of commands and parameters to configure all aspects of the server. - - * [Command Line Arguments](cmdline.md) - * [Configuration File](cfgfile.md) - * [Store Limits](storelimits.md) - * [Persistence](persistence.md) - * [Securing](tls.md) \ No newline at end of file diff --git a/nats_streaming/configuring/filestore.md b/nats_streaming/configuring/filestore.md deleted file mode 100644 index 7bfea60..0000000 --- a/nats_streaming/configuring/filestore.md +++ /dev/null @@ -1,112 +0,0 @@ -# File Store - -For a higher level of message delivery, the server should be configured with a file store. NATS Streaming Server comes with a basic file store implementation. Various file store implementations may be added in the future. - -To start the server with a file store, you need to provide two parameters: - -```sh -nats-streaming-server -store file -dir datastore -``` -The parameter `-store` indicates what type of store to use, in this case `file`. The other (`-dir`) indicates in which directory the state should be stored. - -The first time the server is started, it will create two files in this directory, one containing some server related information (`server.dat`) another to record clients information (`clients.dat`). - -When a streaming client connects, it uses a client identification, which the server registers in this file. When the client disconnects, the client is cleared from this file. - -When the client publishes or subscribe to a new subject (also called channel), the server creates a sub-directory whose name is the subject. For instance, if the client subscribes to `foo`, and assuming that you started the server with `-dir datastore`, then you will find a directory called `datastore/foo`. In this directory you will find several files: one to record subscriptions information (`subs.dat`), and a series of files that logs the messages `msgs.1.dat`, etc... - -The number of sub-directories, which again correspond to channels, can be limited by the configuration parameter `-max_channels`. When the limit is reached, any new subscription or message published on a new channel will produce an error. - -On a given channel, the number of subscriptions can also be limited with the configuration parameter `-max_subs`. A client that tries to create a subscription on a given channel (subject) for which the limit is reached will receive an error. - -Finally, the number of stored messages for a given channel can also be limited with the parameter `-max_msgs` and/or `-max_bytes`. However, for messages, the client does not get an error when the limit is reached. The oldest messages are discarded to make room for the new messages. - -## Options - -As described in the [Configuring](../configuring/cfgfile.html#configuration-file) section, there are several options that you can use to configure a file store. - -Regardless of channel limits, you can configure message logs to be split in individual files (called file slices). You can configure -those slices by number of messages it can contain (`--file_slice_max_msgs`), the size of the file - including the corresponding index file -(`--file_slice_max_bytes`), or the period of time that a file slice should cover - starting at the time the first message is stored in -that slice (`--file_slice_max_age`). The default file store options are defined such that only the slice size is configured to 64MB. - ->**Note**: If you don't configure any slice limit but you do configure channel limits, then the server will automatically -set some limits for file slices. - -When messages accumulate in a channel, and limits are reached, older messages are removed. When the first file slice -becomes empty, the server removes this file slice (and corresponding index file). - -However, if you specify a script (`--file_slice_archive_script`), then the server will rename the slice files (data and index) -with a `.bak` extension and invoke the script with the channel name, data and index file names.
-The files are left in the channel's directory and therefore it is the script responsibility to delete those files when done. -At any rate, those files will not be recovered on a server restart, but having lots of unused files in the directory may slow -down the server restart. - -For instance, suppose the server is about to delete file slice `datastore/foo/msgs.1.dat` (and `datastore/foo/msgs.1.idx`), -and you have configured the script `/home/nats-streaming/archive_script.sh`. The server will invoke: - -``` bash -/home/nats-streaming/archive_script.sh foo datastore/foo/msgs.1.dat.bak datastore/foo/msgs.2.idx.bak -``` -Notice how the files have been renamed with the `.bak` extension so that they are not going to be recovered if -the script leave those files in place. - -As previously described, each channel corresponds to a sub-directory that contains several files. It means that the need -for file descriptors increase with the number of channels. In order to scale to ten or hundred thousands of channels, -the option `fds_limit` (or command line parameter `--file_fds_limit`) may be considered to limit the total use of file descriptors. - -Note that this is a soft limit. It is possible for the store to use more file descriptors than the given limit if the -number of concurrent read/writes to different channels is more than the said limit. It is also understood that this -may affect performance since files may need to be closed/re-opened as needed. - -## Recovery Errors - -We have added the ability for the server to truncate any file that may otherwise report an `unexpected EOF` -error during the recovery process. - -Since dataloss is likely to occur, the default behavior for the server on startup is to report recovery error and stop. -It will now print the content of the first corrupted record before exiting. - -With the `-file_truncate_bad_eof` parameter, the server will still print those bad records but truncate each file at -the position of the first corrupted record in order to successfully start. - -To prevent the use of this parameter as the default value, this option is not available in the configuration file. -Moreover, the server will fail to start if started more than once with that parameter.
-This flag may help recover from a store failure, but since data may be lost in that process, we think that the -operator needs to be aware and make an informed decision. - -Note that this flag will not help with file corruption due to bad CRC for instance. You have the option to disable -CRC on recovery with the `-file_crc=false` option. - -Let's review the impact and suggested steps for each of the server's corrupted files: - -* `server.dat`: This file contains meta data and NATS subjects used to communicate with client applications. If -a corruption is reported with this file, we would suggest that you stop all your clients, stop the server, remove -this file, restart the server. This will create a new `server.dat` file, but will not attempt to recover the -rest of the channels because the server assumes that there is no state. So you should stop and restart the -server once more. Then, you can restart all your clients. - -* `clients.dat`: This contains information about client connections. If the file is truncated to move past -an `unexpected EOF` error, this can result in no issue at all, or in client connections not being recovered, -which means that the server will not know about possible running clients, and therefore it will not try -to deliver any message to those non recovered clients, or reject incoming published messages from those clients. -It is also possible that the server recovers a client connection that was actually closed. In this case, the -server may attempt to deliver or redeliver messages unnecessarily. - -* `subs.dat`: This is a channel's subscriptions file (under the channel's directory). If this file is truncated -and some records are lost, it may result in no issue at all, or in client applications not receiving their messages -since the server will not know about them. It is also possible that acknowledged messages get redelivered -(since their ack may have been lost). - -* `msgs..dat`: This is a channel's message log (several per channel). If one of those files is truncated, then -message loss occurs. With the `unexpected EOF` errors, it is likely that only the last "file slice" of a channel will -be affected. Nevertheless, if a lower sequence file slice is truncated, then gaps in message sequence will occur. -So it would be possible for a channel to have now messages 1..100, 110..300 for instance, with messages 101 to 109 -missing. Again, this is unlikely since we expect the unexpected end-of-file errors to occur on the last slice. - -For *Clustered* mode, this flag would work only for the NATS Streaming specific store files. As you know, NATS -Streaming uses RAFT for consensus, and RAFT uses its own logs. You could try the option if the server reports -`unexpected EOF` errors for NATS Streaming file stores, however, you may want to simply delete all NATS Streaming -and RAFT stores for the failed node and restart it. By design, the other nodes in the cluster have replicated the -data, so this node will become a follower and catchup with the rest of the cluster, getting the data from the -current leader and recreating its local stores. \ No newline at end of file diff --git a/nats_tools/nsc/README.md b/nats_tools/nsc/README.md deleted file mode 100644 index 81e7fe5..0000000 --- a/nats_tools/nsc/README.md +++ /dev/null @@ -1,43 +0,0 @@ -# NATS Account Configuration - -NATS account configurations are built using the `nsc` tool. The NSC tool allows you to: - -- Create and edit Operators, Accounts, Users -- Manage subscribe and publish permissions for Users -- Add and delete Exports and Imports -- Generate Activation tokens -- Generate User credential files -- Describe Operators, Accounts, Users, and Activations -- Push account JWTs to a server or pull account JWTs from a server - -## Installation - -Installing `nsc` is easy: - -```text -curl -L https://raw.githubusercontent.com/nats-io/nsc/master/install.py | python -``` - -The script will download the latest version of `nsc` and install it into your system. - -## Tutorials - -You can find various task-oriented tutorials to working with the tool here: - -- [Basic Usage](nsc.md) -- [Configuring Streams](streams.md) -- [Configuring Services](services.md) -- [Signing Keys](signing_keys.md) -- [Revoking Users or Activations](revocation.md) -- [Working with Managed Operators](managed.md) - -## Tool Documentation - -For more specific browsing of the tool syntax, check out the `nsc` tool documentation. -It can be found within the tool itself: - -```text -> nsc help -``` - -Or an online version [here](https://nats-io.github.io/nsc). diff --git a/whats_new/whats_new_20.md b/whats_new/whats_new_20.md deleted file mode 100644 index 61a7347..0000000 --- a/whats_new/whats_new_20.md +++ /dev/null @@ -1,220 +0,0 @@ -# What's New in NATS 2.0 - -NATS 2.0 is the largest feature release since the original code base for the -server was released. NATS 2.0 was created to allow a new way of thinking about -NATS as a shared utility, solving problems at scale through distributed -security, multi-tenancy, larger networks, and secure sharing of data. - -## Rationale - -NATS 2.0 was created to address problems in large scale distributed computing. - -It is difficult at best to combine identity management end-to-end -(or end-to-edge), with data sharing, while adhering to policy and compliance. -Current distributed systems increase significantly in operational complexity -as they scale upward. Problems arise around service discovery, connectivity, -scaling for volume, and application onboarding and updates. -Disaster recovery is difficult, especially as systems have evolved to -operate in silos defined by technology rather than business needs. -As complexity increases, systems become expensive to operate in terms of time -and money. They become fragile making it difficult to deploy services and -applications hindering innovation, increasing time to value and total cost -of ownership. - -We decided to: - -* __Reduce total cost of ownership__: Users want reduced TCO for their -distributed systems. This is addressed by an easy to use technology that -can operate at global scale with simple configuration and a resilient -and cloud-native architecture. -* __Decrease Time to Value__: As systems scale, _time to value_ increases. -Operations resist change due to risk in touching a complex and fragile -system. Providing isolation contexts can help mitigate this. -* __Support manageable large scale deployments__: No data silos defined by -software, instead easily managed through software to provide exactly what the -business needs. We wanted to provide easy to configure disaster recovery. -* __Decentralize security__: Provide security supporting one -technology end-to-end where organizations may self-manage making it -easier to support a massive number of endpoints. - -To achieve this, we added a number of new features that are transparent -to existing clients with 100% backward client compatibility. - -## Accounts - -Accounts are securely isolated communication contexts that allow multi-tenancy -spanning a NATS deployment. Accounts allow users to bifurcate technology from -business driven use cases, where data silos are created by design, not software -limitations. When a client connects, it specifies an account or will default -to authentication with a global account. - -At least some services need to share data outside of their account. -Data can be securely shared between accounts with secure services and -streams. Only mutual agreement between account owners permit data flow, -and the import account has complete control over its own subject space. - -This means within an account, limitations may be set and subjects can be used -without worry of collisions with other groups or organizations. Development -groups choose any subjects without affecting the rest of the system, and open -up accounts to export or import only the services and streams they need. - -Accounts are easy, secure, and cost effective. There is one NATS deployment -to manage, but organizations and development teams can self manage with more -autonomy reducing time to value with faster, more agile development practices. - -### Service and Streams - -Services and streams are mechanisms to share messages between accounts. - -Think of a service as an RPC endpoint into an account. Behind that account -there might be many microservices working in concert to handle requests, but -from outside the account there is simply one subject exposed. - -__Services__ definition to share an endpoint: - -* Export a service to allow other accounts to import -* Import a service to allow requests to be sent securely and seamlessly to -another account - -Use cases include most applications - anything that accepts a request and returns -a response. - -__Stream__ definitions allow continuous data flow between accounts: - -* Export a stream to allow egress -* Import a stream to allow ingress - -Use cases include Observability, Metrics, and Data analytics. Any application -or endpoint reading a stream of data. - -Note that services and streams operate with __zero__ client configuration or -API changes. Services may even move between accounts, entirely transparent -to end clients. - -### System Accounts - -The system account publishes system messages under established subject patterns. -These are internal NATS system messages that may be useful to operators. - -Server initiated events and data include: - -* Client connection events -* Account connection status -* Authentication errors -* Leaf node connection events -* Server stats summary - -Tools and clients with proper privileges can request: - -* Service statistics -* Server discovery and metrics - -Account servers will also publish messages when an account changes. - -With this information and system metadata you can build useful -monitoring and anomaly detection tools. - -## Global Deployments - -NATS 2.0 supports global deployments, allowing for global topologies that -optimize for WANs while extend to the edge or devices. - -### Self Healing - -While self healing features have been part of NATS 1.X releases, we -ensured they continue to work in global deployments. These include: - -* Client and server connections automatically reconnect -* Auto-Discovery where servers exchange server topology changes with each -other and with clients, in real time with zero configuration changes and -zero downtime while being entirely transparent to clients. Clients can -failover to servers they were not originally configured with. -* NATS server clusters dynamically adjust to new or removed servers allowing -for seamless rolling upgrades and scaling up or down. - -### Superclusters - -Conceptually, superclusters are clusters of NATS clusters. Create -superclusters to deploy a truly global NATS network. Superclusters use -a novel spline based technology with a unique approach to topology, keeping -one hop semantics and optimizing WAN traffic through optimistic sends with -interest graph pruning. Superclusters provide transparent, intelligent support -for geo-distributed queue subscribers. - -### Disaster Recovery - -Superclusters inherently support disaster recovery. With geo-distributed queue -subscribers, local clients are preferred, then an RTT is used to find the lowest -latency NATS cluster containing a matching queue subscriber in the supercluster. - -What does this mean? - -Let's say you have a set of load balanced services in US East Coast -(US-EAST), another set in the EU (EU-WEST), and a supercluster consisting -of a NATS cluster in US-EAST connected to a NATS cluster in EU-WEST. Clients -in the US would connect to a US-EAST, and services connected to that cluster -would service those clients. Clients in Europe would automatically use -services connected to EU-WEST. If the services in US-EAST disconnect, -clients in US-EAST will begin using services in EU-WEST. - -Once the Eastern US services have reconnected to US-EAST, those services -will immediately begin servicing the Eastern US clients since they're local to -the NATS cluster. This is automatic and entirely transparent to the client. -There is no extra configuration in NATS servers. - -This is __zero configuration disaster recovery__. - -### Leaf Nodes - -Leaf nodes are NATS servers running in a special configuration, allowing -hub and spoke topologies to extend superclusters. - -Leaf nodes can also bridge separate security domains. e.g. IoT, mobile, web. -They are ideal for edge computing, IoT hubs, or data centers that need to be -connected to a global NATS deployment. Local applications that communicate -using the loopback interface with physical VM or Container security can -leverage leaf nodes as well. - -Leaf nodes: - -* Transparently and securely bind to a remote NATS account -* Securely bridge specific local data to a wider NATS deployment -* Are 100% transparent to clients which remain simple, lightweight, and easy to develop -* Allow for a local security scheme while using new NATS security features globally -* Can create a DMZ between a local NATS deployment and external NATS cluster or supercluster. - -## Decentralized Security - -### Operators, Accounts, and Users - -NATS 2.0 Security consists of defining Operators, Accounts, and Users -within a NATS deployment. - -* An __Operator__ provides the root of trust for the system, may represent -a company or enterprise - * Creates __Accounts__ for account administrators. An account represents -an organization, business unit, or service offering with a secure context -within the NATS deployment, for example an IT system monitoring group, a -set of microservices, or a regional IoT deployment. Account creation -would likely be managed by a central group. -* __Accounts__ define limits and may securely expose services and streams. - * Account managers create __Users__ with permissions -* __Users__ have specific credentials and permissions. - -### Trust Chain - -PKI (NKeys encoded [Ed25519](https://ed25519.cr.yp.to/)) and signed JWTs -create a hierarchy of Operators, Accounts, and Users creating a scalable -and flexible distributed security mechanism. - -* __Operators__ are represented by a self signed JWT and is the only thing that -is required to be configured in the server. This JWT is usually signed by a -master key that is kept offline. The JWT will contain valid signing keys that -can be revoked with the master updating this JWT. - * Operators will sign __Account__ JWTs with various signing keys. - * __Accounts__ sign __User__ JWTs, again with various signing keys. -* Clients or leaf nodes present __User__ credentials and a signed nonce when connecting. - * The server uses resolvers to obtain JWTs and verify the client trust chain. - -This allows for rapid change of permissions, authentication and limits, to a -secure multi-tenant NATS system. diff --git a/whats_new_20.md b/whats_new_20.md new file mode 100644 index 0000000..ee9a3a0 --- /dev/null +++ b/whats_new_20.md @@ -0,0 +1,190 @@ +# What's New in 2.0 + +NATS 2.0 is the largest feature release since the original code base for the server was released. NATS 2.0 was created to allow a new way of thinking about NATS as a shared utility, solving problems at scale through distributed security, multi-tenancy, larger networks, and secure sharing of data. + +## Rationale + +NATS 2.0 was created to address problems in large scale distributed computing. + +It is difficult at best to combine identity management end-to-end \(or end-to-edge\), with data sharing, while adhering to policy and compliance. Current distributed systems increase significantly in operational complexity as they scale upward. Problems arise around service discovery, connectivity, scaling for volume, and application onboarding and updates. Disaster recovery is difficult, especially as systems have evolved to operate in silos defined by technology rather than business needs. As complexity increases, systems become expensive to operate in terms of time and money. They become fragile making it difficult to deploy services and applications hindering innovation, increasing time to value and total cost of ownership. + +We decided to: + +* **Reduce total cost of ownership**: Users want reduced TCO for their + + distributed systems. This is addressed by an easy to use technology that + + can operate at global scale with simple configuration and a resilient + + and cloud-native architecture. + +* **Decrease Time to Value**: As systems scale, _time to value_ increases. + + Operations resist change due to risk in touching a complex and fragile + + system. Providing isolation contexts can help mitigate this. + +* **Support manageable large scale deployments**: No data silos defined by + + software, instead easily managed through software to provide exactly what the + + business needs. We wanted to provide easy to configure disaster recovery. + +* **Decentralize security**: Provide security supporting one + + technology end-to-end where organizations may self-manage making it + + easier to support a massive number of endpoints. + +To achieve this, we added a number of new features that are transparent to existing clients with 100% backward client compatibility. + +## Accounts + +Accounts are securely isolated communication contexts that allow multi-tenancy spanning a NATS deployment. Accounts allow users to bifurcate technology from business driven use cases, where data silos are created by design, not software limitations. When a client connects, it specifies an account or will default to authentication with a global account. + +At least some services need to share data outside of their account. Data can be securely shared between accounts with secure services and streams. Only mutual agreement between account owners permit data flow, and the import account has complete control over its own subject space. + +This means within an account, limitations may be set and subjects can be used without worry of collisions with other groups or organizations. Development groups choose any subjects without affecting the rest of the system, and open up accounts to export or import only the services and streams they need. + +Accounts are easy, secure, and cost effective. There is one NATS deployment to manage, but organizations and development teams can self manage with more autonomy reducing time to value with faster, more agile development practices. + +### Service and Streams + +Services and streams are mechanisms to share messages between accounts. + +Think of a service as an RPC endpoint into an account. Behind that account there might be many microservices working in concert to handle requests, but from outside the account there is simply one subject exposed. + +**Services** definition to share an endpoint: + +* Export a service to allow other accounts to import +* Import a service to allow requests to be sent securely and seamlessly to + + another account + +Use cases include most applications - anything that accepts a request and returns a response. + +**Stream** definitions allow continuous data flow between accounts: + +* Export a stream to allow egress +* Import a stream to allow ingress + +Use cases include Observability, Metrics, and Data analytics. Any application or endpoint reading a stream of data. + +Note that services and streams operate with **zero** client configuration or API changes. Services may even move between accounts, entirely transparent to end clients. + +### System Accounts + +The system account publishes system messages under established subject patterns. These are internal NATS system messages that may be useful to operators. + +Server initiated events and data include: + +* Client connection events +* Account connection status +* Authentication errors +* Leaf node connection events +* Server stats summary + +Tools and clients with proper privileges can request: + +* Service statistics +* Server discovery and metrics + +Account servers will also publish messages when an account changes. + +With this information and system metadata you can build useful monitoring and anomaly detection tools. + +## Global Deployments + +NATS 2.0 supports global deployments, allowing for global topologies that optimize for WANs while extend to the edge or devices. + +### Self Healing + +While self healing features have been part of NATS 1.X releases, we ensured they continue to work in global deployments. These include: + +* Client and server connections automatically reconnect +* Auto-Discovery where servers exchange server topology changes with each + + other and with clients, in real time with zero configuration changes and + + zero downtime while being entirely transparent to clients. Clients can + + failover to servers they were not originally configured with. + +* NATS server clusters dynamically adjust to new or removed servers allowing + + for seamless rolling upgrades and scaling up or down. + +### Superclusters + +Conceptually, superclusters are clusters of NATS clusters. Create superclusters to deploy a truly global NATS network. Superclusters use a novel spline based technology with a unique approach to topology, keeping one hop semantics and optimizing WAN traffic through optimistic sends with interest graph pruning. Superclusters provide transparent, intelligent support for geo-distributed queue subscribers. + +### Disaster Recovery + +Superclusters inherently support disaster recovery. With geo-distributed queue subscribers, local clients are preferred, then an RTT is used to find the lowest latency NATS cluster containing a matching queue subscriber in the supercluster. + +What does this mean? + +Let's say you have a set of load balanced services in US East Coast \(US-EAST\), another set in the EU \(EU-WEST\), and a supercluster consisting of a NATS cluster in US-EAST connected to a NATS cluster in EU-WEST. Clients in the US would connect to a US-EAST, and services connected to that cluster would service those clients. Clients in Europe would automatically use services connected to EU-WEST. If the services in US-EAST disconnect, clients in US-EAST will begin using services in EU-WEST. + +Once the Eastern US services have reconnected to US-EAST, those services will immediately begin servicing the Eastern US clients since they're local to the NATS cluster. This is automatic and entirely transparent to the client. There is no extra configuration in NATS servers. + +This is **zero configuration disaster recovery**. + +### Leaf Nodes + +Leaf nodes are NATS servers running in a special configuration, allowing hub and spoke topologies to extend superclusters. + +Leaf nodes can also bridge separate security domains. e.g. IoT, mobile, web. They are ideal for edge computing, IoT hubs, or data centers that need to be connected to a global NATS deployment. Local applications that communicate using the loopback interface with physical VM or Container security can leverage leaf nodes as well. + +Leaf nodes: + +* Transparently and securely bind to a remote NATS account +* Securely bridge specific local data to a wider NATS deployment +* Are 100% transparent to clients which remain simple, lightweight, and easy to develop +* Allow for a local security scheme while using new NATS security features globally +* Can create a DMZ between a local NATS deployment and external NATS cluster or supercluster. + +## Decentralized Security + +### Operators, Accounts, and Users + +NATS 2.0 Security consists of defining Operators, Accounts, and Users within a NATS deployment. + +* An **Operator** provides the root of trust for the system, may represent + + a company or enterprise + + * Creates **Accounts** for account administrators. An account represents + + an organization, business unit, or service offering with a secure context + + within the NATS deployment, for example an IT system monitoring group, a + + set of microservices, or a regional IoT deployment. Account creation + + would likely be managed by a central group. + +* **Accounts** define limits and may securely expose services and streams. + * Account managers create **Users** with permissions +* **Users** have specific credentials and permissions. + +### Trust Chain + +PKI \(NKeys encoded [Ed25519](https://ed25519.cr.yp.to/)\) and signed JWTs create a hierarchy of Operators, Accounts, and Users creating a scalable and flexible distributed security mechanism. + +* **Operators** are represented by a self signed JWT and is the only thing that + + is required to be configured in the server. This JWT is usually signed by a + + master key that is kept offline. The JWT will contain valid signing keys that + + can be revoked with the master updating this JWT. + + * Operators will sign **Account** JWTs with various signing keys. + * **Accounts** sign **User** JWTs, again with various signing keys. + +* Clients or leaf nodes present **User** credentials and a signed nonce when connecting. + * The server uses resolvers to obtain JWTs and verify the client trust chain. + +This allows for rapid change of permissions, authentication and limits, to a secure multi-tenant NATS system. +