重新连接外部数据库的好模式是什么?

huangapple go评论85阅读模式
英文:

What is a good pattern for reconnecting external databases?

问题

当我发现持久连接断开时,我该如何高效地重新连接到外部数据库?如果ExtClient失去连接,它会在err上返回"Broken pipe"。

如何在这个方法或另一个方法中以高效的方式重新连接?对这段代码的任何改进也是受欢迎的。ExtClient不会自动重新连接,它是一个全局变量。

英文:

How can I efficiently reconnect to an external database when I find out that the persistent connection is down? If ExtClient loses connection, it would return "Broken pipe" on err.

func ListenForWork(cmdChannel <-chan *WorkCmd) {
    for {
        cmd, ok := <- cmdChannel
        if !ok {
            break
        }
        for { // Retry request until it's OK (`Broken pipe error` might destroy it)
            _, err := ExtClient.Request(cmd.Key, cmd.Value)
            if err == nil {
                break
            }
        }
    }
}

How can I, from this or another method, reconnect in an efficient way? Any improvements in this code is welcome as well. ExtClient does not reconnect on its own and is a global variable.

答案1

得分: 3

如果您正在使用mymysql,那么您可以使用自动重新连接接口

从文档中可以看到:

import (
    "github.com/ziutek/mymysql/autorc"
    _ "github.com/ziutek/mymysql/thrsafe" // 您也可以使用原生引擎
)

// [...]

db := autorc.New("tcp", "", "127.0.0.1:3306", user, pass, dbname)

// 初始化命令。它们将在每次连接后执行。
db.Register("set names utf8")

// 不需要显式连接到MySQL服务器
rows, res, err := db.Query("SELECT * FROM R")
checkError(err)

// 现在我们已经连接上了。

// 即使在睡眠期间连接中断也没有关系,例如
// 由于服务器重启或网络中断。

话虽如此,从阅读sql文档sql驱动程序文档以及相关代码来看,如果SQL驱动程序返回ErrBadConn,那么sql包将使用新的连接进行重试。这个功能是在2012年7月才添加的,所以可能还没有得到SQL驱动程序的很好支持。

英文:

If you are using mymysql then you can use the auto reconnection interface.

From the docs

import (
    "github.com/ziutek/mymysql/autorc"
    _ "github.com/ziutek/mymysql/thrsafe" // You may also use the native engine
)

// [...]

db := autorc.New("tcp", "", "127.0.0.1:3306", user, pass, dbname)

// Initilisation commands. They will be executed after each connect.
db.Register("set names utf8")

// There is no need to explicity connect to the MySQL server
rows, res, err := db.Query("SELECT * FROM R")
checkError(err)

// Now we are connected.

// It does not matter if connection will be interrupted during sleep, eg
// due to server reboot or network down.

That said, from reading the sql docs and sql driver docs and the associated code, it looks like that if the SQL driver returns ErrBadConn then the sql package will retry with a new connection. This was only added in July 2012 so perhaps isn't well supported by SQL drivers yet.

答案2

得分: 0

假设ExtClient有一个Connect或Reconnect方法。

还假设BrokenPipe错误被导出为一个可以匹配的变量。

那么这样应该可以工作:if err == BrokenPipeErr { ExtClient.Connect(args ...SomeType) }

不过这些都是很多假设,所以你可能应该告诉我们更多信息,比如你连接的是哪个数据库,你使用的是哪个客户端库,以及其他相关信息。

英文:

Assuming ExtClient has a Connect or Reconnect method.

And also assuming that the BrokenPipe err is exported as a variable that you can match agains.

Then this should work if err == BrokenPipeErr { ExtClient.Connect(args ...SomeType) }

Those are a lot of assumptions though so you should probably tell us a little bit more information like what database you are connecting to. Which client lib you are using. And other such information.

huangapple
  • 本文由 发表于 2013年3月14日 04:38:18
  • 转载请务必保留本文链接:https://go.coder-hub.com/15395978.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定