Cluster mode
The Nats cluster mode is not transparent to the client.
So the cluster has an impact on both the publisher and the Subscriber.
Both the Publisher and the Subscriber know that a clustered service is connected, not a single point of service, in other words, the Publisher Subscriber must indicate the address of each node in the cluster.
Of course, publishers and Subscribers can publish messages and subscribe to messages only for a node in the cluster, but this is not the purpose of cluster mode.
Objective
Increase availability and scalability.
Implementation principle
availability, multiple nodes, hangs off any one, does not affect the entire cluster to provide services to the outside.
Scalability, the service side supports arbitrarily adding nodes. Subscribers can perceive changes in server-side nodes, but publishers are not automatically aware of them.
Cluster of 3 node
$ gnatsd -p 4222 -m 4333 -cluster nats://localhost:4248 -routes nats://localhost:5248,nats://localhost:6248 -DV
-P Port: Service port, publisher, Subscriber needs to use this port.
-M port: monitoring port.
-cluster Address: The address that the other nodes need to connect as a cluster node that serves the other nodes. (-routes of other nodes can fill in this address)
-routes Address: This node, routed to a list of other addresses (that is, the-cluster of other nodes)
-DV Debug and Trace
GNATSD-P Service provides port-m service monitoring port-cluster in cluster node address-routes Other node address list in cluster-DV
Server
Package Mainimport ("Github.com/nats-io/go-nats" "Log" "Flag" "FMT" "Time") const (//url = "Nats://19 2.168.3.125:4222 "//url = Nats. Defaulturl url = "nats://localhost:4222,nats://localhost:6222"//url = "nats://localhost:4222,nats://localhost:5222, Nats://localhost:6222 ") Var (nc *nats. Conn err Error) func init () {if NC, err = Nats. Connect (URL, Nats. Dontrandomize (), Nats. Maxreconnects (5), Nats. Reconnectwait (2*time. Second), Nats. Disconnecthandler (func (NC *nats). Conn) {fmt. Printf ("Got disconnected!\n")}), Nats. Reconnecthandler (Func (_ *nats). Conn) {fmt. Printf ("Got reconnected to%v!\n", NC. Connectedurl ())}), Nats. Closedhandler (func (NC *nats). Conn) {fmt. Printf ("Connection closed. Reason:%q\n ", NC. LastError ())}), Nats. Discoveredservershandler (func (Conn *nats. Conn) {fmt. Printf ("Got Discover Server%v!\n", NC. Connectedurl ())}), Nats. ErrorHandler (func (Conn *nats. Conn, SubsCription *nats. Subscription, e error) {FMT. Printf ("Got Error Server%v!\n", E)})); Checkerr (ERR) {//}}func main () {var (servername = flag). String ("servername", "Y", "Name for server") Queuegroup = flag. String ("group", "", "group name for Subscribe") SUBJ = flag. String ("Subj", "abc", "Subject name")) flag. Parse () log. Println (*servername, *queuegroup, *SUBJ) StartService (*SUBJ, *servername+ "Worker1", *queuegroup)//startservice (*su BJ, *servername+ "Worker2", *queuegroup)//startservice (*SUBJ, *servername+ "Worker3", *queuegroup) Select {}}//rece Ive messagefunc startservice (subj, name, queue string) {Go Async (NC, SUBJ, name, queue)}func Async (NC *nats. Conn, SUBJ, name, queue string) {_, E: = NC. Queuesubscribe (subj, Queue, func (msg *nats). MSG) {log. PRINTLN (Name, "Received a message from Async:", String (Msg. Data)}) Checkerr (e)}func Checkerr (err error) bool {if err! = Nil { Log. Println ("Error:", err) return false} return true}
Client
Package Mainimport ("Github.com/nats-io/go-nats" "Log" "StrConv" "Github.com/pborman/uuid" "Flag" "Time "FMT") const (//url = "nats://192.168.3.125:4222"//url = "nats://localhost:4222"//url = "Nats://localhos t:4222,nats://localhost:6222 "url =" nats://localhost:4222,nats://localhost:5222,nats://localhost:6222 "//url =" nat S://localhost:5222 ") Var (nc *nats. Conn err Error) func init () {if NC, err = Nats. Connect (URL, Nats. Dontrandomize (), Nats. Maxreconnects (Ten), Nats. Reconnectwait (2*time. Second), Nats. Disconnecthandler (func (NC *nats). Conn) {fmt. Printf ("Got disconnected!\n")}), Nats. Reconnecthandler (Func (_ *nats). Conn) {fmt. Printf ("Got reconnected to%v!\n", NC. Connectedurl ())}), Nats. Closedhandler (func (NC *nats). Conn) {fmt. Printf ("Connection closed. Reason:%q\n ", NC. LastError ())); Checkerr (ERR) {//} NC. Setdiscoveredservershandler (func (Conn *nats. Conn) { })}func main () {var (subj = flag). String ("Subj", "abc", "Subject name")) flag. Parse () log. Println (*SUBJ) startclient (*SUBJ) time. Sleep (time. Second)}//send message to Serverfunc startclient (Subj string) {for I: = 0; i < 1; i++ {id: = UUID. New () log. PRINTLN (ID) nc. Publish (SUBJ, []byte (id+ "Golang" +strconv. Itoa (i)))//nc. Publish (SUBJ, []byte (id+ "Rain" +strconv. Itoa (i)))//nc. Publish (SUBJ, []byte (id+ "Fog" +strconv. Itoa (i)))//nc. Publish (SUBJ, []byte (id+ "Cloudy" +strconv. Itoa (i)))}}func Checkerr (err error) bool {if err! = Nil {log. PRINTLN (ERR) return false} return true}
Attention
- Both the Publisher and the subscriber need to indicate the UR address of 3 nodes
nats://localhost:4222,nats://localhost:5222,nats://localhost:6222
- If 3 node is unavailable, the Publisher will fail to send a message.
- If at least one of the 3 node is available, the Subscriber will receive a message.
- If all 3 node are not available, the Subscriber will automatically disconnect.
- By adding a node nats://localhost:7222, subscribers can connect automatically.
- When node is added, 3 node is not available, subscribers are not disconnected and can accept messages posted from new node.
- After 3 node recovery, subscribers can accept 3 node messages.
Subsequent
Publishers and Subscribers
- node is not available in the original cluster
- Active query Available node
- Accept available Node notifications
- Send a message to available node to subscribe to a message with node available
- The above content needs to cooperate with the service discovery middleware or own realization
Configuration file Startup
$ gnatsd -c nodea.cfg$ gnatsd -c nodeb.cfg$ gnatsd -c nodec.cfg
Nodea.cfg
listen:localhost:4222 # Host/port to listen for client connectionshttp:localhost:4333 # HTTP monitoring port# Authorizat Ion for client Connections#authorization {#user: Yasenagat #./util/mkpasswd-p t0ps3cr3t #password: $2a$11$w2zko7 51kuvvy59mutwmpodwjpem5qhcczrd05gji/ssot.xtihyg #ytc #token: $2a$11$ Zuyxelbdarqnocadex40yotincvei9c3x64k2kyx7wljq7ecpuna2 #timeout: 1#}# Cluster definitioncluster {listen:localhost : 4248 # Host/port for inbound Route connections # Authorization for route connections #authorization {#user: User2 #./util/mkpasswd-p t0ps3cr3tt00! #password: $2a$11$xh8dkgrty1cbntzjhpewjewu/ypbsu.rxjwms6sfilobxzmzomk9m #yctc #token: $2a$11$d/rrrsesipod/ Fxurspfqusirrjserfrfghdrbte7d8wj2laclcvs #timeout: 0.5 #} # Routes is actively solicited and connected to from Server. # Other servers can connect to us if they supply the correct credentials # on their routes definitions from above. Routes = [nats-route://127.0.0.1:5248nats-route://127.0.0.1:6248]}# logging optionsdebug:falsetrace:truelogtime:falselog_file: "Nodea.log" # pid Filepi D_file: "Nodea.pid" # Some system overides# max_connectionsmax_connections:100# max_subscriptions (per connection) Max_ subscriptions:1000# Maximum protocol control linemax_control_line:512# maximum payloadmax_payload:65536# Duration the S Erver can block on a socket write to a client. Exceeding the# deadline would designate a client as a slow consumer.write_deadline: "2s"
nodeb.cfg
listen:localhost:5222 # Host/port to listen for client connectionshttp:localhost:5333 # HTTP monitoring port# Authorizat Ion for client Connectionsauthorization {#user: Yasenagat #./util/mkpasswd-p t0ps3cr3t #password: $2a$11$w2zko75 1kuvvy59mutwmpodwjpem5qhcczrd05gji/ssot.xtihyg #ytb token: $2a$11$toarkoxztstxxkcljofe4edmipq/ Ecab0m7v8mge1tfgov97.iece timeout:1}# Cluster definitioncluster {listen:localhost:5248 # Host/port for inbound route Connections # Authorization for route connections Authorization {#user: User1 #./util/mkpasswd-p t0ps3cr3tt00! #password: Pass1 #yctb token: $2A$11$ERIHSUV8WO7PWUXTXOCY5UP7MHASWLE2TQQQPUZ6KAOF89KHO8CCW timeout:0.5} # Routes is actively solicited and connected to from the this server. # Other servers can connect to us if they supply the correct credentials # on their routes definitions from above. Routes = [nats-route://127.0.0.1:4248 nats-route://127.0.0.1:6248]}# Logging Optionsdebug:falsetRace:truelogtime:falselog_file: "Nodeb.log" # pid Filepid_file: "Nodeb.pid" # Some system overides# Max_connectionsmax_c onnections:100# max_subscriptions (per connection) max_subscriptions:1000# Maximum protocol control Linemax_control_ line:512# Maximum payloadmax_payload:65536# Duration The server can block on a socket write to a client. Exceeding the# deadline would designate a client as a slow consumer.write_deadline: "2s"
nodec.cfg
listen:localhost:6222 # Host/port to listen for client connectionshttp:localhost:6333 # HTTP monitoring port# Authorizat Ion for client Connections#authorization {#user: Yasenagat #./util/mkpasswd-p t0ps3cr3t #password: $2a$11$w2zko7 51kuvvy59mutwmpodwjpem5qhcczrd05gji/ssot.xtihyg #ytc #token: $2a$11$ HZY0M3LCXXZJRSFHTAOIX.JCUQKLYZTCYYZPWRTLR.APHS/4MFYGC #timeout: 1#}# Cluster definitioncluster {listen:localhost : 6248 # Host/port for inbound Route connections # Authorization for route connections #authorization {#user: User2 #./util/mkpasswd-p t0ps3cr3tt00! #password: $2a$11$xh8dkgrty1cbntzjhpewjewu/ypbsu.rxjwms6sfilobxzmzomk9m #yctc #token: $2a$11$ Srwaibfhgwit37t3grpynohspz2lhttw1qxwuznxgoaknewulp4o6 #timeout: 0.5 #} # Routes is actively solicited and connected To from the this server. # Other servers can connect to us if they supply the correct credentials # on their routes definitions from above. Routes = [nats-route://127.0.0.1:5248nats-route://127.0.0.1:4248]}# logging optionsdebug:falsetrace:truelogtime:falselog_file: "Nodec.log" # pid Filepi D_file: "Nodec.pid" # Some system overides# max_connectionsmax_connections:100# max_subscriptions (per connection) Max_ subscriptions:1000# Maximum protocol control linemax_control_line:512# maximum payloadmax_payload:65536# Duration the S Erver can block on a socket write to a client. Exceeding the# deadline would designate a client as a slow consumer.write_deadline: "2s"