Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Whether to create connection every time when amqp.Dial is threadsafe or not in go lang

As it is mentioned in the RabbitMQ docs that tcp connections are expensive to make. So, for that concept of channel was introduced. Now i came across this example. In the main() it creates the connection everytime a message is publised. conn, err := amqp.Dial("amqp://guest:guest@localhost:5672/"). Shouldn't it be declared globally once and there should be failover mechanism in case connection get closed like singleton object. If amqp.Dial is thread-safe, which i suppose it should be

Edited question :

I am handling the connection error in the following manner. In which i listen on a channel and create a new connection on error. But when i kill the existing connection and try to publish message. I get the following error.

error :

2016/03/30 19:20:08 Failed to open a channel: write tcp 172.16.5.48:51085->172.16.0.20:5672: use of closed network connection
exit status 1
7:25 PM

Code :

 func main() {

        Conn, err := amqp.Dial("amqp://guest:[email protected]:5672/")
        failOnError(err, "Failed to connect to RabbitMQ")
         context := &appContext{queueName: "QUEUENAME",exchangeName: "ExchangeName",exchangeType: "direct",routingKey: "RoutingKey",conn: Conn}
        c := make(chan *amqp.Error)

        go func() {
            error := <-c
            if(error != nil){                
                Conn, err = amqp.Dial("amqp://guest:[email protected]:5672/")            
                failOnError(err, "Failed to connect to RabbitMQ")            
                Conn.NotifyClose(c)                                           
            }            
        }()

        Conn.NotifyClose(c)
        r := web.New()
        // We pass an instance to our context pointer, and our handler.
        r.Get("/", appHandler{context, IndexHandler})
        graceful.ListenAndServe(":8086", r)  

    }
like image 702
Naresh Avatar asked Mar 23 '16 13:03

Naresh


People also ask

Should I close RabbitMQ connection?

Don't open and close connections or channels repeatedly. Channels can be opened and closed more frequently if needed. Even channels should be long-lived if possible, e.g., reuse the same channel per thread for publishing.

How many connections can RabbitMQ handle?

Below is the default TCP socket option configuration used by RabbitMQ: TCP connection backlog is limited to 128 connections.

How do I create a connection in RabbitMQ?

In order for a client to interact with RabbitMQ it must first open a connection. This process involves a number of steps: Application configures the client library it uses to use a certain connection endpoint (e.g. hostname and port) The library resolves the hostname to one or more IP addresses.


1 Answers

Of course, you shouldn't create a connection for each request. Make it a global variable or better part of an application context which you initialize once at startup.

You can handle connection errors by registering a channel using Connection.NotifyClose:

func initialize() {
  c := make(chan *amqp.Error)
  go func() {
    err := <-c
    log.Println("reconnect: " + err.Error())
    initialize()
  }()

  conn, err := amqp.Dial("amqp://guest:guest@localhost:5672/")
  if err != nil {
    panic("cannot connect")
  }
  conn.NotifyClose(c)

  // create topology
}
like image 96
Sebastian Avatar answered Sep 29 '22 11:09

Sebastian