【问题标题】:Whether to create connection every time when amqp.Dial is threadsafe or not in go lang在 go lang 中 amqp.Dial 是否为线程安全时是否每次都创建连接
【发布时间】:2016-03-23 13:09:40
【问题描述】:

正如 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)  

    }

【问题讨论】:

  • 据我所见,连接仅在链接示例中创建一次。您应该在问题中包含相应的代码。
  • 不,但是假设我有一个 http 处理程序,每次您需要在队列中推送对象时都会调用它。那么,我们应该在对 rabbitmq 的每个请求上创建连接还是只使用一个连接。

标签: go rabbitmq rabbitmqctl


【解决方案1】:

当然,您不应该为每个请求都创建一个连接。使其成为全局变量或 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
}

【讨论】:

  • 能否详细说明一下。我是新来的。所以,不要有太多想法。我已经编辑了这个问题。你能指出我错的地方吗?
  • 您是否在重新连接时重新声明拓扑(创建通道等)?
  • 不,我只是重新创建连接。正如您在代码中看到的那样。我已经粘贴了我的问题
  • 建立连接后需要重新声明拓扑。你可以把它放在一些你可以在启动时和重新连接后调用的函数中。
  • 但是我为每个发布消息的请求创建了 RabbitMQ 通道(不要与 go 通道混淆)。现在我该如何重新声明它。能否请您使用代码给我建议。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-08-21
  • 1970-01-01
相关资源
最近更新 更多