为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

Go
慕神8447489 2021-12-27 15:44:38
正如 RabbitMQ 文档中提到的,tcp 连接的建立成本很高。因此,引入了通道的概念。现在我遇到了这个例子。在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 connectionexit status 17: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)      }
查看完整描述

1 回答

?
千巷猫影

TA贡献1829条经验 获得超7个赞

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


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

}


查看完整回答
反对 回复 2021-12-27
  • 1 回答
  • 0 关注
  • 294 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信