AMQP Go Client
The recommended Go client is amqp-client.go. It has no dependencies, reconnects on its own, and recovers queues and consumers after a reconnect. Install it with:
go get github.com/cloudamqp/amqp-client.go
Publish and consume
The example reads the broker URL from BROKER_URL and falls back to a local LavinMQ at amqp://guest:guest@localhost.
Save the connection code as main.go:
package main
import (
"context"
"fmt"
"log"
"os"
"os/signal"
amqp "github.com/cloudamqp/amqp-client.go"
)
func main() {
if len(os.Args) != 2 || (os.Args[1] != "publish" && os.Args[1] != "worker") {
fmt.Fprintln(os.Stderr, "Usage: go run . publish|worker")
os.Exit(2)
}
ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt)
defer stop()
c, err := connect(ctx)
if err != nil {
log.Fatal(err)
}
defer c.Close()
if os.Args[1] == "publish" {
err = runPublisher(ctx, c, "hello", "Hello world!")
} else {
err = runWorker(ctx, c, "hello", func(message string) error {
log.Printf(" [x] Received '%s'", message)
return nil
})
}
if err != nil {
log.Fatal(err)
}
}
// connect connects to BROKER_URL, and reconnects if the connection is lost.
func connect(ctx context.Context) (*amqp.Client, error) {
url := os.Getenv("BROKER_URL")
if url == "" {
url = "amqp://guest:guest@localhost"
}
return amqp.NewClient(ctx, url, nil)
}
Save the publisher as publisher.go:
package main
import (
"context"
"log"
amqp "github.com/cloudamqp/amqp-client.go"
)
// runPublisher publishes a persistent message and returns once the broker has confirmed it.
func runPublisher(ctx context.Context, c *amqp.Client, queue, message string) error {
q, err := c.Queue(ctx, queue, nil)
if err != nil {
return err
}
if err := q.Publish(ctx, amqp.Message{Body: message}); err != nil {
return err
}
log.Printf(" [x] Sent '%s'", message)
return nil
}
Save the consumer as worker.go in the same directory:
package main
import (
"context"
"log"
amqp "github.com/cloudamqp/amqp-client.go"
)
// runWorker calls handler for each message until ctx is done, with a prefetch of 10.
// The message is acked when handler returns nil, and requeued when it returns an error.
func runWorker(ctx context.Context, c *amqp.Client, queue string, handler func(message string) error) error {
q, err := c.Queue(ctx, queue, nil)
if err != nil {
return err
}
_, err = q.Subscribe(ctx, func(ctx context.Context, d *amqp.Delivery) error {
return handler(string(d.Body))
}, &amqp.SubscribeOptions{Prefetch: 10})
if err != nil {
return err
}
log.Println(" [*] Waiting for messages. To exit press CTRL+C")
<-ctx.Done()
return nil
}
The go.mod for the project lives in the example repo. Run go run . worker in one terminal and go run . publish in another.
The full, runnable example lives in go/amqp-client in cloudamqp/examples, and CI tests it against LavinMQ.
Good to know
- Messages get acked after the handler returns nil. If the handler returns an error or panics, the client nacks the message and LavinMQ requeues it. A message can arrive twice after a reconnect, so keep handlers idempotent.
- Set a prefetch limit.
Subscribedefaults to a prefetch of 20. The example lowers it with&amqp.SubscribeOptions{Prefetch: 10}, which keeps a consumer from buffering more than it can handle. - Reconnects never give up by default. The client retries with a backoff from 1s up to 30s, then declares queues and bindings again and restarts subscriptions.
ClientOptions.MaxRetriessets a limit. - Use
amqps://for TLS. The client verifies the server certificate and hostname.
The amqp-client.go README covers codecs, RPC and the low-level API.
Other Go clients
- amqp091-go, the low-level client maintained by the RabbitMQ team
Ready to take the next steps?
Managed LavinMQ instance via CloudAMQP
LavinMQ has been built with performance and ease of use in mind - we've benchmarked a throughput of about 1,000,000 messages/sec. You can try LavinMQ without any installation hassle by creating a free instance on CloudAMQP. Signing up is a breeze.
Get started with CloudAMQP ->Help and feedback
We welcome your feedback and are eager to address any questions you may have about this piece or using LavinMQ. Join our Slack channel to connect with us directly. You can also find LavinMQ on GitHub.