如何在Golang中共享服务连接

时间:2017-05-09 20:34:09

标签: elasticsearch go

我是Go的新手,看看elastic library for go,在“入门”示例中,它说“你通常会为你的应用创建一个客户端。”

这是什么意思?您是否在function confirmEnding (str, target) { return str.substr(-(target.length) === target } 函数中创建了一个客户端,并以某种方式将其传递给context的函数?您是否创建了一个全局变量并将其分配给客户端,如下所示?

main

2 个答案:

答案 0 :(得分:2)

这进入了一个有争议的主题:依赖注入。

与其他一些语言不同,我们通常不会相信复杂的IOC容器,xml配置和基于反射的工具。我只遵循一些简单的原则:

  1. 应用程序包和组件应该明确地将所有依赖项传递给它们。优选作为界面类型。如果我的web包需要数据库连接和弹性客户端,它可能有Serve(addr string, db database.DB, client *elastic.Client)之类的函数,其中DB是我的应用程序数据库的接口类型。
  2. main的工作主要是阅读配置,创建所有共享组件,并将它们传递给各个组件:

    func main(){
      var config = readConfig() //flags, json, whatever
      var elastic = elastic.NewClient(config.whatever)
      var db = database.New(config.Connectionstring)
    
      //now start app components
      web.Serve(config.Addr, db, elastic)
    }
    
  3. 我发现这种模式有助于保持我的包裹分离但可互操作。我试图避免任何需要在运行之间更改的包级别变量。

答案 1 :(得分:1)

我会创建包含这些对象的特殊类型。

type AppFactory struct {
  Client          *http.Client
  DatastoreClient *datastore.Client
  FileStorage     FileStorage
  DB              DB
} 

或者您可以使用context.Context

type key int
const clientKey key = 0

func NewContext(ctx context.Context, client *elastic.Client) context.Context {
    return context.WithValue(ctx, clientKey, client)
}

func ClientFromContext(ctx context.Context) *elastic.Client {
    client := ctx.Value(clientKey).(*elastic.Client)
    return client
}

就个人而言,我会使用context.Context,因为它是更普遍的解决方案。

我不认为使用全局变量是个好主意。 很快它就会成为一个问题。