GitBook: [master] 326 pages and 16 assets modified
65
.gitbook/assets/acks.svg
Normal file
@ -0,0 +1,65 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
|
||||
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<!-- Generated by graphviz version 2.40.1 (20161225.0304)
|
||||
-->
|
||||
<!-- Title: nats_request_reply Pages: 1 -->
|
||||
<svg width="359pt" height="162pt"
|
||||
viewBox="0.00 0.00 358.71 161.86" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 157.8639)">
|
||||
<title>nats_request_reply</title>
|
||||
<polygon fill="#ffffff" stroke="transparent" points="-4,4 -4,-157.8639 354.7072,-157.8639 354.7072,4 -4,4"/>
|
||||
<!-- publisher -->
|
||||
<g id="node1" class="node">
|
||||
<title>publisher</title>
|
||||
<path fill="none" stroke="#000000" d="M56.8346,-49.231C56.8346,-49.231 12.0551,-49.231 12.0551,-49.231 6.0551,-49.231 .0551,-43.231 .0551,-37.231 .0551,-37.231 .0551,-25.231 .0551,-25.231 .0551,-19.231 6.0551,-13.231 12.0551,-13.231 12.0551,-13.231 56.8346,-13.231 56.8346,-13.231 62.8346,-13.231 68.8346,-19.231 68.8346,-25.231 68.8346,-25.231 68.8346,-37.231 68.8346,-37.231 68.8346,-43.231 62.8346,-49.231 56.8346,-49.231"/>
|
||||
<text text-anchor="middle" x="34.4448" y="-27.031" font-family="Times,serif" font-size="14.00" fill="#000000">Publisher</text>
|
||||
</g>
|
||||
<!-- subject -->
|
||||
<g id="node2" class="node">
|
||||
<title>subject</title>
|
||||
<ellipse fill="none" stroke="#000000" cx="171.8604" cy="-117.231" rx="36.7663" ry="36.7663"/>
|
||||
<text text-anchor="middle" x="171.8604" y="-113.031" font-family="Times,serif" font-size="14.00" fill="#000000">Subject</text>
|
||||
</g>
|
||||
<!-- publisher->subject -->
|
||||
<g id="edge1" class="edge">
|
||||
<title>publisher->subject</title>
|
||||
<path fill="none" stroke="#000000" d="M63.2516,-49.2594C83.2612,-61.7822 110.1803,-78.6291 132.2123,-92.4176"/>
|
||||
<polygon fill="#000000" stroke="#000000" points="130.3666,-95.3914 140.7002,-97.7297 134.0802,-89.4576 130.3666,-95.3914"/>
|
||||
<text text-anchor="middle" x="102.0586" y="-84.031" font-family="Times,serif" font-size="14.00" fill="#000000">msg1</text>
|
||||
</g>
|
||||
<!-- reply -->
|
||||
<g id="node3" class="node">
|
||||
<title>reply</title>
|
||||
<ellipse fill="none" stroke="#000000" cx="171.8604" cy="-31.231" rx="31.4636" ry="31.4636"/>
|
||||
<text text-anchor="middle" x="171.8604" y="-27.031" font-family="Times,serif" font-size="14.00" fill="#000000">Reply</text>
|
||||
</g>
|
||||
<!-- publisher->reply -->
|
||||
<!-- sub1 -->
|
||||
<g id="node4" class="node">
|
||||
<title>sub1</title>
|
||||
<path fill="none" stroke="#000000" d="M338.6453,-91.231C338.6453,-91.231 286.8931,-91.231 286.8931,-91.231 280.8931,-91.231 274.8931,-85.231 274.8931,-79.231 274.8931,-79.231 274.8931,-67.231 274.8931,-67.231 274.8931,-61.231 280.8931,-55.231 286.8931,-55.231 286.8931,-55.231 338.6453,-55.231 338.6453,-55.231 344.6453,-55.231 350.6453,-61.231 350.6453,-67.231 350.6453,-67.231 350.6453,-79.231 350.6453,-79.231 350.6453,-85.231 344.6453,-91.231 338.6453,-91.231"/>
|
||||
<text text-anchor="middle" x="312.7692" y="-69.031" font-family="Times,serif" font-size="14.00" fill="#000000">Subscriber</text>
|
||||
</g>
|
||||
<!-- subject->sub1 -->
|
||||
<g id="edge3" class="edge">
|
||||
<title>subject->sub1</title>
|
||||
<path fill="none" stroke="#000000" d="M207.0542,-106.2414C224.547,-100.7791 245.9472,-94.0967 264.9064,-88.1765"/>
|
||||
<polygon fill="#000000" stroke="#000000" points="266.0625,-91.4823 274.5647,-85.1607 263.976,-84.8005 266.0625,-91.4823"/>
|
||||
<text text-anchor="middle" x="241.6623" y="-101.031" font-family="Times,serif" font-size="14.00" fill="#000000">msg1</text>
|
||||
</g>
|
||||
<!-- reply->publisher -->
|
||||
<g id="edge5" class="edge">
|
||||
<title>reply->publisher</title>
|
||||
<path fill="none" stroke="#000000" d="M140.9468,-36.9759C122.7803,-38.0548 99.4966,-38.2651 79.3354,-37.6068"/>
|
||||
<polygon fill="#000000" stroke="#000000" points="79.257,-34.1006 69.1206,-37.1834 78.967,-41.0946 79.257,-34.1006"/>
|
||||
</g>
|
||||
<!-- sub1->reply -->
|
||||
<g id="edge4" class="edge">
|
||||
<title>sub1->reply</title>
|
||||
<path fill="none" stroke="#000000" d="M274.7888,-61.9103C255.2759,-56.0942 231.509,-49.0101 211.7317,-43.1152"/>
|
||||
<polygon fill="#000000" stroke="#000000" points="212.672,-39.7434 202.0889,-40.241 210.6725,-46.4517 212.672,-39.7434"/>
|
||||
<text text-anchor="middle" x="241.6623" y="-59.031" font-family="Times,serif" font-size="14.00" fill="#000000">ack</text>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 4.2 KiB |
58
.gitbook/assets/intro.svg
Normal file
@ -0,0 +1,58 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
|
||||
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<!-- Generated by graphviz version 2.40.1 (20161225.0304)
|
||||
-->
|
||||
<!-- Title: nats Pages: 1 -->
|
||||
<svg width="296pt" height="171pt"
|
||||
viewBox="0.00 0.00 296.00 171.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 167)">
|
||||
<title>nats</title>
|
||||
<polygon fill="#ffffff" stroke="transparent" points="-4,4 -4,-167 292,-167 292,4 -4,4"/>
|
||||
<!-- publisher -->
|
||||
<g id="node1" class="node">
|
||||
<title>publisher</title>
|
||||
<polygon fill="none" stroke="#000000" points="4.3018,-118.5 4.3018,-162.5 111.6982,-162.5 111.6982,-118.5 4.3018,-118.5"/>
|
||||
<text text-anchor="middle" x="58" y="-147.3" font-family="Times,serif" font-size="14.00" fill="#000000">Application 1</text>
|
||||
<polyline fill="none" stroke="#000000" points="4.3018,-140.5 111.6982,-140.5 "/>
|
||||
<text text-anchor="middle" x="58" y="-125.3" font-family="Times,serif" font-size="14.00" fill="#000000">NATS Publisher</text>
|
||||
</g>
|
||||
<!-- natsserver -->
|
||||
<g id="node3" class="node">
|
||||
<title>natsserver</title>
|
||||
<polygon fill="none" stroke="#000000" points="288,-82 0,-82 0,-81 288,-81 288,-82"/>
|
||||
</g>
|
||||
<!-- publisher--natsserver -->
|
||||
<g id="edge1" class="edge">
|
||||
<title>publisher:nats--natsserver</title>
|
||||
<path fill="none" stroke="#000000" stroke-width="2" d="M58,-118.3672C58,-105.5168 58,-85.6791 58,-82.0725"/>
|
||||
</g>
|
||||
<!-- application -->
|
||||
<g id="node2" class="node">
|
||||
<title>application</title>
|
||||
<polygon fill="none" stroke="#000000" points="183.7017,-118.5 183.7017,-162.5 276.2983,-162.5 276.2983,-118.5 183.7017,-118.5"/>
|
||||
<text text-anchor="middle" x="230" y="-147.3" font-family="Times,serif" font-size="14.00" fill="#000000">Application 3</text>
|
||||
<polyline fill="none" stroke="#000000" points="183.7017,-140.5 276.2983,-140.5 "/>
|
||||
<text text-anchor="middle" x="230" y="-125.3" font-family="Times,serif" font-size="14.00" fill="#000000"> </text>
|
||||
</g>
|
||||
<!-- application--natsserver -->
|
||||
<g id="edge2" class="edge">
|
||||
<title>application:nats--natsserver</title>
|
||||
<path fill="none" stroke="#000000" d="M230,-118.3672C230,-105.5168 230,-85.6791 230,-82.0725"/>
|
||||
</g>
|
||||
<!-- subscriber -->
|
||||
<g id="node4" class="node">
|
||||
<title>subscriber</title>
|
||||
<polygon fill="none" stroke="#000000" points="86.8086,-.5 86.8086,-44.5 201.1914,-44.5 201.1914,-.5 86.8086,-.5"/>
|
||||
<text text-anchor="middle" x="144" y="-29.3" font-family="Times,serif" font-size="14.00" fill="#000000">NATS Subscriber</text>
|
||||
<polyline fill="none" stroke="#000000" points="86.8086,-22.5 201.1914,-22.5 "/>
|
||||
<text text-anchor="middle" x="144" y="-7.3" font-family="Times,serif" font-size="14.00" fill="#000000">Application 2</text>
|
||||
</g>
|
||||
<!-- natsserver--subscriber -->
|
||||
<g id="edge3" class="edge">
|
||||
<title>natsserver--subscriber:nats</title>
|
||||
<path fill="none" stroke="#000000" stroke-width="2" d="M144,-80.9609C144,-80.9609 144,-54.7842 144,-54.7842"/>
|
||||
<polygon fill="#000000" stroke="#000000" stroke-width="2" points="147.5001,-54.7842 144,-44.7842 140.5001,-54.7842 147.5001,-54.7842"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 3.1 KiB |
67
.gitbook/assets/nats_streaming.svg
Normal file
@ -0,0 +1,67 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
|
||||
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<!-- Generated by graphviz version 2.40.1 (20161225.0304)
|
||||
-->
|
||||
<!-- Title: nats_streaming Pages: 1 -->
|
||||
<svg width="350pt" height="221pt"
|
||||
viewBox="0.00 0.00 349.53 221.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 217)">
|
||||
<title>nats_streaming</title>
|
||||
<polygon fill="#ffffff" stroke="transparent" points="-4,4 -4,-217 345.5327,-217 345.5327,4 -4,4"/>
|
||||
<g id="clust1" class="cluster">
|
||||
<title>cluster_nats_streaming_server</title>
|
||||
<polygon fill="none" stroke="#000000" points="33.5327,-44 33.5327,-118 333.5327,-118 333.5327,-44 33.5327,-44"/>
|
||||
<text text-anchor="middle" x="183.5327" y="-50.8" font-family="Times,serif" font-size="14.00" fill="#000000">NATS Streaming Server</text>
|
||||
</g>
|
||||
<!-- application -->
|
||||
<g id="node1" class="node">
|
||||
<title>application</title>
|
||||
<polygon fill="none" stroke="#000000" points="0,-146.5 0,-212.5 175.0654,-212.5 175.0654,-146.5 0,-146.5"/>
|
||||
<text text-anchor="middle" x="87.5327" y="-197.3" font-family="Times,serif" font-size="14.00" fill="#000000">Application Code</text>
|
||||
<polyline fill="none" stroke="#000000" points="0,-190.5 175.0654,-190.5 "/>
|
||||
<text text-anchor="middle" x="87.5327" y="-175.3" font-family="Times,serif" font-size="14.00" fill="#000000">NATS Streaming Client API</text>
|
||||
<polyline fill="none" stroke="#000000" points="0,-168.5 175.0654,-168.5 "/>
|
||||
<text text-anchor="middle" x="87.5327" y="-153.3" font-family="Times,serif" font-size="14.00" fill="#000000">NATS Client API</text>
|
||||
</g>
|
||||
<!-- nats_server -->
|
||||
<g id="node2" class="node">
|
||||
<title>nats_server</title>
|
||||
<polygon fill="none" stroke="#000000" points="133.0776,-110 41.9878,-110 41.9878,-74 133.0776,-74 133.0776,-110"/>
|
||||
<text text-anchor="middle" x="87.5327" y="-87.8" font-family="Times,serif" font-size="14.00" fill="#000000">NATS Server</text>
|
||||
</g>
|
||||
<!-- application->nats_server -->
|
||||
<g id="edge2" class="edge">
|
||||
<title>application:nats->nats_server</title>
|
||||
<path fill="none" stroke="#000000" stroke-width="2" d="M87.5327,-136.3888C87.5327,-136.3888 87.5327,-120.1041 87.5327,-120.1041"/>
|
||||
<polygon fill="#000000" stroke="#000000" stroke-width="2" points="91.0328,-120.1041 87.5327,-110.1041 84.0328,-120.1041 91.0328,-120.1041"/>
|
||||
<polygon fill="#000000" stroke="#000000" stroke-width="2" points="84.0328,-136.3888 87.5327,-146.3888 91.0328,-136.3888 84.0328,-136.3888"/>
|
||||
</g>
|
||||
<!-- streaming_module -->
|
||||
<g id="node3" class="node">
|
||||
<title>streaming_module</title>
|
||||
<polygon fill="none" stroke="#000000" points="325.6301,-110 205.4354,-110 205.4354,-74 325.6301,-74 325.6301,-110"/>
|
||||
<text text-anchor="middle" x="265.5327" y="-87.8" font-family="Times,serif" font-size="14.00" fill="#000000">Streaming Module</text>
|
||||
</g>
|
||||
<!-- nats_server->streaming_module -->
|
||||
<g id="edge1" class="edge">
|
||||
<title>nats_server->streaming_module</title>
|
||||
<path fill="none" stroke="#000000" stroke-width="2" d="M143.3721,-92C143.3721,-92 195.4077,-92 195.4077,-92"/>
|
||||
<polygon fill="#000000" stroke="#000000" stroke-width="2" points="195.4077,-95.5 205.4077,-92 195.4077,-88.5 195.4077,-95.5"/>
|
||||
<polygon fill="#000000" stroke="#000000" stroke-width="2" points="143.3721,-88.5 133.3721,-92 143.3721,-95.5 143.3721,-88.5"/>
|
||||
</g>
|
||||
<!-- storage -->
|
||||
<g id="node4" class="node">
|
||||
<title>storage</title>
|
||||
<path fill="none" stroke="#000000" d="M281.9621,-36C281.9621,-36 249.1033,-36 249.1033,-36 243.1033,-36 237.1033,-30 237.1033,-24 237.1033,-24 237.1033,-12 237.1033,-12 237.1033,-6 243.1033,0 249.1033,0 249.1033,0 281.9621,0 281.9621,0 287.9621,0 293.9621,-6 293.9621,-12 293.9621,-12 293.9621,-24 293.9621,-24 293.9621,-30 287.9621,-36 281.9621,-36"/>
|
||||
<text text-anchor="middle" x="265.5327" y="-13.8" font-family="Times,serif" font-size="14.00" fill="#000000">storage</text>
|
||||
</g>
|
||||
<!-- streaming_module->storage -->
|
||||
<g id="edge3" class="edge">
|
||||
<title>streaming_module->storage</title>
|
||||
<path fill="none" stroke="#000000" stroke-width="2" d="M265.5327,-63.7079C265.5327,-63.7079 265.5327,-46.0817 265.5327,-46.0817"/>
|
||||
<polygon fill="#000000" stroke="#000000" stroke-width="2" points="269.0328,-46.0817 265.5327,-36.0817 262.0328,-46.0817 269.0328,-46.0817"/>
|
||||
<polygon fill="#000000" stroke="#000000" stroke-width="2" points="262.0328,-63.7078 265.5327,-73.7079 269.0328,-63.7079 262.0328,-63.7078"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 4.4 KiB |
68
.gitbook/assets/noecho.svg
Normal file
@ -0,0 +1,68 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
|
||||
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<!-- Generated by graphviz version 2.40.1 (20161225.0304)
|
||||
-->
|
||||
<!-- Title: %3 Pages: 1 -->
|
||||
<svg width="429pt" height="155pt"
|
||||
viewBox="0.00 0.00 429.14 154.63" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 150.6329)">
|
||||
<title>%3</title>
|
||||
<polygon fill="#ffffff" stroke="transparent" points="-4,4 -4,-150.6329 425.1437,-150.6329 425.1437,4 -4,4"/>
|
||||
<g id="clust1" class="cluster">
|
||||
<title>cluster_1</title>
|
||||
<path fill="none" stroke="#000000" d="M17,-10.6329C17,-10.6329 90.876,-10.6329 90.876,-10.6329 96.876,-10.6329 102.876,-16.6329 102.876,-22.6329 102.876,-22.6329 102.876,-126.6329 102.876,-126.6329 102.876,-132.6329 96.876,-138.6329 90.876,-138.6329 90.876,-138.6329 17,-138.6329 17,-138.6329 11,-138.6329 5,-132.6329 5,-126.6329 5,-126.6329 5,-22.6329 5,-22.6329 5,-16.6329 11,-10.6329 17,-10.6329"/>
|
||||
<text text-anchor="middle" x="53.938" y="-123.4329" font-family="Times,serif" font-size="14.00" fill="#000000">Connection #1</text>
|
||||
</g>
|
||||
<g id="clust2" class="cluster">
|
||||
<title>cluster_2</title>
|
||||
<path fill="none" stroke="#000000" d="M330.2678,-10.6329C330.2678,-10.6329 404.1437,-10.6329 404.1437,-10.6329 410.1437,-10.6329 416.1437,-16.6329 416.1437,-22.6329 416.1437,-22.6329 416.1437,-72.6329 416.1437,-72.6329 416.1437,-78.6329 410.1437,-84.6329 404.1437,-84.6329 404.1437,-84.6329 330.2678,-84.6329 330.2678,-84.6329 324.2678,-84.6329 318.2678,-78.6329 318.2678,-72.6329 318.2678,-72.6329 318.2678,-22.6329 318.2678,-22.6329 318.2678,-16.6329 324.2678,-10.6329 330.2678,-10.6329"/>
|
||||
<text text-anchor="middle" x="367.2057" y="-69.4329" font-family="Times,serif" font-size="14.00" fill="#000000">Connection #2</text>
|
||||
</g>
|
||||
<!-- publisher -->
|
||||
<g id="node1" class="node">
|
||||
<title>publisher</title>
|
||||
<path fill="none" stroke="#000000" d="M76.3277,-108.6329C76.3277,-108.6329 31.5483,-108.6329 31.5483,-108.6329 25.5483,-108.6329 19.5483,-102.6329 19.5483,-96.6329 19.5483,-96.6329 19.5483,-84.6329 19.5483,-84.6329 19.5483,-78.6329 25.5483,-72.6329 31.5483,-72.6329 31.5483,-72.6329 76.3277,-72.6329 76.3277,-72.6329 82.3277,-72.6329 88.3277,-78.6329 88.3277,-84.6329 88.3277,-84.6329 88.3277,-96.6329 88.3277,-96.6329 88.3277,-102.6329 82.3277,-108.6329 76.3277,-108.6329"/>
|
||||
<text text-anchor="middle" x="53.938" y="-86.4329" font-family="Times,serif" font-size="14.00" fill="#000000">Publisher</text>
|
||||
</g>
|
||||
<!-- subject -->
|
||||
<g id="node4" class="node">
|
||||
<title>subject</title>
|
||||
<ellipse fill="none" stroke="#000000" cx="230.297" cy="-36.6329" rx="36.7663" ry="36.7663"/>
|
||||
<text text-anchor="middle" x="230.297" y="-32.4329" font-family="Times,serif" font-size="14.00" fill="#000000">Subject</text>
|
||||
</g>
|
||||
<!-- publisher->subject -->
|
||||
<g id="edge1" class="edge">
|
||||
<title>publisher->subject</title>
|
||||
<path fill="none" stroke="#000000" d="M88.3903,-80.7497C112.8119,-73.6694 146.3209,-63.8034 175.6641,-54.6329 178.957,-53.6038 182.3561,-52.5246 185.7727,-51.4276"/>
|
||||
<polygon fill="#000000" stroke="#000000" points="186.9407,-54.7284 195.3745,-48.3158 184.7825,-48.0694 186.9407,-54.7284"/>
|
||||
<text text-anchor="middle" x="144.27" y="-75.4329" font-family="Times,serif" font-size="14.00" fill="#000000">msg</text>
|
||||
</g>
|
||||
<!-- subscriber_1 -->
|
||||
<g id="node2" class="node">
|
||||
<title>subscriber_1</title>
|
||||
<path fill="none" stroke="#000000" d="M79.8141,-54.6329C79.8141,-54.6329 28.0619,-54.6329 28.0619,-54.6329 22.0619,-54.6329 16.0619,-48.6329 16.0619,-42.6329 16.0619,-42.6329 16.0619,-30.6329 16.0619,-30.6329 16.0619,-24.6329 22.0619,-18.6329 28.0619,-18.6329 28.0619,-18.6329 79.8141,-18.6329 79.8141,-18.6329 85.8141,-18.6329 91.8141,-24.6329 91.8141,-30.6329 91.8141,-30.6329 91.8141,-42.6329 91.8141,-42.6329 91.8141,-48.6329 85.8141,-54.6329 79.8141,-54.6329"/>
|
||||
<text text-anchor="middle" x="53.938" y="-32.4329" font-family="Times,serif" font-size="14.00" fill="#000000">Subscriber</text>
|
||||
</g>
|
||||
<!-- subscriber_2 -->
|
||||
<g id="node3" class="node">
|
||||
<title>subscriber_2</title>
|
||||
<path fill="none" stroke="#000000" d="M393.0818,-54.6329C393.0818,-54.6329 341.3297,-54.6329 341.3297,-54.6329 335.3297,-54.6329 329.3297,-48.6329 329.3297,-42.6329 329.3297,-42.6329 329.3297,-30.6329 329.3297,-30.6329 329.3297,-24.6329 335.3297,-18.6329 341.3297,-18.6329 341.3297,-18.6329 393.0818,-18.6329 393.0818,-18.6329 399.0818,-18.6329 405.0818,-24.6329 405.0818,-30.6329 405.0818,-30.6329 405.0818,-42.6329 405.0818,-42.6329 405.0818,-48.6329 399.0818,-54.6329 393.0818,-54.6329"/>
|
||||
<text text-anchor="middle" x="367.2057" y="-32.4329" font-family="Times,serif" font-size="14.00" fill="#000000">Subscriber</text>
|
||||
</g>
|
||||
<!-- subject->subscriber_1 -->
|
||||
<g id="edge2" class="edge">
|
||||
<title>subject->subscriber_1</title>
|
||||
<path fill="none" stroke="#000000" stroke-dasharray="5,2" d="M193.613,-36.6329C167.1863,-36.6329 131.2603,-36.6329 102.4619,-36.6329"/>
|
||||
<polygon fill="#000000" stroke="#000000" points="102.2053,-33.133 92.2053,-36.6329 102.2052,-40.133 102.2053,-33.133"/>
|
||||
<text text-anchor="middle" x="144.27" y="-39.4329" font-family="Times,serif" font-size="14.00" fill="#000000">echo'd msg</text>
|
||||
</g>
|
||||
<!-- subject->subscriber_2 -->
|
||||
<g id="edge3" class="edge">
|
||||
<title>subject->subscriber_2</title>
|
||||
<path fill="none" stroke="#000000" d="M266.986,-36.6329C282.8596,-36.6329 301.6613,-36.6329 318.6668,-36.6329"/>
|
||||
<polygon fill="#000000" stroke="#000000" points="318.9809,-40.133 328.9809,-36.6329 318.9808,-33.133 318.9809,-40.133"/>
|
||||
<text text-anchor="middle" x="296.5988" y="-39.4329" font-family="Times,serif" font-size="14.00" fill="#000000">msg</text>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 5.6 KiB |
39
.gitbook/assets/pingpong.svg
Normal file
@ -0,0 +1,39 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
|
||||
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<!-- Generated by graphviz version 2.40.1 (20161225.0304)
|
||||
-->
|
||||
<!-- Title: g Pages: 1 -->
|
||||
<svg width="243pt" height="80pt"
|
||||
viewBox="0.00 0.00 242.84 80.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 76)">
|
||||
<title>g</title>
|
||||
<polygon fill="#ffffff" stroke="transparent" points="-4,4 -4,-76 238.8447,-76 238.8447,4 -4,4"/>
|
||||
<!-- client -->
|
||||
<g id="node1" class="node">
|
||||
<title>client</title>
|
||||
<path fill="none" stroke="#000000" d="M76.5917,-54C76.5917,-54 12.1358,-54 12.1358,-54 6.1358,-54 .1358,-48 .1358,-42 .1358,-42 .1358,-30 .1358,-30 .1358,-24 6.1358,-18 12.1358,-18 12.1358,-18 76.5917,-18 76.5917,-18 82.5917,-18 88.5917,-24 88.5917,-30 88.5917,-30 88.5917,-42 88.5917,-42 88.5917,-48 82.5917,-54 76.5917,-54"/>
|
||||
<text text-anchor="middle" x="44.3638" y="-31.8" font-family="Times,serif" font-size="14.00" fill="#000000">NATS Client</text>
|
||||
</g>
|
||||
<!-- natsserver -->
|
||||
<g id="node2" class="node">
|
||||
<title>natsserver</title>
|
||||
<ellipse fill="none" stroke="#000000" cx="198.8447" cy="-36" rx="36" ry="36"/>
|
||||
<text text-anchor="middle" x="198.8447" y="-31.8" font-family="Times,serif" font-size="14.00" fill="#000000">nats-server</text>
|
||||
</g>
|
||||
<!-- client->natsserver -->
|
||||
<g id="edge1" class="edge">
|
||||
<title>client->natsserver</title>
|
||||
<path fill="none" stroke="#000000" d="M88.6318,-36C108.5997,-36 132.1868,-36 152.4062,-36"/>
|
||||
<polygon fill="#000000" stroke="#000000" points="152.6357,-39.5001 162.6357,-36 152.6357,-32.5001 152.6357,-39.5001"/>
|
||||
<text text-anchor="middle" x="125.7861" y="-38.8" font-family="Times,serif" font-size="14.00" fill="#000000">PING</text>
|
||||
</g>
|
||||
<!-- natsserver->client -->
|
||||
<g id="edge2" class="edge">
|
||||
<title>natsserver->client</title>
|
||||
<path fill="none" stroke="#000000" d="M165.2729,-22.9664C158.6007,-20.9033 151.5753,-19.0922 144.8447,-18 128.1225,-15.2864 123.5016,-15.6277 106.7275,-18 104.0479,-18.379 101.3222,-18.8453 98.5826,-19.3791"/>
|
||||
<polygon fill="#000000" stroke="#000000" points="97.6683,-15.9967 88.6596,-21.5728 99.1794,-22.8316 97.6683,-15.9967"/>
|
||||
<text text-anchor="middle" x="125.7861" y="-20.8" font-family="Times,serif" font-size="14.00" fill="#000000">PONG</text>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 2.4 KiB |
71
.gitbook/assets/pubsub.svg
Normal file
@ -0,0 +1,71 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
|
||||
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<!-- Generated by graphviz version 2.40.1 (20161225.0304)
|
||||
-->
|
||||
<!-- Title: nats_pub_sub Pages: 1 -->
|
||||
<svg width="359pt" height="152pt"
|
||||
viewBox="0.00 0.00 358.71 152.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 148)">
|
||||
<title>nats_pub_sub</title>
|
||||
<polygon fill="#ffffff" stroke="transparent" points="-4,4 -4,-148 354.7072,-148 354.7072,4 -4,4"/>
|
||||
<!-- publisher -->
|
||||
<g id="node1" class="node">
|
||||
<title>publisher</title>
|
||||
<path fill="none" stroke="#000000" d="M56.8346,-90C56.8346,-90 12.0551,-90 12.0551,-90 6.0551,-90 .0551,-84 .0551,-78 .0551,-78 .0551,-66 .0551,-66 .0551,-60 6.0551,-54 12.0551,-54 12.0551,-54 56.8346,-54 56.8346,-54 62.8346,-54 68.8346,-60 68.8346,-66 68.8346,-66 68.8346,-78 68.8346,-78 68.8346,-84 62.8346,-90 56.8346,-90"/>
|
||||
<text text-anchor="middle" x="34.4448" y="-67.8" font-family="Times,serif" font-size="14.00" fill="#000000">Publisher</text>
|
||||
</g>
|
||||
<!-- subject -->
|
||||
<g id="node2" class="node">
|
||||
<title>subject</title>
|
||||
<ellipse fill="none" stroke="#000000" cx="171.8604" cy="-72" rx="36.7663" ry="36.7663"/>
|
||||
<text text-anchor="middle" x="171.8604" y="-67.8" font-family="Times,serif" font-size="14.00" fill="#000000">Subject</text>
|
||||
</g>
|
||||
<!-- publisher->subject -->
|
||||
<g id="edge1" class="edge">
|
||||
<title>publisher->subject</title>
|
||||
<path fill="none" stroke="#000000" d="M69.1206,-72C85.9478,-72 106.4184,-72 124.6452,-72"/>
|
||||
<polygon fill="#000000" stroke="#000000" points="124.787,-75.5001 134.787,-72 124.7869,-68.5001 124.787,-75.5001"/>
|
||||
<text text-anchor="middle" x="102.0586" y="-74.8" font-family="Times,serif" font-size="14.00" fill="#000000">msg1</text>
|
||||
</g>
|
||||
<!-- sub1 -->
|
||||
<g id="node3" class="node">
|
||||
<title>sub1</title>
|
||||
<path fill="none" stroke="#000000" d="M338.6453,-144C338.6453,-144 286.8931,-144 286.8931,-144 280.8931,-144 274.8931,-138 274.8931,-132 274.8931,-132 274.8931,-120 274.8931,-120 274.8931,-114 280.8931,-108 286.8931,-108 286.8931,-108 338.6453,-108 338.6453,-108 344.6453,-108 350.6453,-114 350.6453,-120 350.6453,-120 350.6453,-132 350.6453,-132 350.6453,-138 344.6453,-144 338.6453,-144"/>
|
||||
<text text-anchor="middle" x="312.7692" y="-121.8" font-family="Times,serif" font-size="14.00" fill="#000000">Subscriber</text>
|
||||
</g>
|
||||
<!-- subject->sub1 -->
|
||||
<g id="edge2" class="edge">
|
||||
<title>subject->sub1</title>
|
||||
<path fill="none" stroke="#000000" d="M206.3306,-85.2099C224.0345,-91.9945 245.8822,-100.3671 265.1678,-107.7579"/>
|
||||
<polygon fill="#000000" stroke="#000000" points="264.1007,-111.0971 274.691,-111.4074 266.6056,-104.5606 264.1007,-111.0971"/>
|
||||
<text text-anchor="middle" x="241.6623" y="-105.8" font-family="Times,serif" font-size="14.00" fill="#000000">msg1</text>
|
||||
</g>
|
||||
<!-- sub2 -->
|
||||
<g id="node4" class="node">
|
||||
<title>sub2</title>
|
||||
<path fill="none" stroke="#000000" d="M338.6453,-90C338.6453,-90 286.8931,-90 286.8931,-90 280.8931,-90 274.8931,-84 274.8931,-78 274.8931,-78 274.8931,-66 274.8931,-66 274.8931,-60 280.8931,-54 286.8931,-54 286.8931,-54 338.6453,-54 338.6453,-54 344.6453,-54 350.6453,-60 350.6453,-66 350.6453,-66 350.6453,-78 350.6453,-78 350.6453,-84 344.6453,-90 338.6453,-90"/>
|
||||
<text text-anchor="middle" x="312.7692" y="-67.8" font-family="Times,serif" font-size="14.00" fill="#000000">Subscriber</text>
|
||||
</g>
|
||||
<!-- subject->sub2 -->
|
||||
<g id="edge3" class="edge">
|
||||
<title>subject->sub2</title>
|
||||
<path fill="none" stroke="#000000" d="M208.5147,-72C225.6358,-72 246.2469,-72 264.6064,-72"/>
|
||||
<polygon fill="#000000" stroke="#000000" points="264.8244,-75.5001 274.8243,-72 264.8243,-68.5001 264.8244,-75.5001"/>
|
||||
<text text-anchor="middle" x="241.6623" y="-74.8" font-family="Times,serif" font-size="14.00" fill="#000000">msg1</text>
|
||||
</g>
|
||||
<!-- sub3 -->
|
||||
<g id="node5" class="node">
|
||||
<title>sub3</title>
|
||||
<path fill="none" stroke="#000000" d="M338.6453,-36C338.6453,-36 286.8931,-36 286.8931,-36 280.8931,-36 274.8931,-30 274.8931,-24 274.8931,-24 274.8931,-12 274.8931,-12 274.8931,-6 280.8931,0 286.8931,0 286.8931,0 338.6453,0 338.6453,0 344.6453,0 350.6453,-6 350.6453,-12 350.6453,-12 350.6453,-24 350.6453,-24 350.6453,-30 344.6453,-36 338.6453,-36"/>
|
||||
<text text-anchor="middle" x="312.7692" y="-13.8" font-family="Times,serif" font-size="14.00" fill="#000000">Subscriber</text>
|
||||
</g>
|
||||
<!-- subject->sub3 -->
|
||||
<g id="edge4" class="edge">
|
||||
<title>subject->sub3</title>
|
||||
<path fill="none" stroke="#000000" d="M206.3306,-58.7901C224.0345,-52.0055 245.8822,-43.6329 265.1678,-36.2421"/>
|
||||
<polygon fill="#000000" stroke="#000000" points="266.6056,-39.4394 274.691,-32.5926 264.1007,-32.9029 266.6056,-39.4394"/>
|
||||
<text text-anchor="middle" x="241.6623" y="-51.8" font-family="Times,serif" font-size="14.00" fill="#000000">msg1</text>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 4.8 KiB |
95
.gitbook/assets/pubsubtut.svg
Normal file
@ -0,0 +1,95 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
|
||||
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<!-- Generated by graphviz version 2.40.1 (20161225.0304)
|
||||
-->
|
||||
<!-- Title: nats_pub_sub Pages: 1 -->
|
||||
<svg width="584pt" height="188pt"
|
||||
viewBox="0.00 0.00 584.00 188.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 184)">
|
||||
<title>nats_pub_sub</title>
|
||||
<polygon fill="#ffffff" stroke="transparent" points="-4,4 -4,-184 580,-184 580,4 -4,4"/>
|
||||
<!-- sub1 -->
|
||||
<g id="node1" class="node">
|
||||
<title>sub1</title>
|
||||
<polygon fill="none" stroke="#000000" points="170.1559,-180 79.8441,-180 79.8441,-144 170.1559,-144 170.1559,-180"/>
|
||||
<text text-anchor="middle" x="125" y="-164.8" font-family="Times,serif" font-size="14.00" fill="#000000">SUB</text>
|
||||
<text text-anchor="middle" x="125" y="-150.8" font-family="Times,serif" font-size="14.00" fill="#000000">com.msg.one</text>
|
||||
</g>
|
||||
<!-- pub1 -->
|
||||
<g id="node2" class="node">
|
||||
<title>pub1</title>
|
||||
<polygon fill="none" stroke="#000000" points="333.1559,-180 242.8441,-180 242.8441,-144 333.1559,-144 333.1559,-180"/>
|
||||
<text text-anchor="middle" x="288" y="-164.8" font-family="Times,serif" font-size="14.00" fill="#000000">PUB</text>
|
||||
<text text-anchor="middle" x="288" y="-150.8" font-family="Times,serif" font-size="14.00" fill="#000000">com.msg.one</text>
|
||||
</g>
|
||||
<!-- natsserver -->
|
||||
<g id="node4" class="node">
|
||||
<title>natsserver</title>
|
||||
<polygon fill="none" stroke="#000000" points="576,-108 0,-108 0,-72 576,-72 576,-108"/>
|
||||
<text text-anchor="middle" x="288" y="-85.8" font-family="Times,serif" font-size="14.00" fill="#000000">NATS</text>
|
||||
</g>
|
||||
<!-- pub1->natsserver -->
|
||||
<g id="edge1" class="edge">
|
||||
<title>pub1->natsserver</title>
|
||||
<path fill="none" stroke="#000000" stroke-width="2" d="M288,-143.8314C288,-143.8314 288,-118.4133 288,-118.4133"/>
|
||||
<polygon fill="#000000" stroke="#000000" stroke-width="2" points="291.5001,-118.4132 288,-108.4133 284.5001,-118.4133 291.5001,-118.4132"/>
|
||||
</g>
|
||||
<!-- non_active -->
|
||||
<g id="node3" class="node">
|
||||
<title>non_active</title>
|
||||
<polygon fill="none" stroke="#000000" points="487.0899,-180 404.9101,-180 404.9101,-144 487.0899,-144 487.0899,-180"/>
|
||||
<text text-anchor="middle" x="446" y="-164.8" font-family="Times,serif" font-size="14.00" fill="#000000">Non-Active</text>
|
||||
<text text-anchor="middle" x="446" y="-150.8" font-family="Times,serif" font-size="14.00" fill="#000000">Subscriber</text>
|
||||
</g>
|
||||
<!-- natsserver->sub1 -->
|
||||
<g id="edge2" class="edge">
|
||||
<title>natsserver->sub1</title>
|
||||
<path fill="none" stroke="#000000" stroke-width="2" d="M125,-108.1686C125,-108.1686 125,-133.5867 125,-133.5867"/>
|
||||
<polygon fill="#000000" stroke="#000000" stroke-width="2" points="121.5001,-133.5867 125,-143.5867 128.5001,-133.5868 121.5001,-133.5867"/>
|
||||
</g>
|
||||
<!-- natsserver->non_active -->
|
||||
<g id="edge3" class="edge">
|
||||
<title>natsserver->non_active</title>
|
||||
<path fill="none" stroke="#ff0000" stroke-dasharray="5,2" d="M446,-108.1686C446,-119 446,-132.7124 446,-143.5867"/>
|
||||
</g>
|
||||
<!-- sub2 -->
|
||||
<g id="node5" class="node">
|
||||
<title>sub2</title>
|
||||
<polygon fill="none" stroke="#000000" points="170.1559,-36 79.8441,-36 79.8441,0 170.1559,0 170.1559,-36"/>
|
||||
<text text-anchor="middle" x="125" y="-20.8" font-family="Times,serif" font-size="14.00" fill="#000000">SUB</text>
|
||||
<text text-anchor="middle" x="125" y="-6.8" font-family="Times,serif" font-size="14.00" fill="#000000">com.msg.one</text>
|
||||
</g>
|
||||
<!-- natsserver->sub2 -->
|
||||
<g id="edge4" class="edge">
|
||||
<title>natsserver->sub2</title>
|
||||
<path fill="none" stroke="#000000" stroke-width="2" d="M125,-71.8314C125,-71.8314 125,-46.4133 125,-46.4133"/>
|
||||
<polygon fill="#000000" stroke="#000000" stroke-width="2" points="128.5001,-46.4132 125,-36.4133 121.5001,-46.4133 128.5001,-46.4132"/>
|
||||
</g>
|
||||
<!-- sub3 -->
|
||||
<g id="node6" class="node">
|
||||
<title>sub3</title>
|
||||
<polygon fill="none" stroke="#000000" points="333.9425,-36 242.0575,-36 242.0575,0 333.9425,0 333.9425,-36"/>
|
||||
<text text-anchor="middle" x="288" y="-20.8" font-family="Times,serif" font-size="14.00" fill="#000000">SUB</text>
|
||||
<text text-anchor="middle" x="288" y="-6.8" font-family="Times,serif" font-size="14.00" fill="#000000">com.msg.two</text>
|
||||
</g>
|
||||
<!-- natsserver->sub3 -->
|
||||
<g id="edge5" class="edge">
|
||||
<title>natsserver->sub3</title>
|
||||
<path fill="none" stroke="#ff0000" stroke-dasharray="5,2" d="M288,-71.8314C288,-61 288,-47.2876 288,-36.4133"/>
|
||||
</g>
|
||||
<!-- sub4 -->
|
||||
<g id="node7" class="node">
|
||||
<title>sub4</title>
|
||||
<polygon fill="none" stroke="#000000" points="482.9427,-36 405.0573,-36 405.0573,0 482.9427,0 482.9427,-36"/>
|
||||
<text text-anchor="middle" x="444" y="-20.8" font-family="Times,serif" font-size="14.00" fill="#000000">SUB</text>
|
||||
<text text-anchor="middle" x="444" y="-6.8" font-family="Times,serif" font-size="14.00" fill="#000000">com.msg.*</text>
|
||||
</g>
|
||||
<!-- natsserver->sub4 -->
|
||||
<g id="edge6" class="edge">
|
||||
<title>natsserver->sub4</title>
|
||||
<path fill="none" stroke="#000000" stroke-width="2" d="M444,-71.8314C444,-71.8314 444,-46.4133 444,-46.4133"/>
|
||||
<polygon fill="#000000" stroke="#000000" stroke-width="2" points="447.5001,-46.4132 444,-36.4133 440.5001,-46.4133 447.5001,-46.4132"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 5.2 KiB |
71
.gitbook/assets/queue.svg
Normal file
@ -0,0 +1,71 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
|
||||
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<!-- Generated by graphviz version 2.40.1 (20161225.0304)
|
||||
-->
|
||||
<!-- Title: nats_queues Pages: 1 -->
|
||||
<svg width="385pt" height="152pt"
|
||||
viewBox="0.00 0.00 385.26 152.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 148)">
|
||||
<title>nats_queues</title>
|
||||
<polygon fill="#ffffff" stroke="transparent" points="-4,4 -4,-148 381.2638,-148 381.2638,4 -4,4"/>
|
||||
<!-- publisher -->
|
||||
<g id="node1" class="node">
|
||||
<title>publisher</title>
|
||||
<path fill="none" stroke="#000000" d="M56.8346,-90C56.8346,-90 12.0551,-90 12.0551,-90 6.0551,-90 .0551,-84 .0551,-78 .0551,-78 .0551,-66 .0551,-66 .0551,-60 6.0551,-54 12.0551,-54 12.0551,-54 56.8346,-54 56.8346,-54 62.8346,-54 68.8346,-60 68.8346,-66 68.8346,-66 68.8346,-78 68.8346,-78 68.8346,-84 62.8346,-90 56.8346,-90"/>
|
||||
<text text-anchor="middle" x="34.4448" y="-67.8" font-family="Times,serif" font-size="14.00" fill="#000000">Publisher</text>
|
||||
</g>
|
||||
<!-- subject -->
|
||||
<g id="node2" class="node">
|
||||
<title>subject</title>
|
||||
<ellipse fill="none" stroke="#000000" cx="198.3628" cy="-72" rx="33.3752" ry="33.3752"/>
|
||||
<text text-anchor="middle" x="198.3628" y="-67.8" font-family="Times,serif" font-size="14.00" fill="#000000">Queue</text>
|
||||
</g>
|
||||
<!-- publisher->subject -->
|
||||
<g id="edge1" class="edge">
|
||||
<title>publisher->subject</title>
|
||||
<path fill="none" stroke="#000000" d="M69.2076,-72C94.18,-72 128.0202,-72 154.797,-72"/>
|
||||
<polygon fill="#000000" stroke="#000000" points="155.0496,-75.5001 165.0496,-72 155.0496,-68.5001 155.0496,-75.5001"/>
|
||||
<text text-anchor="middle" x="117.0327" y="-74.8" font-family="Times,serif" font-size="14.00" fill="#000000">msgs 1,2,3</text>
|
||||
</g>
|
||||
<!-- sub1 -->
|
||||
<g id="node3" class="node">
|
||||
<title>sub1</title>
|
||||
<path fill="none" stroke="#000000" d="M365.2019,-144C365.2019,-144 313.4497,-144 313.4497,-144 307.4497,-144 301.4497,-138 301.4497,-132 301.4497,-132 301.4497,-120 301.4497,-120 301.4497,-114 307.4497,-108 313.4497,-108 313.4497,-108 365.2019,-108 365.2019,-108 371.2019,-108 377.2019,-114 377.2019,-120 377.2019,-120 377.2019,-132 377.2019,-132 377.2019,-138 371.2019,-144 365.2019,-144"/>
|
||||
<text text-anchor="middle" x="339.3258" y="-121.8" font-family="Times,serif" font-size="14.00" fill="#000000">Subscriber</text>
|
||||
</g>
|
||||
<!-- subject->sub1 -->
|
||||
<g id="edge2" class="edge">
|
||||
<title>subject->sub1</title>
|
||||
<path fill="none" stroke="#000000" d="M229.6471,-83.9844C247.9227,-90.9854 271.3539,-99.9614 291.8636,-107.8182"/>
|
||||
<polygon fill="#000000" stroke="#000000" points="290.7658,-111.1457 301.3562,-111.4546 293.27,-104.6089 290.7658,-111.1457"/>
|
||||
<text text-anchor="middle" x="266.4688" y="-105.8" font-family="Times,serif" font-size="14.00" fill="#000000">msg 2</text>
|
||||
</g>
|
||||
<!-- sub2 -->
|
||||
<g id="node4" class="node">
|
||||
<title>sub2</title>
|
||||
<path fill="none" stroke="#000000" d="M365.2019,-90C365.2019,-90 313.4497,-90 313.4497,-90 307.4497,-90 301.4497,-84 301.4497,-78 301.4497,-78 301.4497,-66 301.4497,-66 301.4497,-60 307.4497,-54 313.4497,-54 313.4497,-54 365.2019,-54 365.2019,-54 371.2019,-54 377.2019,-60 377.2019,-66 377.2019,-66 377.2019,-78 377.2019,-78 377.2019,-84 371.2019,-90 365.2019,-90"/>
|
||||
<text text-anchor="middle" x="339.3258" y="-67.8" font-family="Times,serif" font-size="14.00" fill="#000000">Subscriber</text>
|
||||
</g>
|
||||
<!-- subject->sub2 -->
|
||||
<g id="edge3" class="edge">
|
||||
<title>subject->sub2</title>
|
||||
<path fill="none" stroke="#000000" d="M231.7691,-72C249.5052,-72 271.6202,-72 291.1768,-72"/>
|
||||
<polygon fill="#000000" stroke="#000000" points="291.433,-75.5001 301.433,-72 291.4329,-68.5001 291.433,-75.5001"/>
|
||||
<text text-anchor="middle" x="266.4688" y="-74.8" font-family="Times,serif" font-size="14.00" fill="#000000">msg 1</text>
|
||||
</g>
|
||||
<!-- sub3 -->
|
||||
<g id="node5" class="node">
|
||||
<title>sub3</title>
|
||||
<path fill="none" stroke="#000000" d="M365.2019,-36C365.2019,-36 313.4497,-36 313.4497,-36 307.4497,-36 301.4497,-30 301.4497,-24 301.4497,-24 301.4497,-12 301.4497,-12 301.4497,-6 307.4497,0 313.4497,0 313.4497,0 365.2019,0 365.2019,0 371.2019,0 377.2019,-6 377.2019,-12 377.2019,-12 377.2019,-24 377.2019,-24 377.2019,-30 371.2019,-36 365.2019,-36"/>
|
||||
<text text-anchor="middle" x="339.3258" y="-13.8" font-family="Times,serif" font-size="14.00" fill="#000000">Subscriber</text>
|
||||
</g>
|
||||
<!-- subject->sub3 -->
|
||||
<g id="edge4" class="edge">
|
||||
<title>subject->sub3</title>
|
||||
<path fill="none" stroke="#000000" d="M229.6471,-60.0156C247.9227,-53.0146 271.3539,-44.0386 291.8636,-36.1818"/>
|
||||
<polygon fill="#000000" stroke="#000000" points="293.27,-39.3911 301.3562,-32.5454 290.7658,-32.8543 293.27,-39.3911"/>
|
||||
<text text-anchor="middle" x="266.4688" y="-53.8" font-family="Times,serif" font-size="14.00" fill="#000000">msg 3</text>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 4.8 KiB |
71
.gitbook/assets/queues.svg
Normal file
@ -0,0 +1,71 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
|
||||
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<!-- Generated by graphviz version 2.40.1 (20161225.0304)
|
||||
-->
|
||||
<!-- Title: g Pages: 1 -->
|
||||
<svg width="500pt" height="152pt"
|
||||
viewBox="0.00 0.00 499.52 152.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 148)">
|
||||
<title>g</title>
|
||||
<polygon fill="#ffffff" stroke="transparent" points="-4,4 -4,-148 495.5219,-148 495.5219,4 -4,4"/>
|
||||
<!-- publisher -->
|
||||
<g id="node1" class="node">
|
||||
<title>publisher</title>
|
||||
<path fill="none" stroke="#000000" d="M77.2514,-90C77.2514,-90 12.2486,-90 12.2486,-90 6.2486,-90 .2486,-84 .2486,-78 .2486,-78 .2486,-66 .2486,-66 .2486,-60 6.2486,-54 12.2486,-54 12.2486,-54 77.2514,-54 77.2514,-54 83.2514,-54 89.2514,-60 89.2514,-66 89.2514,-66 89.2514,-78 89.2514,-78 89.2514,-84 83.2514,-90 77.2514,-90"/>
|
||||
<text text-anchor="middle" x="44.75" y="-67.8" font-family="Times,serif" font-size="14.00" fill="#000000">PUB updates</text>
|
||||
</g>
|
||||
<!-- subject -->
|
||||
<g id="node2" class="node">
|
||||
<title>subject</title>
|
||||
<ellipse fill="none" stroke="#000000" cx="234.6868" cy="-72" rx="48.8014" ry="48.8014"/>
|
||||
<text text-anchor="middle" x="234.6868" y="-67.8" font-family="Times,serif" font-size="14.00" fill="#000000">nats-server</text>
|
||||
</g>
|
||||
<!-- publisher->subject -->
|
||||
<g id="edge1" class="edge">
|
||||
<title>publisher->subject</title>
|
||||
<path fill="none" stroke="#000000" d="M89.2817,-72C115.0626,-72 147.8295,-72 175.729,-72"/>
|
||||
<polygon fill="#000000" stroke="#000000" points="175.7656,-75.5001 185.7656,-72 175.7656,-68.5001 175.7656,-75.5001"/>
|
||||
<text text-anchor="middle" x="137.6431" y="-74.8" font-family="Times,serif" font-size="14.00" fill="#000000">msgs 1,2,3</text>
|
||||
</g>
|
||||
<!-- sub1 -->
|
||||
<g id="node3" class="node">
|
||||
<title>sub1</title>
|
||||
<path fill="none" stroke="#000000" d="M479.5703,-144C479.5703,-144 365.3769,-144 365.3769,-144 359.3769,-144 353.3769,-138 353.3769,-132 353.3769,-132 353.3769,-120 353.3769,-120 353.3769,-114 359.3769,-108 365.3769,-108 365.3769,-108 479.5703,-108 479.5703,-108 485.5703,-108 491.5703,-114 491.5703,-120 491.5703,-120 491.5703,-132 491.5703,-132 491.5703,-138 485.5703,-144 479.5703,-144"/>
|
||||
<text text-anchor="middle" x="422.4736" y="-121.8" font-family="Times,serif" font-size="14.00" fill="#000000">SUB updates workers</text>
|
||||
</g>
|
||||
<!-- subject->sub1 -->
|
||||
<g id="edge2" class="edge">
|
||||
<title>subject->sub1</title>
|
||||
<path fill="none" stroke="#000000" d="M282.0733,-85.6265C302.7038,-91.559 327.3418,-98.6439 350.1777,-105.2106"/>
|
||||
<polygon fill="#000000" stroke="#000000" points="349.2594,-108.5883 359.8373,-107.9883 351.194,-101.8609 349.2594,-108.5883"/>
|
||||
<text text-anchor="middle" x="318.5063" y="-102.8" font-family="Times,serif" font-size="14.00" fill="#000000">msg 2</text>
|
||||
</g>
|
||||
<!-- sub2 -->
|
||||
<g id="node4" class="node">
|
||||
<title>sub2</title>
|
||||
<path fill="none" stroke="#000000" d="M479.5703,-90C479.5703,-90 365.3769,-90 365.3769,-90 359.3769,-90 353.3769,-84 353.3769,-78 353.3769,-78 353.3769,-66 353.3769,-66 353.3769,-60 359.3769,-54 365.3769,-54 365.3769,-54 479.5703,-54 479.5703,-54 485.5703,-54 491.5703,-60 491.5703,-66 491.5703,-66 491.5703,-78 491.5703,-78 491.5703,-84 485.5703,-90 479.5703,-90"/>
|
||||
<text text-anchor="middle" x="422.4736" y="-67.8" font-family="Times,serif" font-size="14.00" fill="#000000">SUB updates workers</text>
|
||||
</g>
|
||||
<!-- subject->sub2 -->
|
||||
<g id="edge3" class="edge">
|
||||
<title>subject->sub2</title>
|
||||
<path fill="none" stroke="#000000" d="M284.0255,-72C302.1531,-72 323.1652,-72 343.2577,-72"/>
|
||||
<polygon fill="#000000" stroke="#000000" points="343.3446,-75.5001 353.3446,-72 343.3445,-68.5001 343.3446,-75.5001"/>
|
||||
<text text-anchor="middle" x="318.5063" y="-74.8" font-family="Times,serif" font-size="14.00" fill="#000000">msg 1</text>
|
||||
</g>
|
||||
<!-- sub3 -->
|
||||
<g id="node5" class="node">
|
||||
<title>sub3</title>
|
||||
<path fill="none" stroke="#000000" d="M479.5703,-36C479.5703,-36 365.3769,-36 365.3769,-36 359.3769,-36 353.3769,-30 353.3769,-24 353.3769,-24 353.3769,-12 353.3769,-12 353.3769,-6 359.3769,0 365.3769,0 365.3769,0 479.5703,0 479.5703,0 485.5703,0 491.5703,-6 491.5703,-12 491.5703,-12 491.5703,-24 491.5703,-24 491.5703,-30 485.5703,-36 479.5703,-36"/>
|
||||
<text text-anchor="middle" x="422.4736" y="-13.8" font-family="Times,serif" font-size="14.00" fill="#000000">SUB updates workers</text>
|
||||
</g>
|
||||
<!-- subject->sub3 -->
|
||||
<g id="edge4" class="edge">
|
||||
<title>subject->sub3</title>
|
||||
<path fill="none" stroke="#000000" d="M282.0733,-58.3735C302.7038,-52.441 327.3418,-45.3561 350.1777,-38.7894"/>
|
||||
<polygon fill="#000000" stroke="#000000" points="351.194,-42.1391 359.8373,-36.0117 349.2594,-35.4117 351.194,-42.1391"/>
|
||||
<text text-anchor="middle" x="318.5063" y="-53.8" font-family="Times,serif" font-size="14.00" fill="#000000">msg 3</text>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 4.8 KiB |
91
.gitbook/assets/reqrepl.svg
Normal file
@ -0,0 +1,91 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
|
||||
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<!-- Generated by graphviz version 2.40.1 (20161225.0304)
|
||||
-->
|
||||
<!-- Title: nats_request_reply Pages: 1 -->
|
||||
<svg width="359pt" height="195pt"
|
||||
viewBox="0.00 0.00 358.71 195.23" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 191.231)">
|
||||
<title>nats_request_reply</title>
|
||||
<polygon fill="#ffffff" stroke="transparent" points="-4,4 -4,-191.231 354.7072,-191.231 354.7072,4 -4,4"/>
|
||||
<!-- publisher -->
|
||||
<g id="node1" class="node">
|
||||
<title>publisher</title>
|
||||
<path fill="none" stroke="#000000" d="M56.8346,-49.231C56.8346,-49.231 12.0551,-49.231 12.0551,-49.231 6.0551,-49.231 .0551,-43.231 .0551,-37.231 .0551,-37.231 .0551,-25.231 .0551,-25.231 .0551,-19.231 6.0551,-13.231 12.0551,-13.231 12.0551,-13.231 56.8346,-13.231 56.8346,-13.231 62.8346,-13.231 68.8346,-19.231 68.8346,-25.231 68.8346,-25.231 68.8346,-37.231 68.8346,-37.231 68.8346,-43.231 62.8346,-49.231 56.8346,-49.231"/>
|
||||
<text text-anchor="middle" x="34.4448" y="-27.031" font-family="Times,serif" font-size="14.00" fill="#000000">Publisher</text>
|
||||
</g>
|
||||
<!-- subject -->
|
||||
<g id="node2" class="node">
|
||||
<title>subject</title>
|
||||
<ellipse fill="none" stroke="#000000" cx="171.8604" cy="-117.231" rx="36.7663" ry="36.7663"/>
|
||||
<text text-anchor="middle" x="171.8604" y="-113.031" font-family="Times,serif" font-size="14.00" fill="#000000">Subject</text>
|
||||
</g>
|
||||
<!-- publisher->subject -->
|
||||
<g id="edge1" class="edge">
|
||||
<title>publisher->subject</title>
|
||||
<path fill="none" stroke="#000000" d="M63.2516,-49.2594C83.2612,-61.7822 110.1803,-78.6291 132.2123,-92.4176"/>
|
||||
<polygon fill="#000000" stroke="#000000" points="130.3666,-95.3914 140.7002,-97.7297 134.0802,-89.4576 130.3666,-95.3914"/>
|
||||
<text text-anchor="middle" x="102.0586" y="-85.031" font-family="Times,serif" font-size="14.00" fill="#000000">msg1</text>
|
||||
</g>
|
||||
<!-- reply -->
|
||||
<g id="node3" class="node">
|
||||
<title>reply</title>
|
||||
<ellipse fill="none" stroke="#000000" cx="171.8604" cy="-31.231" rx="31.4636" ry="31.4636"/>
|
||||
<text text-anchor="middle" x="171.8604" y="-27.031" font-family="Times,serif" font-size="14.00" fill="#000000">Reply</text>
|
||||
</g>
|
||||
<!-- publisher->reply -->
|
||||
<!-- sub1 -->
|
||||
<g id="node4" class="node">
|
||||
<title>sub1</title>
|
||||
<path fill="none" stroke="#000000" d="M338.6453,-187.231C338.6453,-187.231 286.8931,-187.231 286.8931,-187.231 280.8931,-187.231 274.8931,-181.231 274.8931,-175.231 274.8931,-175.231 274.8931,-163.231 274.8931,-163.231 274.8931,-157.231 280.8931,-151.231 286.8931,-151.231 286.8931,-151.231 338.6453,-151.231 338.6453,-151.231 344.6453,-151.231 350.6453,-157.231 350.6453,-163.231 350.6453,-163.231 350.6453,-175.231 350.6453,-175.231 350.6453,-181.231 344.6453,-187.231 338.6453,-187.231"/>
|
||||
<text text-anchor="middle" x="312.7692" y="-165.031" font-family="Times,serif" font-size="14.00" fill="#000000">Subscriber</text>
|
||||
</g>
|
||||
<!-- subject->sub1 -->
|
||||
<g id="edge4" class="edge">
|
||||
<title>subject->sub1</title>
|
||||
<path fill="none" stroke="#000000" stroke-dasharray="1,5" d="M206.3306,-129.9516C224.0345,-136.4849 245.8822,-144.5474 265.1678,-151.6645"/>
|
||||
<polygon fill="#000000" stroke="#000000" points="264.0976,-155.0002 274.691,-155.1788 266.5211,-148.4331 264.0976,-155.0002"/>
|
||||
<text text-anchor="middle" x="241.6623" y="-150.031" font-family="Times,serif" font-size="14.00" fill="#000000">msg1</text>
|
||||
</g>
|
||||
<!-- sub2 -->
|
||||
<g id="node5" class="node">
|
||||
<title>sub2</title>
|
||||
<path fill="none" stroke="#000000" d="M338.6453,-133.231C338.6453,-133.231 286.8931,-133.231 286.8931,-133.231 280.8931,-133.231 274.8931,-127.231 274.8931,-121.231 274.8931,-121.231 274.8931,-109.231 274.8931,-109.231 274.8931,-103.231 280.8931,-97.231 286.8931,-97.231 286.8931,-97.231 338.6453,-97.231 338.6453,-97.231 344.6453,-97.231 350.6453,-103.231 350.6453,-109.231 350.6453,-109.231 350.6453,-121.231 350.6453,-121.231 350.6453,-127.231 344.6453,-133.231 338.6453,-133.231"/>
|
||||
<text text-anchor="middle" x="312.7692" y="-111.031" font-family="Times,serif" font-size="14.00" fill="#000000">Subscriber</text>
|
||||
</g>
|
||||
<!-- subject->sub2 -->
|
||||
<g id="edge5" class="edge">
|
||||
<title>subject->sub2</title>
|
||||
<path fill="none" stroke="#000000" stroke-dasharray="1,5" d="M208.5147,-116.7107C225.6358,-116.4677 246.2469,-116.1751 264.6064,-115.9146"/>
|
||||
<polygon fill="#000000" stroke="#000000" points="264.8751,-119.4112 274.8243,-115.7695 264.7756,-112.4119 264.8751,-119.4112"/>
|
||||
<text text-anchor="middle" x="241.6623" y="-119.031" font-family="Times,serif" font-size="14.00" fill="#000000">msg1</text>
|
||||
</g>
|
||||
<!-- sub3 -->
|
||||
<g id="node6" class="node">
|
||||
<title>sub3</title>
|
||||
<path fill="none" stroke="#000000" d="M338.6453,-49.231C338.6453,-49.231 286.8931,-49.231 286.8931,-49.231 280.8931,-49.231 274.8931,-43.231 274.8931,-37.231 274.8931,-37.231 274.8931,-25.231 274.8931,-25.231 274.8931,-19.231 280.8931,-13.231 286.8931,-13.231 286.8931,-13.231 338.6453,-13.231 338.6453,-13.231 344.6453,-13.231 350.6453,-19.231 350.6453,-25.231 350.6453,-25.231 350.6453,-37.231 350.6453,-37.231 350.6453,-43.231 344.6453,-49.231 338.6453,-49.231"/>
|
||||
<text text-anchor="middle" x="312.7692" y="-27.031" font-family="Times,serif" font-size="14.00" fill="#000000">Subscriber</text>
|
||||
</g>
|
||||
<!-- subject->sub3 -->
|
||||
<g id="edge6" class="edge">
|
||||
<title>subject->sub3</title>
|
||||
<path fill="none" stroke="#000000" d="M203.1327,-98.1448C224.1767,-85.3011 252.059,-68.2838 274.4388,-54.6249"/>
|
||||
<polygon fill="#000000" stroke="#000000" points="276.3189,-57.5779 283.0314,-49.3807 272.6722,-51.6028 276.3189,-57.5779"/>
|
||||
<text text-anchor="middle" x="241.6623" y="-85.031" font-family="Times,serif" font-size="14.00" fill="#000000">msg1</text>
|
||||
</g>
|
||||
<!-- reply->publisher -->
|
||||
<g id="edge8" class="edge">
|
||||
<title>reply->publisher</title>
|
||||
<path fill="none" stroke="#000000" d="M140.9468,-36.9759C122.7803,-38.0548 99.4966,-38.2651 79.3354,-37.6068"/>
|
||||
<polygon fill="#000000" stroke="#000000" points="79.257,-34.1006 69.1206,-37.1834 78.967,-41.0946 79.257,-34.1006"/>
|
||||
</g>
|
||||
<!-- reply->sub3 -->
|
||||
<!-- sub3->reply -->
|
||||
<g id="edge7" class="edge">
|
||||
<title>sub3->reply</title>
|
||||
<path fill="none" stroke="#000000" d="M274.891,-37.2937C255.7517,-38.1623 232.4997,-38.2075 212.9317,-37.4295"/>
|
||||
<polygon fill="#000000" stroke="#000000" points="212.9434,-33.926 202.7835,-36.9303 212.5994,-40.9175 212.9434,-33.926"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 6.4 KiB |
59
.gitbook/assets/seqno.svg
Normal file
@ -0,0 +1,59 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
|
||||
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<!-- Generated by graphviz version 2.40.1 (20161225.0304)
|
||||
-->
|
||||
<!-- Title: nats_pub_sub Pages: 1 -->
|
||||
<svg width="405pt" height="81pt"
|
||||
viewBox="0.00 0.00 404.56 81.27" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 77.2658)">
|
||||
<title>nats_pub_sub</title>
|
||||
<polygon fill="#ffffff" stroke="transparent" points="-4,4 -4,-77.2658 400.5627,-77.2658 400.5627,4 -4,4"/>
|
||||
<!-- publisher -->
|
||||
<g id="node1" class="node">
|
||||
<title>publisher</title>
|
||||
<path fill="none" stroke="#000000" d="M56.8346,-54.6329C56.8346,-54.6329 12.0551,-54.6329 12.0551,-54.6329 6.0551,-54.6329 .0551,-48.6329 .0551,-42.6329 .0551,-42.6329 .0551,-30.6329 .0551,-30.6329 .0551,-24.6329 6.0551,-18.6329 12.0551,-18.6329 12.0551,-18.6329 56.8346,-18.6329 56.8346,-18.6329 62.8346,-18.6329 68.8346,-24.6329 68.8346,-30.6329 68.8346,-30.6329 68.8346,-42.6329 68.8346,-42.6329 68.8346,-48.6329 62.8346,-54.6329 56.8346,-54.6329"/>
|
||||
<text text-anchor="middle" x="34.4448" y="-32.4329" font-family="Times,serif" font-size="14.00" fill="#000000">Publisher</text>
|
||||
</g>
|
||||
<!-- subject -->
|
||||
<g id="node2" class="node">
|
||||
<title>subject</title>
|
||||
<ellipse fill="none" stroke="#000000" cx="194.7882" cy="-36.6329" rx="36.7663" ry="36.7663"/>
|
||||
<text text-anchor="middle" x="194.7882" y="-32.4329" font-family="Times,serif" font-size="14.00" fill="#000000">Subject</text>
|
||||
</g>
|
||||
<!-- publisher->subject -->
|
||||
<g id="edge1" class="edge">
|
||||
<title>publisher->subject</title>
|
||||
<path fill="none" stroke="#000000" d="M68.8499,-47.9423C74.8047,-49.4755 80.9813,-50.8046 86.8896,-51.6329 110.334,-54.9197 116.6938,-54.7952 140.1553,-51.6329 143.372,-51.1993 146.6673,-50.6283 149.9674,-49.9624"/>
|
||||
<polygon fill="#000000" stroke="#000000" points="150.8343,-53.3547 159.8083,-47.723 149.281,-46.5292 150.8343,-53.3547"/>
|
||||
<text text-anchor="middle" x="113.5225" y="-56.4329" font-family="Times,serif" font-size="14.00" fill="#000000">updates.1</text>
|
||||
</g>
|
||||
<!-- publisher->subject -->
|
||||
<g id="edge2" class="edge">
|
||||
<title>publisher->subject</title>
|
||||
<path fill="none" stroke="#000000" d="M68.8497,-34.383C74.8603,-34.0705 81.0553,-33.7996 86.8896,-33.6329 110.5536,-32.9566 116.4906,-32.9837 140.1553,-33.6329 142.6894,-33.7024 145.2889,-33.7901 147.9126,-33.8913"/>
|
||||
<polygon fill="#000000" stroke="#000000" points="147.9206,-37.3949 158.0652,-34.3393 148.2293,-30.4017 147.9206,-37.3949"/>
|
||||
<text text-anchor="middle" x="113.5225" y="-36.4329" font-family="Times,serif" font-size="14.00" fill="#000000">updates.2</text>
|
||||
</g>
|
||||
<!-- publisher->subject -->
|
||||
<g id="edge3" class="edge">
|
||||
<title>publisher->subject</title>
|
||||
<path fill="none" stroke="#000000" d="M69.0978,-19.8534C74.9167,-17.6923 80.9851,-15.8212 86.8896,-14.6329 110.0979,-9.9622 116.914,-10.1291 140.1553,-14.6329 144.0529,-15.3882 148.0251,-16.4205 151.9594,-17.6284"/>
|
||||
<polygon fill="#000000" stroke="#000000" points="151.0028,-21.0003 161.5974,-20.9347 153.2743,-14.3791 151.0028,-21.0003"/>
|
||||
<text text-anchor="middle" x="113.5225" y="-17.4329" font-family="Times,serif" font-size="14.00" fill="#000000">updates.3</text>
|
||||
</g>
|
||||
<!-- sub -->
|
||||
<g id="node3" class="node">
|
||||
<title>sub</title>
|
||||
<path fill="none" stroke="#000000" d="M384.5008,-54.6329C384.5008,-54.6329 332.7486,-54.6329 332.7486,-54.6329 326.7486,-54.6329 320.7486,-48.6329 320.7486,-42.6329 320.7486,-42.6329 320.7486,-30.6329 320.7486,-30.6329 320.7486,-24.6329 326.7486,-18.6329 332.7486,-18.6329 332.7486,-18.6329 384.5008,-18.6329 384.5008,-18.6329 390.5008,-18.6329 396.5008,-24.6329 396.5008,-30.6329 396.5008,-30.6329 396.5008,-42.6329 396.5008,-42.6329 396.5008,-48.6329 390.5008,-54.6329 384.5008,-54.6329"/>
|
||||
<text text-anchor="middle" x="358.6247" y="-32.4329" font-family="Times,serif" font-size="14.00" fill="#000000">Subscriber</text>
|
||||
</g>
|
||||
<!-- subject->sub -->
|
||||
<g id="edge4" class="edge">
|
||||
<title>subject->sub</title>
|
||||
<path fill="none" stroke="#000000" d="M231.5563,-36.6329C254.8568,-36.6329 285.2447,-36.6329 310.4609,-36.6329"/>
|
||||
<polygon fill="#000000" stroke="#000000" points="310.557,-40.133 320.557,-36.6329 310.557,-33.133 310.557,-40.133"/>
|
||||
<text text-anchor="middle" x="276.0539" y="-39.4329" font-family="Times,serif" font-size="14.00" fill="#000000">updates.*</text>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 4.4 KiB |
76
.gitbook/assets/simple.svg
Normal file
@ -0,0 +1,76 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns="http://www.w3.org/2000/svg" xmlns:xl="http://www.w3.org/1999/xlink" version="1.1" viewBox="152 192 358 280" width="358" height="280">
|
||||
<defs>
|
||||
<font-face font-family="Helvetica Neue" font-size="16" panose-1="2 0 5 3 0 0 0 2 0 4" units-per-em="1000" underline-position="-100" underline-thickness="50" slope="0" x-height="517" cap-height="714" ascent="951.9958" descent="-212.99744" font-weight="400">
|
||||
<font-face-src>
|
||||
<font-face-name name="HelveticaNeue"/>
|
||||
</font-face-src>
|
||||
</font-face>
|
||||
<marker orient="auto" overflow="visible" markerUnits="strokeWidth" id="FilledArrow_Marker" stroke-linejoin="miter" stroke-miterlimit="10" viewBox="-1 -4 10 8" markerWidth="10" markerHeight="8" color="black">
|
||||
<g>
|
||||
<path d="M 8 0 L 0 -3 L 0 3 Z" fill="currentColor" stroke="currentColor" stroke-width="1"/>
|
||||
</g>
|
||||
</marker>
|
||||
</defs>
|
||||
<metadata> Produced by OmniGraffle 7.10.2
|
||||
<dc:date>2019-05-07 16:42:18 +0000</dc:date>
|
||||
</metadata>
|
||||
<g id="Canvas_1" fill-opacity="1" stroke="none" stroke-dasharray="none" fill="none" stroke-opacity="1">
|
||||
<title>Canvas 1</title>
|
||||
<rect fill="white" x="152" y="192" width="358" height="280"/>
|
||||
<g id="Canvas_1: Layer 1">
|
||||
<title>Layer 1</title>
|
||||
<g id="Graphic_5">
|
||||
<circle cx="185.75" cy="225.75" r="33.250053130238" fill="white"/>
|
||||
<circle cx="185.75" cy="225.75" r="33.250053130238" stroke="gray" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
|
||||
<text transform="translate(164.15 215.75)" fill="black">
|
||||
<tspan font-family="Helvetica Neue" font-size="16" font-weight="400" fill="black" x="11.968" y="15">A1</tspan>
|
||||
</text>
|
||||
</g>
|
||||
<g id="Graphic_6">
|
||||
<circle cx="185.75" cy="332.25" r="33.250053130238" fill="white"/>
|
||||
<circle cx="185.75" cy="332.25" r="33.250053130238" stroke="gray" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
|
||||
<text transform="translate(164.15 322.25)" fill="black">
|
||||
<tspan font-family="Helvetica Neue" font-size="16" font-weight="400" fill="black" x="11.968" y="15">A2</tspan>
|
||||
</text>
|
||||
</g>
|
||||
<g id="Graphic_7">
|
||||
<circle cx="185.75" cy="438.25" r="33.2500531302381" fill="white"/>
|
||||
<circle cx="185.75" cy="438.25" r="33.2500531302381" stroke="gray" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
|
||||
<text transform="translate(164.15 428.25)" fill="black">
|
||||
<tspan font-family="Helvetica Neue" font-size="16" font-weight="400" fill="black" x="11.968" y="15">A3</tspan>
|
||||
</text>
|
||||
</g>
|
||||
<g id="Graphic_9">
|
||||
<circle cx="476.25" cy="225.75" r="33.250053130238" fill="white"/>
|
||||
<circle cx="476.25" cy="225.75" r="33.250053130238" stroke="gray" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
|
||||
<text transform="translate(454.65 215.75)" fill="black">
|
||||
<tspan font-family="Helvetica Neue" font-size="16" font-weight="400" fill="black" x="11.672" y="15">B1</tspan>
|
||||
</text>
|
||||
</g>
|
||||
<g id="Graphic_8">
|
||||
<circle cx="476.25" cy="332.25" r="33.250053130238" fill="white"/>
|
||||
<circle cx="476.25" cy="332.25" r="33.250053130238" stroke="gray" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
|
||||
<text transform="translate(454.65 322.25)" fill="black">
|
||||
<tspan font-family="Helvetica Neue" font-size="16" font-weight="400" fill="black" x="11.672" y="15">B2</tspan>
|
||||
</text>
|
||||
</g>
|
||||
<g id="Line_10">
|
||||
<line x1="219.00002" y1="225.75" x2="433.1" y2="225.75" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
|
||||
</g>
|
||||
<g id="Line_11">
|
||||
<line x1="216.9757" y1="320.80236" x2="435.72924" y2="240.6053" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
|
||||
</g>
|
||||
<g id="Line_12">
|
||||
<line x1="216.99302" y1="426.8498" x2="435.70677" y2="347.04374" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
|
||||
</g>
|
||||
<g id="Line_14">
|
||||
<line x1="449.4098" y1="245.38355" x2="220.58062" y2="412.7715" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-dasharray="1.0,5.0" stroke-width="1"/>
|
||||
</g>
|
||||
<g id="Line_15">
|
||||
<line x1="443" y1="332.25" x2="228.90002" y2="332.25" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-dasharray="1.0,5.0" stroke-width="1"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 4.8 KiB |
58
.gitbook/assets/subjects1.svg
Normal file
@ -0,0 +1,58 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
|
||||
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<!-- Generated by graphviz version 2.40.1 (20161225.0304)
|
||||
-->
|
||||
<!-- Title: g Pages: 1 -->
|
||||
<svg width="374pt" height="98pt"
|
||||
viewBox="0.00 0.00 373.81 98.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 94)">
|
||||
<title>g</title>
|
||||
<polygon fill="#ffffff" stroke="transparent" points="-4,4 -4,-94 369.8066,-94 369.8066,4 -4,4"/>
|
||||
<!-- publisher -->
|
||||
<g id="node1" class="node">
|
||||
<title>publisher</title>
|
||||
<path fill="none" stroke="#000000" d="M75.3492,-63C75.3492,-63 12.2162,-63 12.2162,-63 6.2162,-63 .2162,-57 .2162,-51 .2162,-51 .2162,-39 .2162,-39 .2162,-33 6.2162,-27 12.2162,-27 12.2162,-27 75.3492,-27 75.3492,-27 81.3492,-27 87.3492,-33 87.3492,-39 87.3492,-39 87.3492,-51 87.3492,-51 87.3492,-57 81.3492,-63 75.3492,-63"/>
|
||||
<text text-anchor="middle" x="43.7827" y="-40.8" font-family="Times,serif" font-size="14.00" fill="#000000">PUB time.us</text>
|
||||
</g>
|
||||
<!-- subject -->
|
||||
<g id="node2" class="node">
|
||||
<title>subject</title>
|
||||
<ellipse fill="none" stroke="#000000" cx="182.9033" cy="-45" rx="36" ry="36"/>
|
||||
<text text-anchor="middle" x="182.9033" y="-40.8" font-family="Times,serif" font-size="14.00" fill="#000000">nats-server</text>
|
||||
</g>
|
||||
<!-- publisher->subject -->
|
||||
<g id="edge1" class="edge">
|
||||
<title>publisher->subject</title>
|
||||
<path fill="none" stroke="#000000" d="M87.4196,-45C103.1079,-45 120.8492,-45 136.7449,-45"/>
|
||||
<polygon fill="#000000" stroke="#000000" points="136.8841,-48.5001 146.8841,-45 136.884,-41.5001 136.8841,-48.5001"/>
|
||||
<text text-anchor="middle" x="117.2344" y="-47.8" font-family="Times,serif" font-size="14.00" fill="#000000">msg</text>
|
||||
</g>
|
||||
<!-- sub1 -->
|
||||
<g id="node3" class="node">
|
||||
<title>sub1</title>
|
||||
<path fill="none" stroke="#000000" d="M353.5904,-90C353.5904,-90 290.4574,-90 290.4574,-90 284.4574,-90 278.4574,-84 278.4574,-78 278.4574,-78 278.4574,-66 278.4574,-66 278.4574,-60 284.4574,-54 290.4574,-54 290.4574,-54 353.5904,-54 353.5904,-54 359.5904,-54 365.5904,-60 365.5904,-66 365.5904,-66 365.5904,-78 365.5904,-78 365.5904,-84 359.5904,-90 353.5904,-90"/>
|
||||
<text text-anchor="middle" x="322.0239" y="-67.8" font-family="Times,serif" font-size="14.00" fill="#000000">SUB time.us</text>
|
||||
</g>
|
||||
<!-- subject->sub1 -->
|
||||
<g id="edge2" class="edge">
|
||||
<title>subject->sub1</title>
|
||||
<path fill="none" stroke="#000000" d="M218.3693,-51.8831C233.5027,-54.8201 251.4966,-58.3123 268.2103,-61.5561"/>
|
||||
<polygon fill="#000000" stroke="#000000" points="267.9309,-65.0671 278.4146,-63.5365 269.2646,-58.1953 267.9309,-65.0671"/>
|
||||
<text text-anchor="middle" x="248.5723" y="-61.8" font-family="Times,serif" font-size="14.00" fill="#000000">msg</text>
|
||||
</g>
|
||||
<!-- sub2 -->
|
||||
<g id="node4" class="node">
|
||||
<title>sub2</title>
|
||||
<path fill="none" stroke="#000000" d="M353.5904,-36C353.5904,-36 290.4574,-36 290.4574,-36 284.4574,-36 278.4574,-30 278.4574,-24 278.4574,-24 278.4574,-12 278.4574,-12 278.4574,-6 284.4574,0 290.4574,0 290.4574,0 353.5904,0 353.5904,0 359.5904,0 365.5904,-6 365.5904,-12 365.5904,-12 365.5904,-24 365.5904,-24 365.5904,-30 359.5904,-36 353.5904,-36"/>
|
||||
<text text-anchor="middle" x="322.0239" y="-13.8" font-family="Times,serif" font-size="14.00" fill="#000000">SUB time.us</text>
|
||||
</g>
|
||||
<!-- subject->sub2 -->
|
||||
<g id="edge3" class="edge">
|
||||
<title>subject->sub2</title>
|
||||
<path fill="none" stroke="#000000" d="M218.3693,-38.1169C233.5027,-35.1799 251.4966,-31.6877 268.2103,-28.4439"/>
|
||||
<polygon fill="#000000" stroke="#000000" points="269.2646,-31.8047 278.4146,-26.4635 267.9309,-24.9329 269.2646,-31.8047"/>
|
||||
<text text-anchor="middle" x="248.5723" y="-35.8" font-family="Times,serif" font-size="14.00" fill="#000000">msg</text>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 3.8 KiB |
58
.gitbook/assets/subjects2.svg
Normal file
@ -0,0 +1,58 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
|
||||
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<!-- Generated by graphviz version 2.40.1 (20161225.0304)
|
||||
-->
|
||||
<!-- Title: g Pages: 1 -->
|
||||
<svg width="424pt" height="98pt"
|
||||
viewBox="0.00 0.00 424.34 98.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 94)">
|
||||
<title>g</title>
|
||||
<polygon fill="#ffffff" stroke="transparent" points="-4,4 -4,-94 420.3379,-94 420.3379,4 -4,4"/>
|
||||
<!-- publisher -->
|
||||
<g id="node1" class="node">
|
||||
<title>publisher</title>
|
||||
<path fill="none" stroke="#000000" d="M100.7467,-63C100.7467,-63 12.0843,-63 12.0843,-63 6.0843,-63 .0843,-57 .0843,-51 .0843,-51 .0843,-39 .0843,-39 .0843,-33 6.0843,-27 12.0843,-27 12.0843,-27 100.7467,-27 100.7467,-27 106.7467,-27 112.7467,-33 112.7467,-39 112.7467,-39 112.7467,-51 112.7467,-51 112.7467,-57 106.7467,-63 100.7467,-63"/>
|
||||
<text text-anchor="middle" x="56.4155" y="-40.8" font-family="Times,serif" font-size="14.00" fill="#000000">PUB time.us.east</text>
|
||||
</g>
|
||||
<!-- subject -->
|
||||
<g id="node2" class="node">
|
||||
<title>subject</title>
|
||||
<ellipse fill="none" stroke="#000000" cx="208.1689" cy="-45" rx="36" ry="36"/>
|
||||
<text text-anchor="middle" x="208.1689" y="-40.8" font-family="Times,serif" font-size="14.00" fill="#000000">nats-server</text>
|
||||
</g>
|
||||
<!-- publisher->subject -->
|
||||
<g id="edge1" class="edge">
|
||||
<title>publisher->subject</title>
|
||||
<path fill="none" stroke="#000000" d="M112.9229,-45C128.9445,-45 146.2009,-45 161.5658,-45"/>
|
||||
<polygon fill="#000000" stroke="#000000" points="161.8625,-48.5001 171.8624,-45 161.8624,-41.5001 161.8625,-48.5001"/>
|
||||
<text text-anchor="middle" x="142.5" y="-47.8" font-family="Times,serif" font-size="14.00" fill="#000000">msg</text>
|
||||
</g>
|
||||
<!-- sub1 -->
|
||||
<g id="node3" class="node">
|
||||
<title>sub1</title>
|
||||
<path fill="none" stroke="#000000" d="M401.8059,-90C401.8059,-90 318.0389,-90 318.0389,-90 312.0389,-90 306.0389,-84 306.0389,-78 306.0389,-78 306.0389,-66 306.0389,-66 306.0389,-60 312.0389,-54 318.0389,-54 318.0389,-54 401.8059,-54 401.8059,-54 407.8059,-54 413.8059,-60 413.8059,-66 413.8059,-66 413.8059,-78 413.8059,-78 413.8059,-84 407.8059,-90 401.8059,-90"/>
|
||||
<text text-anchor="middle" x="359.9224" y="-67.8" font-family="Times,serif" font-size="14.00" fill="#000000">SUB time.*.east</text>
|
||||
</g>
|
||||
<!-- subject->sub1 -->
|
||||
<g id="edge2" class="edge">
|
||||
<title>subject->sub1</title>
|
||||
<path fill="none" stroke="#000000" d="M243.7484,-51.3303C259.4187,-54.1184 278.3195,-57.4812 296.2807,-60.6769"/>
|
||||
<polygon fill="#000000" stroke="#000000" points="295.6776,-64.1244 306.1361,-62.4303 296.9039,-57.2327 295.6776,-64.1244"/>
|
||||
<text text-anchor="middle" x="273.8379" y="-60.8" font-family="Times,serif" font-size="14.00" fill="#000000">msg</text>
|
||||
</g>
|
||||
<!-- sub2 -->
|
||||
<g id="node4" class="node">
|
||||
<title>sub2</title>
|
||||
<path fill="none" stroke="#000000" d="M404.2535,-36C404.2535,-36 315.5912,-36 315.5912,-36 309.5912,-36 303.5912,-30 303.5912,-24 303.5912,-24 303.5912,-12 303.5912,-12 303.5912,-6 309.5912,0 315.5912,0 315.5912,0 404.2535,0 404.2535,0 410.2535,0 416.2535,-6 416.2535,-12 416.2535,-12 416.2535,-24 416.2535,-24 416.2535,-30 410.2535,-36 404.2535,-36"/>
|
||||
<text text-anchor="middle" x="359.9224" y="-13.8" font-family="Times,serif" font-size="14.00" fill="#000000">SUB time.us.east</text>
|
||||
</g>
|
||||
<!-- subject->sub2 -->
|
||||
<g id="edge3" class="edge">
|
||||
<title>subject->sub2</title>
|
||||
<path fill="none" stroke="#000000" d="M243.7484,-38.6697C258.6145,-36.0247 276.388,-32.8624 293.5086,-29.8163"/>
|
||||
<polygon fill="#000000" stroke="#000000" points="294.2543,-33.2387 303.4866,-28.0411 293.0281,-26.347 294.2543,-33.2387"/>
|
||||
<text text-anchor="middle" x="273.8379" y="-36.8" font-family="Times,serif" font-size="14.00" fill="#000000">msg</text>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 3.8 KiB |
65
.gitbook/assets/subjects3.svg
Normal file
@ -0,0 +1,65 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
|
||||
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<!-- Generated by graphviz version 2.40.1 (20161225.0304)
|
||||
-->
|
||||
<!-- Title: g Pages: 1 -->
|
||||
<svg width="506pt" height="152pt"
|
||||
viewBox="0.00 0.00 505.96 152.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 148)">
|
||||
<title>g</title>
|
||||
<polygon fill="#ffffff" stroke="transparent" points="-4,4 -4,-148 501.959,-148 501.959,4 -4,4"/>
|
||||
<!-- publisher -->
|
||||
<g id="node1" class="node">
|
||||
<title>publisher</title>
|
||||
<path fill="none" stroke="#000000" d="M141.4628,-90C141.4628,-90 12.1788,-90 12.1788,-90 6.1788,-90 .1788,-84 .1788,-78 .1788,-78 .1788,-66 .1788,-66 .1788,-60 6.1788,-54 12.1788,-54 12.1788,-54 141.4628,-54 141.4628,-54 147.4628,-54 153.4628,-60 153.4628,-66 153.4628,-66 153.4628,-78 153.4628,-78 153.4628,-84 147.4628,-90 141.4628,-90"/>
|
||||
<text text-anchor="middle" x="76.8208" y="-67.8" font-family="Times,serif" font-size="14.00" fill="#000000">PUB time.us.east.atlanta</text>
|
||||
</g>
|
||||
<!-- subject -->
|
||||
<g id="node2" class="node">
|
||||
<title>subject</title>
|
||||
<ellipse fill="none" stroke="#000000" cx="248.9795" cy="-72" rx="36" ry="36"/>
|
||||
<text text-anchor="middle" x="248.9795" y="-67.8" font-family="Times,serif" font-size="14.00" fill="#000000">nats-server</text>
|
||||
</g>
|
||||
<!-- publisher->subject -->
|
||||
<g id="edge1" class="edge">
|
||||
<title>publisher->subject</title>
|
||||
<path fill="none" stroke="#000000" d="M153.5855,-72C170.3418,-72 187.5746,-72 202.7037,-72"/>
|
||||
<polygon fill="#000000" stroke="#000000" points="202.8099,-75.5001 212.8099,-72 202.8098,-68.5001 202.8099,-75.5001"/>
|
||||
<text text-anchor="middle" x="183.3105" y="-74.8" font-family="Times,serif" font-size="14.00" fill="#000000">msg</text>
|
||||
</g>
|
||||
<!-- sub1 -->
|
||||
<g id="node3" class="node">
|
||||
<title>sub1</title>
|
||||
<path fill="none" stroke="#000000" d="M485.7802,-144C485.7802,-144 356.4962,-144 356.4962,-144 350.4962,-144 344.4962,-138 344.4962,-132 344.4962,-132 344.4962,-120 344.4962,-120 344.4962,-114 350.4962,-108 356.4962,-108 356.4962,-108 485.7802,-108 485.7802,-108 491.7802,-108 497.7802,-114 497.7802,-120 497.7802,-120 497.7802,-132 497.7802,-132 497.7802,-138 491.7802,-144 485.7802,-144"/>
|
||||
<text text-anchor="middle" x="421.1382" y="-121.8" font-family="Times,serif" font-size="14.00" fill="#000000">SUB time.us.east.atlanta</text>
|
||||
</g>
|
||||
<!-- subject->sub1 -->
|
||||
<g id="edge3" class="edge">
|
||||
<title>subject->sub1</title>
|
||||
<path fill="none" stroke="#000000" d="M283.4046,-82.7979C303.5855,-89.1279 329.7773,-97.3434 353.8947,-104.9081"/>
|
||||
<polygon fill="#000000" stroke="#000000" points="353.1348,-108.3379 363.724,-107.9912 355.2299,-101.6587 353.1348,-108.3379"/>
|
||||
<text text-anchor="middle" x="314.6484" y="-97.8" font-family="Times,serif" font-size="14.00" fill="#000000">msg</text>
|
||||
</g>
|
||||
<!-- sub2 -->
|
||||
<g id="node4" class="node">
|
||||
<title>sub2</title>
|
||||
<path fill="none" stroke="#000000" d="M458.2036,-90C458.2036,-90 384.0727,-90 384.0727,-90 378.0727,-90 372.0727,-84 372.0727,-78 372.0727,-78 372.0727,-66 372.0727,-66 372.0727,-60 378.0727,-54 384.0727,-54 384.0727,-54 458.2036,-54 458.2036,-54 464.2036,-54 470.2036,-60 470.2036,-66 470.2036,-66 470.2036,-78 470.2036,-78 470.2036,-84 464.2036,-90 458.2036,-90"/>
|
||||
<text text-anchor="middle" x="421.1382" y="-67.8" font-family="Times,serif" font-size="14.00" fill="#000000">SUB time.us.*</text>
|
||||
</g>
|
||||
<!-- subject->sub2 -->
|
||||
<!-- sub3 -->
|
||||
<g id="node5" class="node">
|
||||
<title>sub3</title>
|
||||
<path fill="none" stroke="#000000" d="M458.5991,-36C458.5991,-36 383.6772,-36 383.6772,-36 377.6772,-36 371.6772,-30 371.6772,-24 371.6772,-24 371.6772,-12 371.6772,-12 371.6772,-6 377.6772,0 383.6772,0 383.6772,0 458.5991,0 458.5991,0 464.5991,0 470.5991,-6 470.5991,-12 470.5991,-12 470.5991,-24 470.5991,-24 470.5991,-30 464.5991,-36 458.5991,-36"/>
|
||||
<text text-anchor="middle" x="421.1382" y="-13.8" font-family="Times,serif" font-size="14.00" fill="#000000">SUB time.us.></text>
|
||||
</g>
|
||||
<!-- subject->sub3 -->
|
||||
<g id="edge4" class="edge">
|
||||
<title>subject->sub3</title>
|
||||
<path fill="none" stroke="#000000" d="M283.2153,-60.439C289.7664,-58.2691 296.5774,-56.0419 302.9795,-54 322.1173,-47.8961 343.0697,-41.4392 361.9465,-35.7048"/>
|
||||
<polygon fill="#000000" stroke="#000000" points="363.0525,-39.0269 371.6081,-32.7777 361.0228,-32.3276 363.0525,-39.0269"/>
|
||||
<text text-anchor="middle" x="314.6484" y="-56.8" font-family="Times,serif" font-size="14.00" fill="#000000">msg</text>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 4.5 KiB |
109
.gitbook/assets/three_gw.svg
Normal file
@ -0,0 +1,109 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns="http://www.w3.org/2000/svg" xmlns:xl="http://www.w3.org/1999/xlink" version="1.1" viewBox="152 140.7461 648.5 356.93095" width="648.5" height="356.93095">
|
||||
<defs>
|
||||
<font-face font-family="Helvetica Neue" font-size="16" panose-1="2 0 5 3 0 0 0 2 0 4" units-per-em="1000" underline-position="-100" underline-thickness="50" slope="0" x-height="517" cap-height="714" ascent="951.9958" descent="-212.99744" font-weight="400">
|
||||
<font-face-src>
|
||||
<font-face-name name="HelveticaNeue"/>
|
||||
</font-face-src>
|
||||
</font-face>
|
||||
<marker orient="auto" overflow="visible" markerUnits="strokeWidth" id="FilledArrow_Marker" stroke-linejoin="miter" stroke-miterlimit="10" viewBox="-1 -4 10 8" markerWidth="10" markerHeight="8" color="black">
|
||||
<g>
|
||||
<path d="M 8 0 L 0 -3 L 0 3 Z" fill="currentColor" stroke="currentColor" stroke-width="1"/>
|
||||
</g>
|
||||
</marker>
|
||||
<marker orient="auto" overflow="visible" markerUnits="strokeWidth" id="FilledArrow_Marker_2" stroke-linejoin="miter" stroke-miterlimit="10" viewBox="-1 -4 10 8" markerWidth="10" markerHeight="8" color="black">
|
||||
<g>
|
||||
<path d="M 8 0 L 0 -3 L 0 3 Z" fill="currentColor" stroke="currentColor" stroke-width="1"/>
|
||||
</g>
|
||||
</marker>
|
||||
</defs>
|
||||
<metadata> Produced by OmniGraffle 7.10.2
|
||||
<dc:date>2019-05-07 16:43:34 +0000</dc:date>
|
||||
</metadata>
|
||||
<g id="Canvas_1" fill-opacity="1" stroke="none" stroke-dasharray="none" fill="none" stroke-opacity="1">
|
||||
<title>Canvas 1</title>
|
||||
<rect fill="white" x="152" y="140.7461" width="648.5" height="356.93095"/>
|
||||
<g id="Canvas_1: Layer 1">
|
||||
<title>Layer 1</title>
|
||||
<g id="Graphic_5">
|
||||
<circle cx="185.75" cy="225.75" r="33.250053130238" fill="white"/>
|
||||
<circle cx="185.75" cy="225.75" r="33.250053130238" stroke="gray" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
|
||||
<text transform="translate(164.15 215.75)" fill="black">
|
||||
<tspan font-family="Helvetica Neue" font-size="16" font-weight="400" fill="black" x="11.968" y="15">A1</tspan>
|
||||
</text>
|
||||
</g>
|
||||
<g id="Graphic_6">
|
||||
<circle cx="185.75" cy="332.25" r="33.250053130238" fill="white"/>
|
||||
<circle cx="185.75" cy="332.25" r="33.250053130238" stroke="gray" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
|
||||
<text transform="translate(164.15 322.25)" fill="black">
|
||||
<tspan font-family="Helvetica Neue" font-size="16" font-weight="400" fill="black" x="11.968" y="15">A2</tspan>
|
||||
</text>
|
||||
</g>
|
||||
<g id="Graphic_7">
|
||||
<circle cx="185.75" cy="438.25" r="33.2500531302381" fill="white"/>
|
||||
<circle cx="185.75" cy="438.25" r="33.2500531302381" stroke="gray" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
|
||||
<text transform="translate(164.15 428.25)" fill="black">
|
||||
<tspan font-family="Helvetica Neue" font-size="16" font-weight="400" fill="black" x="11.968" y="15">A3</tspan>
|
||||
</text>
|
||||
</g>
|
||||
<g id="Graphic_9">
|
||||
<circle cx="476.25" cy="225.75" r="33.250053130238" fill="white"/>
|
||||
<circle cx="476.25" cy="225.75" r="33.250053130238" stroke="gray" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
|
||||
<text transform="translate(454.65 215.75)" fill="black">
|
||||
<tspan font-family="Helvetica Neue" font-size="16" font-weight="400" fill="black" x="11.672" y="15">B1</tspan>
|
||||
</text>
|
||||
</g>
|
||||
<g id="Graphic_8">
|
||||
<circle cx="476.25" cy="332.25" r="33.250053130238" fill="white"/>
|
||||
<circle cx="476.25" cy="332.25" r="33.250053130238" stroke="gray" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
|
||||
<text transform="translate(454.65 322.25)" fill="black">
|
||||
<tspan font-family="Helvetica Neue" font-size="16" font-weight="400" fill="black" x="11.672" y="15">B2</tspan>
|
||||
</text>
|
||||
</g>
|
||||
<g id="Line_10">
|
||||
<line x1="219.00002" y1="225.75" x2="433.1" y2="225.75" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
|
||||
</g>
|
||||
<g id="Line_11">
|
||||
<line x1="216.9757" y1="320.80236" x2="435.72924" y2="240.6053" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
|
||||
</g>
|
||||
<g id="Line_12">
|
||||
<line x1="216.99302" y1="426.8498" x2="435.70677" y2="347.04374" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
|
||||
</g>
|
||||
<g id="Line_14">
|
||||
<line x1="449.4098" y1="245.38355" x2="220.58062" y2="412.7715" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-dasharray="1.0,5.0" stroke-width="1"/>
|
||||
</g>
|
||||
<g id="Line_15">
|
||||
<line x1="443" y1="332.25" x2="228.90002" y2="332.25" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-dasharray="1.0,5.0" stroke-width="1"/>
|
||||
</g>
|
||||
<g id="Graphic_18">
|
||||
<circle cx="766.75" cy="225.75" r="33.250053130238" fill="white"/>
|
||||
<circle cx="766.75" cy="225.75" r="33.250053130238" stroke="gray" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
|
||||
<text transform="translate(745.15 215.75)" fill="black">
|
||||
<tspan font-family="Helvetica Neue" font-size="16" font-weight="400" fill="black" x="11.376" y="15">C1</tspan>
|
||||
</text>
|
||||
</g>
|
||||
<g id="Line_19">
|
||||
<line x1="509.5" y1="225.75" x2="723.6" y2="225.75" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
|
||||
</g>
|
||||
<g id="Line_24">
|
||||
<path d="M 737.9152 209.17695 C 691.19614 184.57088 592.20205 141.2461 474.34375 141.2461 C 363.9938 141.2461 271.8946 179.22656 223.17214 204.26238" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-dasharray="1.0,4.0" stroke-width="1"/>
|
||||
</g>
|
||||
<g id="Line_25">
|
||||
<path d="M 215.77826 452.5492 C 273.97692 477.73306 407.3362 523.2367 531.3711 477.8711 C 649.03855 434.8344 718.7598 324.48573 748.9529 265.0568" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-dasharray="1.0,4.0" stroke-width="1"/>
|
||||
</g>
|
||||
<g id="Line_26">
|
||||
<path d="M 206.45157 358.2732 C 244.25963 400.88577 331.892 478.7072 453.0625 456.4961 C 575.3629 434.07786 689.0991 317.5855 739.4792 259.19245" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-dasharray="1.0,4.0" stroke-width="1"/>
|
||||
</g>
|
||||
<g id="Line_27">
|
||||
<path d="M 199.5272 256.02128 C 228.04436 312.15083 301.47194 426.71484 425.75 426.71484 C 549.392 426.71484 679.6919 313.32052 736.8824 256.88767" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-dasharray="1.0,4.0" stroke-width="1"/>
|
||||
</g>
|
||||
<g id="Line_28">
|
||||
<line x1="507.4757" y1="320.80236" x2="726.2292" y2="240.6053" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
|
||||
</g>
|
||||
<g id="Line_30">
|
||||
<path d="M 736.5963 211.71723 C 709.7235 200.97972 667.2586 188 619 188 C 577.0519 188 540.7803 197.8071 515.29633 207.424" marker-end="url(#FilledArrow_Marker_2)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-dasharray="1.0,4.0" stroke-width="1"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 7.6 KiB |
33
README.md
@ -1,18 +1,12 @@
|
||||
# Introduction
|
||||
|
||||
<a href="https://nats.io"><img src="nats-horizontal-color.png" width="350" height="90" title="NATS Logo">
|
||||
</a>
|
||||
# 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
|
||||
|
||||
|
340
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)
|
||||
|
||||
|
@ -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.
|
||||
|
||||

