Testing NATS-streaming in Kubernetes with minimal effort

1.4k views Asked by At

I wanted to test a very basic application for NATS-streaming on Kubernetes. To do so, I followed the commands from the official NATS-docs.

It basically comes down to running

kubectl apply -f https://raw.githubusercontent.com/nats-io/k8s/master/nats-server/single-server-nats.yml
kubectl apply -f https://raw.githubusercontent.com/nats-io/k8s/master/nats-streaming-server/single-server-stan.yml

in a terminal with access to the cluster (it's a kind-cluster in my case).

I used stan.go as the NATS-streaming-client. Here is the code I tried to connect to the NATS-streaming-server:

package main

import stan "github.com/nats-io/stan.go"

func main() {
    sc, err := stan.Connect("stan", "test-client")

    if err != nil {
        panic(err)
    }
    if err := sc.Publish("test-subject", []byte("This is a test-message!")); err != nil {
        panic(err)
    }
}

and this is the error I'm getting:

panic: nats: no servers available for connection

goroutine 1 [running]:
main.main()
    /Users/thilt/tmp/main.go:9 +0x15d
exit status 2

so I think another name was used for the cluster or something. If I use the provided example with nats-box from the docs.nats-link above, it also doesn't work! Where did I go wrong here?

I will happily provide more information, if needed.

1

There are 1 answers

0
Matt On BEST ANSWER

There is a great example in stan.go docs:

// Connect to NATS
nc, err := nats.Connect(URL, opts...)
if err != nil {
    log.Fatal(err)
}
defer nc.Close()

sc, err := stan.Connect(clusterID, clientID, stan.NatsConn(nc))
if err != nil {
    log.Fatalf("Can't connect: %v.\nMake sure a NATS Streaming Server is running at: %s", err, URL)
}
defer sc.Close()

Your error happens because by default stan connects to localhost address (source code):

// DefaultNatsURL is the default URL the client connects to
DefaultNatsURL = "nats://127.0.0.1:4222"

Notice that povided above example overwrite this default connection.

Stan source code is short and easy to analyze. I really recommend you to try to analyze it and figure out what it does.


Now let's put it all together; here is a working example:

package main

import (
    nats "github.com/nats-io/nats.go"
    stan "github.com/nats-io/stan.go"
)

func main() {
    // Create a NATS connection 
    nc, err := nats.Connect("nats://nats:4222")
    if err != nil {
        panic(err)
    }

    // Then pass it to the stan.Connect() call.
    sc, err := stan.Connect("stan", "me", stan.NatsConn(nc))
    if err != nil {
        panic(err)
    }
    if err := sc.Publish("test-subject", []byte("This is a test-message!")); err != nil {
        panic(err)
    }
}