最佳实践打开数据库。

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

Best Practise opening DB

问题

注意:我不确定这是否是这篇文章的最准确的标题,如果不是,请提供一个更好的标题。

目前,我正在创建一个服务器,其中包含几个处理程序(使用goji)。在接收到请求后,我想要与我拥有的MongoDB数据库进行交互(使用mgo)。我的问题是:

我假设每次处理请求时执行这种操作是昂贵的:

uri := os.Getenv("MONGOHQ_URL")

if uri == "" {
    panic("no DB connection string provided")
}

session, err := mgo.Dial(uri)

那么,对我来说,是否更好的做法是拥有一个可以从处理程序内部访问的全局变量呢? 所以我会这样做:

var session *mgo.Session

func main() {
    session = setupDB()
    defer session.Close()

    goji.Get("/user", getUser)
    goji.Serve()
}

func getUser(c web.C, w http.ResponseWriter, r *http.Request) {
    // 在这里使用 session 变量
}

我的问题与在这里应该采用什么最佳实践有关?是每次请求到来时打开数据库,还是在整个应用程序的生命周期内保持数据库连接打开?

英文:

Note: I am not sure if this is the most accurate title for this post, if not, please advise on a better one.

Currently I am creating a server where I have a couple of handlers (using goji). After receiving a request, I want to interact with a MongoDB database I have (using mgo). My question is:

I am assuming doing this kind of stuff every time I am handling a request is expensive:

uri := os.Getenv("MONGOHQ_URL")

if uri == "" {

	panic("no DB connection string provided")
}

session, err := mgo.Dial(uri)

So, would it be better for me to have a global var that I can access from inside the handlers? So I would go with something like this:

var session *mgo.Session

func main() {

	session = setupDB()
	defer session.Close()

	goji.Get("/user", getUser)
	goji.Serve()
}

func getUser(c web.C, w http.ResponseWriter, r *http.Request) {
// Use the session var here
}

My question is related to what would be the best practise here? Opening the DB every time a request comes in, or keep it open for the entire duration of the application.

答案1

得分: 1

你可以像这样将你的处理程序包装在一个Controller结构体中:(http://play.golang.org/p/NK6GO_lqgk)

package main

import (
	"fmt"
	"log"
	"net/http"
	"os"

	"github.com/zenazn/goji"
	"github.com/zenazn/goji/web"
)

type Controller struct {
	session *Session
}

func NewController() (*Controller, error) {
	if uri := os.Getenv("MONGOHQ_URL"); uri == "" {
		return nil, fmt.Errorf("no DB connection string provided")
	}
	session, err := mgo.Dial(uri)
	if err != nil {
		return nil, err
	}
	return &Controller{
		session: session,
	}, nil
}

func (c *Controller) getUser(c web.C, w http.ResponseWriter, r *http.Request) {
	// 在这里使用session变量
}

func main() {
	ctl, err := NewController()
	if err != nil {
		log.Fatal(err)
	}
	defer ctl.session.Close()

	goji.Get("/user", ctl.getUser)
	goji.Serve()
}

这样你可以将session嵌入到处理程序中并添加任何其他你可能需要的数据

<details>
<summary>英文:</summary>

What about wraping your handler in a Controller struct like this: (http://play.golang.org/p/NK6GO_lqgk)

    package main
    
    import (
    	&quot;fmt&quot;
    	&quot;log&quot;
    	&quot;net/http&quot;
    	&quot;os&quot;

    	&quot;github.com/zenazn/goji&quot;
	    &quot;github.com/zenazn/goji/web&quot;
    )
    
    type Controller struct {
    	session *Session
    }
    
    func NewController() (*Controller, error) {
    	if uri := os.Getenv(&quot;MONGOHQ_URL&quot;); uri == &quot;&quot; {
    		return nil, fmt.Errorf(&quot;no DB connection string provided&quot;)
    	}
    	session, err := mgo.Dial(uri)
    	if err != nil {
    		return nil, err
    	}
    	return &amp;Controller{
    		session: session,
    	}, nil
    }
    
    func (c *Controller) getUser(c web.C, w http.ResponseWriter, r *http.Request) {
    	// Use the session var here
    }
    
    func main() {
    	ctl, err := NewController()
    	if err != nil {
    		log.Fatal(err)
    	}
    	defer ctl.session.Close()
    
    	goji.Get(&quot;/user&quot;, ctl.getUser)
    	goji.Serve()
    }

This way, you can embed your session in your handler and add any other data that you might need.


</details>



huangapple
  • 本文由 发表于 2014年8月29日 22:23:49
  • 转载请务必保留本文链接:https://go.coder-hub.com/25570321.html
匿名

发表评论

匿名网友

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

确定