-
The documentation example shows how to create a For example, a restful interface that sends out messages based on the endpoint, would each call use the same Assuming going to the same queue, changing func main() {
queueName := "myqueue"
addr, _ := os.LookupEnv("MQSERVER")
queue := New(queueName, addr)
message := []byte("message")
ctx, cancel := context.WithDeadline(context.Background(), time.Now().Add(time.Second*20))
defer cancel()
go Publish(ctx, queue, append(message, []byte(" 1")...)) // should these be "new" queues or just new channels?
go Publish(ctx, queue, append(message, []byte(" 2")...))
<-ctx.Done()
}
func Publish(ctx context.Context, queue *Client, message []byte) {
loop:
for {
select {
// Attempt to push a message every 2 seconds
case <-ctx.Done():
fmt.Printf("Context Timed Out!\n")
if err := queue.Close(); err != nil {
fmt.Printf("Closing failed: %v", err)
}
break loop
case <-time.After(time.Second * 2):
if err := queue.Push(message); err != nil {
fmt.Printf("Push failed: %s\n", err)
} else {
fmt.Printf("%s\n", message)
}
}
}
} Perhaps a section on best practices for connections and channels? |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 2 replies
-
Generally, the best practice is to have long-lived connections and create new channels as needed. It also important to not use the same channel by multiple threads; instead, use one channel per thread/go-routine. Another common pitfall is to use the same channel to publish and consume. It's best advised to use separate channels for consumption and publishing, because RabbitMQ may block a publisher channel due to an alarm (e.g. high memory usage), if consumers are using this channel, they will be blocked as well. I recommend to have a look at the production check list, the apps section: https://rabbitmq.com/production-checklist.html#apps Answering your question, I would have my restful interface get a new channel from the same connection. If you are building on top of the example, you will have to implement a locking mechanism to avoid races, and you will have to modify slightly the recovery mechanism to recover all known channels after a connection closed event. Note that the example aims to showcase the functions and mechanisms available to handle recovery; it is not production ready, rock-solid code.
Another point for consideration, if this is an HTTP based API, you would benefit greatly from having a connection pool. If you don't want to maintain your own connection pool, you may consider using a proxy like https://github.com/bloomberg/amqpprox or https://github.com/cloudamqp/amqproxy |
Beta Was this translation helpful? Give feedback.
Generally, the best practice is to have long-lived connections and create new channels as needed. It also important to not use the same channel by multiple threads; instead, use one channel per thread/go-routine.
Another common pitfall is to use the same channel to publish and consume. It's best advised to use separate channels for consumption and publishing, because RabbitMQ may block a publisher channel due to an alarm (e.g. high memory usage), if consumers are using this channel, they will be blocked as well.
I recommend to have a look at the production check list, the apps section: https://rabbitmq.com/production-checklist.html#apps
This covers important topics, like connection/channe…