1 Star 0 Fork 0

PengHengBen / devcloud-mini

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
config.go 6.88 KB
一键复制 编辑 原始数据 按行查看 历史
PengHengBen 提交于 2024-02-19 17:19 . 实现跨服务tracer追踪
package conf
import (
"context"
"database/sql"
"encoding/json"
"fmt"
"sync"
"time"
_ "github.com/go-sql-driver/mysql"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
"go.opentelemetry.io/contrib/instrumentation/go.mongodb.org/mongo-driver/mongo/otelmongo"
orm_mysql "gorm.io/driver/mysql"
"gorm.io/gorm"
)
func DefaultConfig() *Config {
return &Config{
App: newDefaultApp(),
MySQL: newDefaulMySQL(),
Http: newDefaultHttp(),
Grpc: NewDefaultGrpc(),
MongoDB: newDefaultMongoDB(),
Jaeger: newJaeger(),
}
}
// 程序的配置对象 config --> object
type Config struct {
App *App `json:"app" toml:"app"`
// [mysql]
MySQL *MySQL `json:"mysql" toml:"mysql"`
// [mongo]
MongoDB *mongodb `json:"mongo" toml:"mongo"`
// [http]
Http *Http `json:"http" toml:"http"`
// [grpc]
Grpc *Grpc `json:"grpc" toml:"grpc"`
// 程序接入Jaeger配置
Jaeger *jaeger `json:"jaeger" toml:"jaeger"`
}
func newDefaultApp() *App {
return &App{
Name: "mcenter",
}
}
type App struct {
Name string `json:"name" toml:"name"`
}
// 格式化成一个json
func (c *Config) String() string {
d, _ := json.MarshalIndent(c, "", " ")
return string(d)
}
type MySQL struct {
Host string `json:"host" toml:"host" env:"MYSQL_HOST"`
Port int `json:"port" toml:"port" env:"MYSQL_PORT"`
DB string `json:"db" toml:"db" env:"MYSQL_DB"`
Username string `json:"username" toml:"username" env:"MYSQL_USERNAME"`
Password string `json:"password" toml:"password" env:"MYSQL_PASSWORD"`
// 高级参数
MaxOpenConn int `toml:"max_open_conn" env:"MYSQL_MAX_OPEN_CONN"`
MaxIdleConn int `toml:"max_idle_conn" env:"MYSQL_MAX_IDLE_CONN"`
MaxLifeTime int `toml:"max_life_time" env:"MYSQL_MAX_LIFE_TIME"`
MaxIdleTime int `toml:"max_idle_time" env:"MYSQL_MAX_IDLE_TIME"`
// 面临并发安全
lock sync.Mutex
db *gorm.DB
}
func (m *MySQL) Close() error {
if m.db == nil {
return nil
}
// 没有提供Close方法
// 没法实现数据库的优雅关闭
return nil
}
func (m *MySQL) GetConnPool() (*sql.DB, error) {
var err error
dsn := fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?charset=utf8mb4&multiStatements=true",
m.Username, m.Password, m.Host, m.Port, m.DB)
db, err := sql.Open("mysql", dsn)
if err != nil {
return nil, fmt.Errorf("connect to mysql<%s> error, %s", dsn, err.Error())
}
// 对连接池进行设置
db.SetMaxOpenConns(m.MaxOpenConn)
db.SetMaxIdleConns(m.MaxIdleConn)
if m.MaxLifeTime != 0 {
db.SetConnMaxLifetime(time.Second * time.Duration(m.MaxLifeTime))
}
if m.MaxIdleConn != 0 {
db.SetConnMaxIdleTime(time.Second * time.Duration(m.MaxIdleTime))
}
// 加了一个Ping
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
if err := db.PingContext(ctx); err != nil {
return nil, fmt.Errorf("ping mysql<%s> error, %s", dsn, err.Error())
}
return db, nil
}
func (m *MySQL) ORM() *gorm.DB {
m.lock.Lock()
defer m.lock.Unlock()
if m.db == nil {
// 初始化DB
// 1.1 获取sql.DB
p, err := m.GetConnPool()
if err != nil {
panic(err)
}
// 1.2 使用pool 初始化orm db对象
m.db, err = gorm.Open(orm_mysql.New(orm_mysql.Config{
Conn: p,
}), &gorm.Config{
// 执行任何 SQL 时都创建并缓存预编译语句,可以提高后续的调用速度
PrepareStmt: true,
// 对于写操作(创建、更新、删除),为了确保数据的完整性,GORM 会将它们封装在事务内运行。
// 但这会降低性能,如果没有这方面的要求,您可以在初始化时禁用它,这将获得大约 30%+ 性能提升
SkipDefaultTransaction: true,
// 要有效地插入大量记录,请将一个 slice 传递给 Create 方法
// CreateBatchSize: 200,
})
if err != nil {
panic(err)
}
}
return m.db
}
func newDefaulMySQL() *MySQL {
return &MySQL{
Host: "127.0.0.1",
Port: 3306,
DB: "mcenter",
Username: "root",
Password: "1",
}
}
func newDefaultHttp() *Http {
return &Http{
Host: "192.168.204.142",
Port: 8010,
}
}
type Http struct {
Host string `json:"host" toml:"host" env:"HTTP_HOST"`
Port int `json:"port" toml:"port" env:"HTTP_PORT"`
}
func (h *Http) Address() string {
return fmt.Sprintf("%s:%d", h.Host, h.Port)
}
func NewDefaultGrpc() *Grpc {
return &Grpc{
Host: "127.0.0.1",
Port: 18010,
}
}
type Grpc struct {
Host string `json:"host" toml:"host" env:"MCENTER_GRPC_HOST"`
Port int `json:"port" toml:"port" env:"MCENTER_GRPC_PORT"`
}
func (h *Grpc) Address() string {
return fmt.Sprintf("%s:%d", h.Host, h.Port)
}
func newDefaultMongoDB() *mongodb {
m := &mongodb{
UserName: "mcenter",
Password: "123456",
Database: "mcenter_mini",
AuthDB: "",
Endpoints: []string{"192.168.204.11:27017"},
}
return m
}
type mongodb struct {
Endpoints []string `toml:"endpoints" env:"MONGO_ENDPOINTS" envSeparator:","`
UserName string `toml:"username" env:"MONGO_USERNAME"`
Password string `toml:"password" env:"MONGO_PASSWORD"`
Database string `toml:"database" env:"MONGO_DATABASE"`
AuthDB string `toml:"auth_db" env:"MONGO_AUTH_DB"`
client *mongo.Client
lock sync.Mutex
}
func (m *mongodb) GetAuthDB() string {
if m.AuthDB != "" {
return m.AuthDB
}
return m.Database
}
func (m *mongodb) GetDB() (*mongo.Database, error) {
conn, err := m.Client()
if err != nil {
return nil, err
}
return conn.Database(m.Database), nil
}
// 关闭数据库连接
func (m *mongodb) Close(ctx context.Context) error {
if m.client == nil {
return nil
}
return m.client.Disconnect(ctx)
}
// Client 获取一个全局的mongodb客户端连接
func (m *mongodb) Client() (*mongo.Client, error) {
// 加载全局数据量单例
m.lock.Lock()
defer m.lock.Unlock()
if m.client == nil {
conn, err := m.getClient()
if err != nil {
return nil, err
}
m.client = conn
}
return m.client, nil
}
func (m *mongodb) getClient() (*mongo.Client, error) {
opts := options.Client()
if m.UserName != "" && m.Password != "" {
cred := options.Credential{
AuthSource: m.GetAuthDB(),
}
cred.Username = m.UserName
cred.Password = m.Password
cred.PasswordSet = true
opts.SetAuth(cred)
}
opts.SetHosts(m.Endpoints)
opts.SetConnectTimeout(5 * time.Second)
// 添加MongoDB的trace
opts.Monitor = otelmongo.NewMonitor(
otelmongo.WithCommandAttributeDisabled(true),
)
ctx, cancel := context.WithTimeout(context.Background(), time.Duration(time.Second*5))
defer cancel()
// Connect to MongoDB
client, err := mongo.Connect(ctx, opts)
if err != nil {
return nil, fmt.Errorf("new mongodb client error, %s", err)
}
if err = client.Ping(ctx, nil); err != nil {
return nil, fmt.Errorf("ping mongodb server(%s) error, %s", m.Endpoints, err)
}
return client, nil
}
func newJaeger() *jaeger {
// 使用自定义值
return &jaeger{
Endpoint: "http://192.168.204.11:14268/api/traces",
}
}
type jaeger struct {
Endpoint string `toml:"endpoint" json:"endpoint" yaml:"endpoint" env:"JAEGER_ENDPOINT"`
}
Go
1
https://gitee.com/penghengben/devcloud-mini.git
git@gitee.com:penghengben/devcloud-mini.git
penghengben
devcloud-mini
devcloud-mini
52595909206d

搜索帮助