V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
The Go Programming Language
http://golang.org/
Go Playground
Go Projects
Revel Web Framework
wwhontheway
V2EX  ›  Go 编程语言

web 项目中,对于依赖的各种 client 初始化

  •  
  •   wwhontheway · 166 天前 · 1754 次点击
    这是一个创建于 166 天前的主题,其中的信息可能已经有所发展或是发生改变。

    这里的 client 举个例子,redis/mq/db 的 client 等,应该放在哪个目录下? pkg 下统一初始化好全局变量?还是 service 目录下跟着 service 走?

    第 1 条附言  ·  166 天前
    准备放到 internal/dependency 目录下面项目启动初始化,全局变量
    11 条回复    2024-06-21 20:00:53 +08:00
    BeautifulSoap
        1
    BeautifulSoap  
       166 天前 via Android   ❤️ 1
    lz 指 DDD 还是普通开发

    普通开发随便你折腾,一般找个地方 singleton 一下就行了,尤其 db ,每个实例内部维护有链接池,每次都新 new 的话 db 连接会很快耗尽(都是生产事故的教训)

    DDD 的话 domain service 里肯定不能 new 这种 infra 的,项目启动时 new 一下塞 di 里,或者用全局变量做个 lazyload 的 singleton 。我更喜欢在 domain 里为简单的 client 各自定义出一个抽象的接口,然后 domain entity 数据通过 repository 接口和 infra 进行交互
    ninjashixuan
        2
    ninjashixuan  
       166 天前   ❤️ 1
    项目不大就是全局变量然后塞 context 里传递,不然就折腾 wire ,dig 等 DI 工具。
    lasuar
        3
    lasuar  
       166 天前   ❤️ 1
    要么统一放到 global/ 下面,要么依赖注入。
    wwhontheway
        4
    wwhontheway  
    OP
       166 天前
    @BeautifulSoap 普通开发,也不想依赖注入
    bv
        5
    bv  
       166 天前
    依赖注入,用框架也可以,自己依赖注入也可以:

    ```go
    func Run(cfg Config) error {
    db, err := mysql.Open(cfg.Database)
    if err != nil {
    return err
    }
    defer db.Close()

    mq, err := kafka.Open(cfg.Kafka)
    if err != nil {
    return err
    }
    defer mq.Close()

    rdb, err := redis.Open(cfg.Redis)
    if err != nil {
    return err
    }
    defer rdb.Close()

    bar := NewBar(db, mq, rdb)

    return bar.Foo()
    }

    func NewBar(db *sql.DB, mq *kafka.Client, rdb *redis.Client) *Bar {
    return &Bar{
    db: db,
    mq: mq,
    rdb: rdb,
    }
    }

    type Bar struct {
    db *sql.DB
    mq *kafka.Client
    rdb *redis.Client
    }

    func (b *Bar) Foo() error {
    _, err := b.db.Exec("SELECT 1")
    return err
    }
    ```
    devhxy
        6
    devhxy  
       166 天前
    只要涉及到 singleton ,di 是最稳妥的办法,选个轻量级的就好
    推荐:github.com/samber/do
    dobelee
        7
    dobelee  
       166 天前
    微服务的话跟着 service 走就行。全局变量不是好范式,也不好 mock 。除非你要做成一个包单独提供服务。
    RedisMasterNode
        8
    RedisMasterNode  
       166 天前
    不是直接在项目根目录下做个 /datasource (命名可改)然后放各种 client 的目录就好了吗...
    ./
    --- cmd/
    --- pkg/
    --- internal/
    --- ...
    --- datasource
    --------- mysql
    --------- redis
    --------- kafka

    然后 internal 里调用 GetMySQL(xxx) 或者 GetRedis(xxx) 就能直接用了

    为啥要塞到某个结构体里...
    sophos
        9
    sophos  
       166 天前
    好问题,有兴趣的话可以看看这个

    https://github.com/go-kod/kod-mono
    Desdemor
        10
    Desdemor  
       165 天前
    DDD 的话跟 1 楼差不多, 项目启动的时候 依赖注入,给你个参考: https://github.com/8treenet/freedom
    qloog
        11
    qloog  
       150 天前
    放在各自的目录下去,比如:
    db 在 internal/models 下
    redis 在 internal/cache 下
    然后统一在 main.go 里调用对应的方法进行初始化

    参看: https://github.com/go-eagle/eagle/blob/master/main.go

    mq 是直接放到公共的 pkg 里的目录 比如 queue, 最后也在在启动服务的 main.go 里进行启动

    参看: https://github.com/go-eagle/eagle/blob/master/examples/queue/rabbitmq/consumer/main.go
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2902 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 21ms · UTC 15:03 · PVG 23:03 · LAX 07:03 · JFK 10:03
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.