go lang中amqp.Dial是否线程安全时是否每次都创建连接

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

正如 RabbitMQ 文档中提到的那样,建立 tcp 连接的成本很高。因此,引入了通道的概念。现在我遇到了这个 example。在 main() 中,它会在每次发布消息时创建连接。 conn, err := amqp.Dial("amqp://guest:guest@localhost:5672/")。 它不应该全局声明一次并且应该有故障转移机制以防连接像单例对象一样关闭。如果 amqp.Dial 是线程安全的,我想它应该是

已编辑问题:

我正在按以下方式处理连接错误。我在其中收听频道并在出错时创建新连接。但是当我终止现有连接并尝试发布消息时。我收到以下错误。

错误:

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

代码:

 func main() {

        Conn, err := amqp.Dial("amqp://guest:guest@172.16.0.20: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:guest@172.16.0.20: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)  

    }

当然,您不应该为每个请求都创建一个连接。使其成为全局变量或 application context 的更好部分,您在启动时初始化一次。

您可以通过使用 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
}