【问题标题】:Gin + Golang + DB Connection PoolingGin + Golang + DB 连接池
【发布时间】:2018-05-12 16:43:48
【问题描述】:

我想了解 GIN 如何确保每个 HTTP 请求都获得一个唯一的数据库(例如 MySQL)连接。这是一个示例代码。 如果您看到,由于 'db' 是一个全局对象,因此 API router.GET("/person/:age"... 可以访问 DB。 现在有了负载,我想 GIN 将在内部实现并发。如果是,那么它如何确保每个请求获得不同的连接。如果不是,那么它是单线程实现。谁能纠正我的理解。

package main

import (
    //  "bytes"
    "database/sql"
    "fmt"
    "github.com/gin-gonic/gin"
    _ "github.com/go-sql-driver/mysql"
    "net/http"
)

func checkErr(err error) {
    if err != nil {
        panic(err)
    } else {
        fmt.Println("successful...")
    }
}

func main() {
    db, err := sql.Open("mysql", "abfl:abfl@tcp(127.0.0.1:3306)/abfl?charset=utf8")
    checkErr(err)
    defer db.Close()
    // make sure connection is available
    err = db.Ping()
    checkErr(err)
    type User struct {
        age  int
        name string
    }
    router := gin.Default()
    // Add API handlers here
    // GET a user detail
    router.GET("/person/:age", func(c *gin.Context) {
        var (
            user   User
            result gin.H
        )
        age := c.Param("age")
        fmt.Println("input age : '%d'", age)
        row := db.QueryRow("select age, name from user where age = ?", age)
        err = row.Scan(&user.age, &user.name)
        fmt.Printf("user : %+v\n", user)
        if err != nil {
            // If no results send null
            result = gin.H{
                "user":  nil,
                "count": 0,
            }
        } else {
            result = gin.H{
                "age":   user.age,
                "name":  user.name,
                "count": 1,
            }
        }
        c.JSON(http.StatusOK, result)
    })
    router.Run(":3000")
}

【问题讨论】:

  • 请务必正确格式化代码。正如最初发布的那样,它完全不可读。我编辑了它,但是……将来,请在发布时这样做。
  • 当然谢谢。为什么我的问题是-2 :)。这是一个无效的问题吗?伙计们,我正在寻找答案。
  • 为什么每个请求都需要单独的连接?事实上,好的框架可以缓存数据,因此页面加载可以不涉及数据库访问。数据库驱动程序也有自己的连接池。所以 web 和 db 请求之间没有直接关联。
  • 我建议您获取并阅读this ebook 以深入了解database/sql 的实现方式。 (我不隶属于本书的作者 FWIW。)
  • 伟大的@kostix。这很有帮助

标签: mysql rest go connection-pooling


【解决方案1】:

为每个 HTTP 请求建立新的 SQL 连接太繁重,没有意义。
在 go 中还没有用户可管理的连接池,它由 go 实现在内部处理。
sql.DB 可以并发使用,所以不用担心。
而 GIN 与 SQL 连接完全无关。正确处理查询/交易完全是您的责任。

【讨论】:

  • 这里是我上面提到的问题的复制粘贴:我正在寻找的是:如何在这个框架(杜松子酒)中使用“准备好的语句”。我不想看到它工作,因为每次 REST API 调用都在准备语句。这将是非常低效的。正确的逻辑是在创建准备好的语句时,它应该与连接紧密绑定。现在,如果我们使用连接池并且我们真的想使用 prep-stmt 句柄,那么我们应该有一个具有唯一数据库连接的每个 stmt 的映射。现在的问题是:它是否由 GIN 提供
  • 不,它没有。 Gin - 是一个 Web 工具,对 HTTP 传输层下的任何内容都没有任何作用。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-04-20
  • 1970-01-01
  • 2015-12-23
  • 1970-01-01
  • 1970-01-01
  • 2022-12-01
相关资源
最近更新 更多