当前位置: 首页 > 面试题库 >

在go lang中是否在amqp.Dial具有线程安全性时每次创建连接

陶高扬
2023-03-14
问题内容

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

    }

问题答案:

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

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


 类似资料:
  • 我使用Eclipse数据库开发视角手动创建了一个模式和几个表。但是每当我试图从代码访问表时,我都会得到“架构不存在”错误。但是,如果我在使用这些表之前在程序中创建这些表,一切都会顺利。每次连接到数据库时都必须创建表吗?因为,我正在测试我的代码,我必须多次重启项目。

  • 我有一个在Oracle 11g DB上运行的insert语句,如下所示: 这里有一个处理PostgreSQL的类似问题。但是,由于Oracle序列由所有会话共享,所以我不能相信DB会给出当前会话中最后插入的值。

  • 问题内容: 我知道文档说明该对象是线程安全的,但这是否意味着从所有方法对其进行的所有访问都是线程安全的?因此,如果我一次从多个线程中调用它,并且一次在同一实例上调用它,会不会发生什么不好的事情? 问题答案: 快速答案是肯定的,它们是线程安全的。但是不要让它在那里… 首先,一个小的内部管理是一个接口,任何不是线程安全的实现都将破坏书面合同。您包括的链接是指,它具有一定的灵巧性。 您包含的链接引起了一

  • 我有以下ThreadPoolTaskExecator2配置 在我的公共类AdminService中,我有两个方法。 void triggerJob() 布尔执行sql(字符串sql) 如何将ThreadPoolTaskExecutor插入triggerJob方法,以便在第一个方法中调用executeSql时创建新线程。 在triggerjob中,我有一个基于条件调用executeSql的循环。 我

  • 问题内容: 我一直在假设线程安全也不是线程安全,但是在最近的一次讨论中,一位同事告诉我线程安全。 因此,我做了一些研究,却一无所获。很多人认为它是线程安全的,很多人认为它不是线程安全的。而且,最重要的是,文档没有以一种或另一种方式说任何话,不是为了,甚至不是。 那是什么呢? 问题答案: 这是指向Java 7 中Calendar和GregorianCalendar的源代码的链接。 如果阅读该代码,您

  • null 有些问题似乎是这样说的: 如何为多个用户隔离Jetty HttpClient?