Skip to content

Instantly share code, notes, and snippets.

@wallyqs
Last active February 18, 2024 22:27
Show Gist options
  • Save wallyqs/7f72efdc3fd6371364f8b28cbe32c5ee to your computer and use it in GitHub Desktop.
Save wallyqs/7f72efdc3fd6371364f8b28cbe32c5ee to your computer and use it in GitHub Desktop.
NATS Docker blog post/HTTP Server
package main
import (
"fmt"
"log"
"net/http"
"os"
"time"
"github.com/nats-io/nats"
)
type server struct {
nc *nats.Conn
}
func (s server) baseRoot(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, "Basic NATS based microservice example v0.0.1")
}
func (s server) createTask(w http.ResponseWriter, r *http.Request) {
requestAt := time.Now()
response, err := s.nc.Request("tasks", []byte("help please"), 5*time.Second)
if err != nil {
log.Println("Error making NATS request:", err)
}
duration := time.Since(requestAt)
fmt.Fprintf(w, "Task scheduled in %+v\nResponse: %v\n", duration, string(response.Data))
}
func (s server) healthz(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, "OK")
}
func main() {
var s server
var err error
uri := os.Getenv("NATS_URI")
for i := 0; i < 5; i++ {
nc, err := nats.Connect(uri)
if err == nil {
s.nc = nc
break
}
fmt.Println("Waiting before connecting to NATS at:", uri)
time.Sleep(1 * time.Second)
}
if err != nil {
log.Fatal("Error establishing connection to NATS:", err)
}
fmt.Println("Connected to NATS at:", s.nc.ConnectedUrl())
http.HandleFunc("/", s.baseRoot)
http.HandleFunc("/createTask", s.createTask)
http.HandleFunc("/healthz", s.healthz)
fmt.Println("Server listening on port 8080...")
if err := http.ListenAndServe(":8080", nil); err != nil {
log.Fatal(err)
}
}
$ docker-compose -f build.yml up
nats uses an image, skipping
Building api
Step 1 : FROM golang:1.6.2
---> 5850add7ecc2
Step 2 : COPY . /go
---> 188fa03a7cf5
Removing intermediate container 37ee6fd35e0d
Step 3 : RUN go build api-server.go
---> Running in 048e4010e539
---> 21dbaf567bbb
Removing intermediate container 048e4010e539
Step 4 : EXPOSE 8080
---> Running in b07dde665ad2
---> 3a6a59102f81
Removing intermediate container b07dde665ad2
Step 5 : ENTRYPOINT /go/api-server
---> Running in e3c5de88d6d4
---> faf4d12797f3
Removing intermediate container e3c5de88d6d4
Successfully built faf4d12797f3
Building worker
Step 1 : FROM golang:1.6.2
---> 5850add7ecc2
Step 2 : COPY . /go
---> Using cache
---> 0376e8a54e9d
Step 3 : RUN go build worker.go
---> Using cache
---> 1a53e068ad91
Step 4 : EXPOSE 8080
---> Using cache
---> 77b8a0e0ab4f
Step 5 : ENTRYPOINT /go/worker
---> Using cache
---> 7d23b0d4e846
Successfully built 7d23b0d4e846
version: "2"
services:
nats:
image: 'nats:0.8.0'
entrypoint: "/gnatsd -DV"
expose:
- "4222"
ports:
- "8222:8222"
hostname: nats-server
api:
build:
context: "./api"
entrypoint: /go/api-server
links:
- nats
environment:
- "NATS_URI=nats://nats:4222"
depends_on:
- nats
ports:
- "8080:8080"
worker:
build:
context: "./worker"
entrypoint: /go/worker
links:
- nats
environment:
- "NATS_URI=nats://nats:4222"
depends_on:
- nats
ports:
- "8181:8181"
FROM golang:1.6.2
COPY . /go
RUN go get github.com/nats-io/nats
RUN go build api-server.go
EXPOSE 8080
ENTRYPOINT ["/go/api-server"]
$ docker-compose -f build.yml up
nats_1 | [1] 2016/06/14 01:30:25.563332 [INF] Starting nats-server version 0.8.0
nats_1 | [1] 2016/06/14 01:30:25.564371 [DBG] Go build version go1.6.2
nats_1 | [1] 2016/06/14 01:30:25.564392 [INF] Listening for client connections on 0.0.0.0:4222
nats_1 | [1] 2016/06/14 01:30:25.564444 [DBG] Server id is VYcRrgxx6c097Tq62NIIVp
nats_1 | [1] 2016/06/14 01:30:25.564451 [INF] Server is ready
nats_1 | [1] 2016/06/14 01:30:25.799723 [DBG] 172.18.0.3:32999 - cid:1 - Client connection created
nats_1 | [1] 2016/06/14 01:30:25.800213 [TRC] 172.18.0.3:32999 - cid:1 - ->> [CONNECT {"verbose":false,"pedantic":false,"tls_required":false,"name":"","lang":"go","version":"1.2.0"}]
nats_1 | [1] 2016/06/14 01:30:25.800308 [TRC] 172.18.0.3:32999 - cid:1 - ->> [PING]
nats_1 | [1] 2016/06/14 01:30:25.800311 [TRC] 172.18.0.3:32999 - cid:1 - <<- [PONG]
nats_1 | [1] 2016/06/14 01:30:25.800703 [TRC] 172.18.0.3:32999 - cid:1 - ->> [SUB tasks 1]
worker_1 | 2016/06/14 01:30:25 Connected to NATS at nats://nats:4222
worker_1 | 2016/06/14 01:30:25 Worker subscribed to 'tasks' for processing requests...
worker_1 | 2016/06/14 01:30:25 Server listening on port 8181...
nats_1 | [1] 2016/06/14 01:30:26.009136 [DBG] 172.18.0.4:47156 - cid:2 - Client connection created
nats_1 | [1] 2016/06/14 01:30:26.009536 [TRC] 172.18.0.4:47156 - cid:2 - ->> [CONNECT {"verbose":false,"pedantic":false,"tls_required":false,"name":"","lang":"go","version":"1.2.0"}]
nats_1 | [1] 2016/06/14 01:30:26.009562 [TRC] 172.18.0.4:47156 - cid:2 - ->> [PING]
nats_1 | [1] 2016/06/14 01:30:26.009566 [TRC] 172.18.0.4:47156 - cid:2 - <<- [PONG]
api_1 | 2016/06/14 01:30:26 Connected to NATS at nats://nats:4222
api_1 | 2016/06/14 01:30:26 Server listening on port 8080...
FROM golang:1.6.2
COPY . /go
RUN go get github.com/nats-io/nats
RUN go build worker.go
EXPOSE 8080
ENTRYPOINT ["/go/worker"]
package main
import (
"fmt"
"log"
"net/http"
"os"
"time"
"github.com/nats-io/nats"
)
func healthz(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, "OK")
}
func main() {
uri := os.Getenv("NATS_URI")
var err error
var nc *nats.Conn
for i := 0; i < 5; i++ {
nc, err = nats.Connect(uri)
if err == nil {
break
}
fmt.Println("Waiting before connecting to NATS at:", uri)
time.Sleep(1 * time.Second)
}
if err != nil {
log.Fatal("Error establishing connection to NATS:", err)
}
fmt.Println("Connected to NATS at:", nc.ConnectedUrl())
nc.Subscribe("tasks", func(m *nats.Msg) {
fmt.Println("Got task request on:", m.Subject)
nc.Publish(m.Reply, []byte("Done!"))
})
fmt.Println("Worker subscribed to 'tasks' for processing requests...")
fmt.Println("Server listening on port 8181...")
http.HandleFunc("/healthz", healthz)
if err := http.ListenAndServe(":8181", nil); err != nil {
log.Fatal(err)
}
}
@wallyqs
Copy link
Author

wallyqs commented Jun 14, 2016

screen shot 2016-06-14 at 8 56 23 am

@gotstago
Copy link

Great article!

One suggestion. Both Dockerfile definitions should include;

RUN go get github.com/nats-io/nats

I had to include this to get it working.

Thanks!

@gotstago
Copy link

and...

In worker.go;

func healthz(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, "OK")
}

@wallyqs
Copy link
Author

wallyqs commented Jun 23, 2016

Thanks, updated in the gist...

@nehasenna
Copy link

Great article!
One suggestion. Both Dockerfile definitions should include;
RUN go get
I had to include this to http://www.freshersmirror.com/ get it working.
[Thanks!]

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment