首页  >  文章  >  后端开发  >  Go 中的 AMQP 连接应该是全局的还是为每个消息创建?

Go 中的 AMQP 连接应该是全局的还是为每个消息创建?

Patricia Arquette
Patricia Arquette原创
2024-10-28 08:51:29622浏览

 Should AMQP Connections in Go be Global or Created for Each Message?

在 AMQP Dial 中管理连接

在 Go 中, amqp.Dial 函数用于建立与 AMQP 服务器的连接。但是,有人担心 amqp.Dial 函数是否应该在每次发送消息时调用,或者是否可以全局声明并重用于多个操作。

全局连接管理

正如官方文档中提到的,TCP 连接的建立可能会占用大量资源。为了优化性能,AMQP 中引入了通道的概念,允许在单个连接上创建多个通道。

因此,一般建议只创建一次 AMQP 连接,作为全局变量,并且将其重用于所有后续操作。这减少了每次建立新连接所需的开销。

线程安全

amqp.Dial 函数是线程安全的,可以从多个 goroutine 并发调用。这允许在必要时创建多个连接,而无需任何竞争条件。

连接失败处理

要优雅地处理连接失败,您可以使用 Connection. NotifyClose 方法注册一个通道以在连接关闭时接收通知。这使您能够根据需要进行检测并重新连接。

在提供的示例中,代码侦听通道并在发生错误时尝试重新建立连接。但是,在终止现有连接并尝试发布消息时会发生错误。这可能是由于现有通道仍保留对已关闭连接的引用。

要解决此问题,您还应该在重新建立连接时关闭所有活动通道以避免意外行为。

错误处理示例

这是一个包含连接失败处理的示例:

<code class="go">import (
    "context"
    "log"
    "sync"
    "time"

    "github.com/streadway/amqp"
)

var (
    connOnce sync.Once
    conn     *amqp.Connection
)

func main() {
    connOnce.Do(func() {
        var err error
        conn, err = amqp.Dial("amqp://guest:guest@localhost:5672/")
        if err != nil {
            log.Panicf("Failed to connect: %v", err)
        }
    })

    c := make(chan *amqp.Error)
    conn.NotifyClose(c)

    go func() {
        for {
            err := <-c
            log.Println("reconnect: " + err.Error())
            connOnce.Do(func() {
                var err error
                conn, err = amqp.Dial("amqp://guest:guest@localhost:5672/")
                if err != nil {
                    log.Panicf("Failed to connect: %v", err)
                }
            })
            conn.NotifyClose(c)
            // Give time for any pending messages to be delivered
            // after reconnection
            time.Sleep(5 * time.Second)
        }
    }()

    // Create channels and perform operations here
    // ...

    // Close the connection when done
    defer conn.Close()
}</code>

在此示例中,使用sync.Once 创建了一个全局连接。类型以确保它只被初始化一次。 Connection.NotifyClose 方法用于监视连接失败并根据需要重新建立连接。

以上是Go 中的 AMQP 连接应该是全局的还是为每个消息创建?的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn