Golang Go语言中web项目里依赖的各种client初始化
这里的 client 举个例子,redis/mq/db 的 client 等,应该放在哪个目录下? pkg 下统一初始化好全局变量?还是 service 目录下跟着 service 走?
Golang Go语言中web项目里依赖的各种client初始化
lz 指 DDD 还是普通开发
普通开发随便你折腾,一般找个地方 singleton 一下就行了,尤其 db ,每个实例内部维护有链接池,每次都新 new 的话 db 连接会很快耗尽(都是生产事故的教训)
DDD 的话 domain service 里肯定不能 new 这种 infra 的,项目启动时 new 一下塞 di 里,或者用全局变量做个 lazyload 的 singleton 。我更喜欢在 domain 里为简单的 client 各自定义出一个抽象的接口,然后 domain entity 数据通过 repository 接口和 infra 进行交互
更多关于Golang Go语言中web项目里依赖的各种client初始化的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
项目不大就是全局变量然后塞 context 里传递,不然就折腾 wire ,dig 等 DI 工具。
要么统一放到 global/ 下面,要么依赖注入。
普通开发,也不想依赖注入
依赖注入,用框架也可以,自己依赖注入也可以:go<br>func Run(cfg Config) error {<br> db, err := mysql.Open(cfg.Database)<br> if err != nil {<br> return err<br> }<br> defer db.Close()<br> <br> mq, err := kafka.Open(cfg.Kafka)<br> if err != nil {<br> return err<br> }<br> defer mq.Close()<br> <br> rdb, err := redis.Open(cfg.Redis)<br> if err != nil {<br> return err<br> }<br> defer rdb.Close()<br><br> bar := NewBar(db, mq, rdb)<br> <br> return bar.Foo()<br>}<br><br>func NewBar(db *sql.DB, mq *kafka.Client, rdb *redis.Client) *Bar {<br> return &Bar{<br> db: db,<br> mq: mq,<br> rdb: rdb,<br> }<br>}<br><br>type Bar struct {<br> db *sql.DB<br> mq *kafka.Client<br> rdb *redis.Client<br>}<br><br>func (b *Bar) Foo() error {<br> _, err := b.db.Exec("SELECT 1")<br> return err<br>}<br>
只要涉及到 singleton ,di 是最稳妥的办法,选个轻量级的就好
推荐:github.com/samber/do
微服务的话跟着 service 走就行。全局变量不是好范式,也不好 mock 。除非你要做成一个包单独提供服务。
不是直接在项目根目录下做个 /datasource (命名可改)然后放各种 client 的目录就好了吗…
./
— cmd/
— pkg/
— internal/
— …
— datasource
--------- mysql
--------- redis
--------- kafka
然后 internal 里调用 GetMySQL(xxx) 或者 GetRedis(xxx) 就能直接用了
为啥要塞到某个结构体里…
好问题,有兴趣的话可以看看这个
https://github.com/go-kod/kod-mono
DDD 的话跟 1 楼差不多, 项目启动的时候 依赖注入,给你个参考: https://github.com/8treenet/freedom
放在各自的目录下去,比如:
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
在Golang的web项目中,初始化各种client(如HTTP client、数据库client、Redis client等)是一个常见的需求。这些client的初始化通常涉及到配置参数的读取、连接池的创建以及错误处理等多个方面。以下是一些关键步骤和最佳实践:
-
配置管理:首先,将所有client的配置参数(如URL、用户名、密码、连接池大小等)集中管理,通常是通过读取配置文件或环境变量来实现。这有助于在多个环境中(开发、测试、生产)进行灵活配置。
-
单例模式:为了避免资源泄漏和重复创建连接,通常使用单例模式来管理client的实例。这可以通过全局变量、包级变量或依赖注入框架来实现。
-
连接池管理:对于数据库和Redis等需要连接池的client,合理配置连接池的大小和超时时间。这有助于平衡性能和资源使用。
-
错误处理:在初始化client时,要妥善处理可能出现的错误,如网络错误、认证失败等。通常,这些错误会被记录到日志系统中,并可能触发告警。
-
优雅关闭:在web应用关闭时,确保所有client都能被正确关闭,以释放资源和避免连接泄漏。这通常通过实现一个优雅的关闭机制来实现,如监听系统信号并调用client的关闭方法。
总之,在Golang的web项目中,合理初始化和管理client是确保应用性能和稳定性的关键。通过集中配置、单例模式、连接池管理、错误处理和优雅关闭等最佳实践,可以显著提高应用的可靠性和可维护性。