golang nats[5] cluster叢集

來源:互聯網
上載者:User

叢集模式

nats的叢集模式對用戶端來說並不是透明的。
所以叢集對發行者和訂閱者都是有影響的。
發行者和訂閱者都知道串連的是一個叢集的服務,而不是一個單點服務,換句話說發行者訂閱者都必須指明叢集中各個節點的地址。
當然,發行者和訂閱者可以只針對叢集中的某節點發布訊息和訂閱訊息,不過這並不是叢集模式的目的。

目的

提高可用性和延展性。

實現原理

可用性,多個節點,掛掉任意一個,不影響整個叢集對外提供服務。
伸縮性,服務端支援隨意增加節點。訂閱者可以感知服務端節點的變動,但是發行者並不能自動感知。

3個node的叢集

$ gnatsd -p 4222 -m 4333 -cluster nats://localhost:4248 -routes nats://localhost:5248,nats://localhost:6248 -DV  $ gnatsd -p 5222 -m 5333 -cluster nats://localhost:5248 -routes nats://localhost:4248,nats://localhost:6248 -DV $ gnatsd -p 6222 -m 6333 -cluster nats://localhost:6248 -routes nats://localhost:4248,nats://localhost:5248 -DV 

-p 連接埠:服務連接埠,發行者,訂閱者需要使用此連接埠。
-m 連接埠: 監控連接埠。
-cluster 地址:作為叢集節點對其他節點提供服務的地址,其他節點需要串連的地址。(其他節點的-routes 可以填寫此地址)
-routes 地址:此節點,路由到其他地址的列表(也就是其他節點的-cluster)
-DV Debug and trace

gnatsd -p 服務提供連接埠 -m 服務監控連接埠 -cluster 叢集內node地址 -routes 叢集內其他node地址清單 -DV

Server

package mainimport (    "github.com/nats-io/go-nats"    "log"    "flag"    "fmt"    "time")const (    //url   = "nats://192.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(*subj, *servername+" worker2", *queueGroup)    //startService(*subj, *servername+" worker3", *queueGroup)    select {}}//receive 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://localhost:4222,nats://localhost:6222"    url = "nats://localhost:4222,nats://localhost:5222,nats://localhost:6222"    //url = "nats://localhost:5222")var (    nc  *nats.Conn    err error)func init() {    if nc, err = nats.Connect(url, nats.DontRandomize(), nats.MaxReconnects(10), 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}

注意

  • 發行者和訂閱者都需要指明3個節點的ur地址
    nats://localhost:4222,nats://localhost:5222,nats://localhost:6222
  • 如果3個node都不可用,發行者會發送訊息失敗。
  • 如果3個node至少有一個可用,訂閱者就會收到訊息。
  • 如果3個node全都不可用,訂閱者會自動中斷連線。
  • 增加一個node nats://localhost:7222,訂閱者可以自動連接。
  • 增加node後,3個node全都不可用,訂閱者不會中斷連線,可以接受從新node發布的訊息。
  • 3個node恢複後,訂閱者可以接受3個node的訊息。

後續

發行者和訂閱者

  • 原創組群中node都不可用
  • 主動查詢可用node
  • 接受可用node通知
  • 向可用node發送訊息,訂閱可用node的訊息
  • 以上內容需要配合服務發現中介軟體或者自己實現

設定檔啟動

$ 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# Authorization for client connections#authorization {  #user:     yasenagat  # ./util/mkpasswd -p T0pS3cr3t  #password: $2a$11$W2zko751KUvVy59mUTWmpOdWjpEm5qhcCZRd05GjI/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 are actively solicited and connected to from this server.  # Other servers can connect to us if they supply the correct credentials  # in their routes definitions from above.  routes = [    nats-route://127.0.0.1:5248    nats-route://127.0.0.1:6248  ]}# logging optionsdebug:   falsetrace:   truelogtime: falselog_file: "nodea.log"# pid filepid_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 server can block on a socket write to a client.  Exceeding the# deadline will 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# Authorization for client connectionsauthorization {  #user:     yasenagat  # ./util/mkpasswd -p T0pS3cr3t  #password: $2a$11$W2zko751KUvVy59mUTWmpOdWjpEm5qhcCZRd05GjI/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 are actively solicited and connected to from this server.  # Other servers can connect to us if they supply the correct credentials  # in 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_connections: 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 will 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# Authorization for client connections#authorization {  #user:     yasenagat  # ./util/mkpasswd -p T0pS3cr3t  #password: $2a$11$W2zko751KUvVy59mUTWmpOdWjpEm5qhcCZRd05GjI/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 are actively solicited and connected to from this server.  # Other servers can connect to us if they supply the correct credentials  # in their routes definitions from above.  routes = [    nats-route://127.0.0.1:5248    nats-route://127.0.0.1:4248  ]}# logging optionsdebug:   falsetrace:   truelogtime: falselog_file: "nodec.log"# pid filepid_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 server can block on a socket write to a client.  Exceeding the# deadline will designate a client as a slow consumer.write_deadline: "2s"
相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.