Ai
1 Star 10 Fork 50

go-course/restful-api-demo-g7

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
config.go 4.45 KB
一键复制 编辑 原始数据 按行查看 历史
Mr.Yu 提交于 2022-04-23 18:36 +08:00 . 通过cli start 启动程序
package conf
import (
"context"
"database/sql"
"fmt"
"sync"
"time"
_ "github.com/go-sql-driver/mysql"
)
// 全局config实例对象,
// 也就是我们程序,在内存中的配置对象
// 程序内部获取配置, 都通过读取该对象
// 该Config对象 什么时候被初始化喃?
// 配置加载时:
// LoadConfigFromToml
// LoadConfigFromEnv
// 为了不被程序在运行时恶意修改, 设置成私有变量
var config *Config
// 全局MySQL 客户端实例
var db *sql.DB
// 要想获取配置, 单独提供函数
// 全局Config对象获取函数
func C() *Config {
return config
}
// 初始化一个有默认值的Config对象
func NewDefaultConfig() *Config {
return &Config{
App: NewDefaultApp(),
Log: NewDefaultLog(),
MySQL: NewDefaultMySQL(),
}
}
// Config 应用配置
// 通过封装为一个对象, 来与外部配置进行对接
type Config struct {
App *App `toml:"app"`
Log *Log `toml:"log"`
MySQL *MySQL `toml:"mysql"`
}
func NewDefaultApp() *App {
return &App{
Name: "demo",
Host: "127.0.0.1",
Port: "8050",
}
}
type App struct {
Name string `toml:"name" env:"APP_NAME"`
Host string `toml:"host" env:"APP_HOST"`
Port string `toml:"port" env:"APP_PORT"`
}
func (a *App) HttpAddr() string {
return fmt.Sprintf("%s:%s", a.Host, a.Port)
}
func NewDefaultMySQL() *MySQL {
return &MySQL{
Host: "127.0.0.1",
Port: "3306",
UserName: "demo",
Password: "123456",
Database: "demo",
MaxOpenConn: 200,
MaxIdleConn: 100,
}
}
// MySQL todo
type MySQL struct {
Host string `toml:"host" env:"MYSQL_HOST"`
Port string `toml:"port" env:"MYSQL_PORT"`
UserName string `toml:"username" env:"MYSQL_USERNAME"`
Password string `toml:"password" env:"MYSQL_PASSWORD"`
Database string `toml:"database" env:"MYSQL_DATABASE"`
// 因为使用的MySQL连接池, 需要池做一些规划配置
// 控制当前程序的MySQL打开的连接数
MaxOpenConn int `toml:"max_open_conn" env:"MYSQL_MAX_OPEN_CONN"`
// 控制MySQL复用, 比如5, 最多运行5个来复用
MaxIdleConn int `toml:"max_idle_conn" env:"MYSQL_MAX_IDLE_CONN"`
// 一个连接的生命周期, 这个和MySQL Server配置有关系, 必须小于Server配置
// 一个连接用12h 换一个conn, 保证一定的可用性
MaxLifeTime int `toml:"max_life_time" env:"MYSQL_MAX_LIFE_TIME"`
// Idle 连接 最多允许存活多久
MaxIdleTime int `toml:"max_idle_time" env:"MYSQL_MAX_idle_TIME"`
// 作为私有变量, 用户与控制GetDB
lock sync.Mutex
}
// 1. 第一种方式, 使用LoadGlobal 在加载时 初始化全局db实例
// 2. 第二种方式, 惰性加载, 获取DB是,动态判断再初始化
func (m *MySQL) GetDB() *sql.DB {
// 直接加锁, 锁住临界区
m.lock.Lock()
defer m.lock.Unlock()
// 如果实例不存在, 就初始化一个新的实例
if db == nil {
conn, err := m.getDBConn()
if err != nil {
panic(err)
}
db = conn
}
// 全局变量db就一定存在了
return db
}
// 连接池, driverConn具体的连接对象, 他维护着一个Socket
// pool []*driverConn, 维护pool里面的连接都是可用的, 定期检查我们的conn健康情况
// 某一个driverConn已经失效, driverConn.Reset(), 清空该结构体的数据, Reconn获取一个连接, 让该conn借壳存活
// 避免driverConn结构体的内存申请和释放的一个成本
func (m *MySQL) getDBConn() (*sql.DB, error) {
var err error
dsn := fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?charset=utf8&multiStatements=true", m.UserName, m.Password, m.Host, m.Port, m.Database)
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)
db.SetConnMaxLifetime(time.Second * time.Duration(m.MaxLifeTime))
db.SetConnMaxIdleTime(time.Second * time.Duration(m.MaxIdleTime))
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 NewDefaultLog() *Log {
return &Log{
// debug, info, error, warn
Level: "info",
Format: TextFormat,
To: ToStdout,
}
}
// Log todo
// 用于配置全局Logger对象
type Log struct {
Level string `toml:"level" env:"LOG_LEVEL"`
Format LogFormat `toml:"format" env:"LOG_FORMAT"`
To LogTo `toml:"to" env:"LOG_TO"`
PathDir string `toml:"path_dir" env:"LOG_PATH_DIR"`
}
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
Go
1
https://gitee.com/go-course/restful-api-demo-g7.git
git@gitee.com:go-course/restful-api-demo-g7.git
go-course
restful-api-demo-g7
restful-api-demo-g7
8fd23093c783

搜索帮助