|
||||

|
||||
|
||||
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.
|
||||
|
@ -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.
|
||||
|
||||

|
||||

|
||||
|
||||
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.
|
@ -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.
|
||||
|
||||

|
||||

|
||||
|
||||
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).
|
@ -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.
|
||||
|
||||

|
||||

|
||||
|
||||
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).
|
@ -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.
|
||||
|
||||

|
||||

|
||||
|
||||
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).
|
@ -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.
|
||||
|
||||

|
||||

|
||||
|
||||
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.
|
||||
|
@ -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.
|
||||
|
||||

|
||||

|
||||
|
||||
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`.
|
||||
|
||||

|
||||

|
||||
|
||||
### 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.
|
||||
|
||||

|
||||

|
||||
|
||||
### 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.
|
||||
|
@ -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"
|
@ -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"
|
@ -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"
|
@ -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"
|
@ -1,5 +0,0 @@
|
||||
# Disable Reconnect
|
||||
|
||||
You can disable automatic reconnect with connection options:
|
||||
|
||||
!INCLUDE "../../_examples/reconnect_none.html"
|
@ -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 `<discover-prefix>.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)
|
@ -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)
|
@ -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))
|
||||
```
|
||||
|
@ -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))
|
||||
```
|
||||
|
@ -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.
|
||||
Check the [concepts](../nats-streaming-concepts/channels/subscriptions/durable.md) section for more information.
|
||||
|
254
developing-with-nats-streaming/protocol.md
Normal file
@ -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 `<discover-prefix>.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)
|
||||
|
@ -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))
|
||||
```
|
||||
|
@ -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.
|
||||
|
@ -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._
|
||||
|
@ -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**.
|
||||
|
@ -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.
|
||||
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.
|
||||
|
@ -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.
|
||||
|
@ -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.*
|
6
developing-with-nats/intro-1/disable.md
Normal file
@ -0,0 +1,6 @@
|
||||
# Disabling Reconnect
|
||||
|
||||
You can disable automatic reconnect with connection options:
|
||||
|
||||
!INCLUDE "../../\_examples/reconnect\_none.html"
|
||||
|
@ -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"
|
||||
!INCLUDE "../../\_examples/reconnect\_event.html"
|
||||
|
@ -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"
|
||||
!INCLUDE "../../\_examples/reconnect\_10x.html"
|
||||
|
@ -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"
|
||||
|
@ -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"
|
||||
!INCLUDE "../../\_examples/reconnect\_10s.html"
|
||||
|
@ -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.
|
||||
|
@ -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"
|
||||
!INCLUDE "../../\_examples/connect\_creds.html"
|
||||
|
@ -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"
|
||||
|
@ -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"
|
||||
|
@ -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"
|
||||
!INCLUDE "../../\_examples/connect\_token\_url.html"
|
||||
|
@ -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"
|
||||
!INCLUDE "../../\_examples/connect\_userpass\_url.html"
|
||||
|
@ -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.
|
||||
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.
|
||||
|
@ -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"
|
||||
!INCLUDE "../../\_examples/subscribe\_async.html"
|
||||
|
@ -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.
|
||||
|
@ -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.
|
||||
|
||||

|
||||

|
||||
|
||||
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.
|
||||
|
@ -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"
|
||||
!INCLUDE "../../\_examples/subscribe\_w\_reply.html"
|
||||
|
@ -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"
|
||||
!INCLUDE "../../\_examples/subscribe\_json.html"
|
||||
|
@ -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"
|
||||
!INCLUDE "../../\_examples/subscribe\_sync.html"
|
||||
|
@ -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"
|
||||
!INCLUDE "../../\_examples/unsubscribe\_auto.html"
|
||||
|
@ -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"
|
||||
!INCLUDE "../../\_examples/unsubscribe.html"
|
||||
|
@ -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"
|
||||
!INCLUDE "../../\_examples/wildcard\_tester.html"
|
||||
|
@ -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"
|
||||
!INCLUDE "../../\_examples/publish\_bytes.html"
|
||||
|
@ -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.
|
||||
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.
|
||||
|
@ -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"
|
||||
!INCLUDE "../../\_examples/publish\_with\_reply.html"
|
||||
|
@ -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()
|
||||
```
|
||||
```
|
||||
|
@ -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"
|
||||
!INCLUDE "../../\_examples/publish\_json.html"
|
||||
|
@ -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"
|
||||
!INCLUDE "../../\_examples/connect\_status.html"
|
||||
|
@ -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"
|
||||
!INCLUDE "../../\_examples/error\_listener.html"
|
||||
|
@ -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"
|
||||
!INCLUDE "../../\_examples/slow\_listener.html"
|
||||
|
9
developing-with-nats/intro-6/README.md
Normal file
@ -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)
|
||||
|
@ -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")
|
||||
}
|
||||
```
|
||||
|
@ -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.
|
||||
|
||||

|
||||

|
||||
|
||||
## 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 <subject>
|
||||
```
|
||||
|
||||
@ -44,11 +44,11 @@ Where `<subject>` 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 <subject> <message>
|
||||
```
|
||||
|
||||
@ -70,27 +70,27 @@ Where `<subject>` is the subject name and `<message>` 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.
|
||||
|
@ -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.
|
||||
|
@ -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.
|
||||
|
@ -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.
|
||||
|
114
developing-with-nats/intro/cluster.md
Normal file
@ -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 %}
|
||||
|
73
developing-with-nats/intro/connect_timeout.md
Normal file
@ -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 %}
|
||||
|
89
developing-with-nats/intro/default_server.md
Normal file
@ -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 %}
|
||||
|
@ -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.
|
||||
|
||||

|
||||

|
||||
|
||||
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"
|
||||
|
@ -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.
|
||||
|
||||

|
||||

|
||||
|
||||
## 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"
|
||||
|
@ -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"
|
||||
!INCLUDE "../../\_examples/connect\_verbose.html"
|
||||
|
86
developing-with-nats/intro/specific_server.md
Normal file
@ -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 %}
|
||||
|
56
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.
|
||||
|
||||
|
@ -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
|
||||
```
|
||||
|
319
nats-protocol/nats-protocol/README.md
Normal file
@ -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 <subject> [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 <subject> [queue group] <sid>\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 <sid> [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 <subject> <sid> [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 <error message>`
|
||||
|
||||
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 <subject>'`: The user specified in the [`CONNECT`](./#connect) message does not have permission to subscribe to the subject.
|
||||
* `-ERR 'Permissions Violation for Publish to <subject>'`: The user specified in the [`CONNECT`](./#connect) message does not have permissions to publish to the subject.
|
||||
|
@ -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.
|
||||
|
@ -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://<hostname>:<port>`
|
||||
|
||||
#### 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`
|
||||
|
||||
## <a name="SUB"></a>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+ <account> <subject>\r\n`
|
||||
|
||||
@ -116,13 +113,13 @@ where:
|
||||
* `queue`: Optional queue group name
|
||||
* `weight`: Optional queue group weight representing how much interest/subscribers
|
||||
|
||||
## <a name="UNSUB"></a>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- <account> <subject>\r\n`
|
||||
|
||||
@ -133,11 +130,11 @@ where:
|
||||
|
||||
## RMSG
|
||||
|
||||
#### Description
|
||||
### Description
|
||||
|
||||
The `RMSG` protocol message delivers a message to another server.
|
||||
|
||||
#### Syntax
|
||||
### Syntax
|
||||
|
||||
`RMSG <account> <subject> [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.
|
||||
|
@ -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 `<ctrl>+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://<server>:<port>` and `tls://<server>:<port>`. 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 ">"
|
||||
```
|
||||
|
||||
|
@ -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
|
||||
```
|
||||
|
@ -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]
|
||||
```
|
||||
|
@ -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
|
||||
]
|
||||
}
|
||||
```
|
||||
```
|
||||
|
@ -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 {
|
||||
]
|
||||
}
|
||||
```
|
||||
|
@ -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.
|
||||
|
||||

|
||||

|
||||
|
||||
> 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.
|
||||
|
||||

|
||||

|
||||
|
||||
> 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.
|
||||
|
@ -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 `<host>:<port>` 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 `<host>:<port>` 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"]}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
@ -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
|
||||
|
@ -1,39 +1,37 @@
|
||||
## `leafnodes` Configuration Block
|
||||
# Configuration
|
||||
|
||||
| Property | Description |
|
||||
| :------ | :---- |
|
||||
| :--- | :--- |
|
||||
| `advertise` | Hostport `<host>:<port>` 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 `<host>:<port>` |
|
||||
| `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. |
|
||||
|
||||
|
@ -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://<hostname>:<port>
|
||||
```
|
||||
|
||||
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.
|
||||
* 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.
|
||||
|