diff --git a/deploy.sh b/deploy.sh index dd119f2..49ca6a4 100644 --- a/deploy.sh +++ b/deploy.sh @@ -23,7 +23,7 @@ docker container prune -f docker run -itd --name "voucher" --restart=always \ -p 13000:13000 \ -v /var/www/cert:/app/cert \ - registry.cn-chengdu.aliyuncs.com/lsxdjr/voucher-pre:1db45238 \ + registry.cn-chengdu.aliyuncs.com/lsxdjr/voucher-pre:50bb64d6 \ ./server -nacosIp "172.16.0.239" -nacosPort 8848 -nacosSpace "pre" -nacosUsername "nacos" -nacosPassword "nacos" diff --git a/internal/data/gorm.go b/internal/data/gorm.go index 9fab3bd..5fc5899 100644 --- a/internal/data/gorm.go +++ b/internal/data/gorm.go @@ -23,12 +23,12 @@ func NewGormDb(c *conf.Bootstrap) (*GormDb, func()) { } func db(data *conf.Data_Database) (*gorm.DB, func()) { - //mysqlConn, err := sql.Open(data.Driver, data.Source) gormDB, err := gorm.Open( mysql.Open(data.Source), &gorm.Config{ - Logger: logger.Default.LogMode(logger.Info), + Logger: logger.Default.LogMode(logger.Info), + SkipDefaultTransaction: false, }, ) @@ -41,12 +41,8 @@ func db(data *conf.Data_Database) (*gorm.DB, func()) { panic("failed to gormDB " + err.Error()) } - //sqlDB.SetMaxIdleConns(int(data.MaxIdle)) sqlDB.SetMaxIdleConns(1000) - //sqlDB.SetMaxOpenConns(int(data.MaxOpen)) sqlDB.SetMaxOpenConns(1000) - //sqlDB.SetConnMaxLifetime(1 * time.Hour) - //sqlDB.SetConnMaxIdleTime(15 * time.Minute) return gormDB, func() { @@ -56,3 +52,38 @@ func db(data *conf.Data_Database) (*gorm.DB, func()) { } } + +//func db(data *conf.Data_Database) (*gorm.DB, func()) { +// //mysqlConn, err := sql.Open(data.Driver, data.Source) +// +// gormDB, err := gorm.Open( +// mysql.Open(data.Source), +// //&gorm.Config{ +// // Logger: logger.Default.LogMode(logger.Info), +// //}, +// ) +// +// if err != nil { +// panic("failed to connect database " + err.Error()) +// } +// +// sqlDB, err := gormDB.DB() +// if err != nil { +// panic("failed to gormDB " + err.Error()) +// } +// +// //sqlDB.SetMaxIdleConns(int(data.MaxIdle)) +// sqlDB.SetMaxIdleConns(1000) +// //sqlDB.SetMaxOpenConns(int(data.MaxOpen)) +// sqlDB.SetMaxOpenConns(1000) +// //sqlDB.SetConnMaxLifetime(1 * time.Hour) +// //sqlDB.SetConnMaxIdleTime(15 * time.Minute) +// +// return gormDB, func() { +// +// if gormDB != nil { +// fmt.Println("关闭 db") +// } +// +// } +//} diff --git a/internal/data/gorm_test.go b/internal/data/gorm_test.go index 589ae07..6ee6239 100644 --- a/internal/data/gorm_test.go +++ b/internal/data/gorm_test.go @@ -5,7 +5,9 @@ import ( "errors" "fmt" "google.golang.org/protobuf/types/known/durationpb" + "gorm.io/driver/mysql" "gorm.io/gorm" + "gorm.io/gorm/logger" "gorm.io/hints" "sync" "testing" @@ -15,30 +17,32 @@ import ( "voucher/internal/data/model" ) -func Test_gorm_db(t *testing.T) { - // 镜像mysql - data := &conf.Data_Database{ - Driver: "mysql", - Source: "root:lsxddb123.@tcp(47.108.53.72:3306)/voucher?parseTime=True&loc=Local", - MaxIdle: 20, // 空闲连接池 - MaxOpen: 200, // 最大连接数 - MaxLifetime: durationpb.New(60), // 5分钟 - IsDebug: false, +var source = "voucher:Lsxd@2024@tcp(voucher.rwlb.cn-chengdu.rds.aliyuncs.com:3306)/voucher?parseTime=True&loc=Local" + +func Test_gorm_db_create(t *testing.T) { + + gormDB, err := gorm.Open( + mysql.Open(source), + &gorm.Config{ + Logger: logger.Default.LogMode(logger.Info), + SkipDefaultTransaction: false, + }, + ) + if err != nil { + t.Fatal("failed to connect database " + err.Error()) } - //data := &conf.Data_Database{ - // Driver: "mysql", - // Source: "root:lansexiongdi6,@tcp(47.97.27.195:3306)/voucher?parseTime=True&loc=Local", - // MaxIdle: 2, // 空闲连接池 - // MaxOpen: 10, // 最大连接数 - // MaxLifetime: durationpb.New(60), - // IsDebug: false, - //} - gormDb, cleanup := db(data) - defer cleanup() + + sqlDB, err := gormDB.DB() + if err != nil { + t.Fatal("failed to gormDB " + err.Error()) + } + + sqlDB.SetMaxIdleConns(1000) + sqlDB.SetMaxOpenConns(1000) start2 := time.Now() - concurrency := 2 // 调整并发数 + concurrency := 1000 // 调整并发数 errCount := 0 var wg sync.WaitGroup @@ -48,14 +52,97 @@ func Test_gorm_db(t *testing.T) { go func(i int) { defer wg.Done() - ctx := context.Background() + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + defer cancel() + + now := time.Now() + + info := &model.Order{ + OrderNo: fmt.Sprintf("test_create_1_%d", i), + OutBizNo: fmt.Sprintf("174252390990605ngywYrSAGE83e2_%d", i), + ProductNo: "001", + BatchNo: "001", + Account: "oO3vO5K2nE131-9uMoeYymLhlbYk", + AccountType: 1, + Status: 2, + Type: 1, + AppID: "", + MerchantNo: "wx9ed74283ad25bca1", + Channel: 1, + NotifyUrl: "https://sandbox.cdcc.cmbchina.com/AccessGateway/transIn/updateCodeStatus.json", + Attach: "{}", + CreateTime: &now, + UpdateTime: &now, + } + + if info.ProductNo == "001" { + info.VoucherNo = info.OrderNo + info.Status = vo.OrderStatusSuccess.GetValue() + } + + tx := gormDB.WithContext(ctx).Model(model.Order{}).Create(info) + if tx.Error != nil { + fmt.Printf("写入错误: %v\n", tx.Error) + errCount += 1 + } + }(i) + } + + wg.Wait() + t.Logf("\n--------------连接请求,总请求耗时: %v,总数: %d, 失败次数: %d--------------\n", time.Since(start2), concurrency, errCount) +} + +func Test_gorm_db(t *testing.T) { + // 镜像mysql + //data := &conf.Data_Database{ + // Driver: "mysql", + // Source: "root:lsxddb123.@tcp(47.108.53.72:3306)/voucher?parseTime=True&loc=Local", + // MaxIdle: 20, // 空闲连接池 + // MaxOpen: 200, // 最大连接数 + // MaxLifetime: durationpb.New(60), // 5分钟 + // IsDebug: false, + //} + //data := &conf.Data_Database{ + // Driver: "mysql", + // Source: "root:lansexiongdi6,@tcp(47.97.27.195:3306)/voucher?parseTime=True&loc=Local", + // MaxIdle: 2, // 空闲连接池 + // MaxOpen: 10, // 最大连接数 + // MaxLifetime: durationpb.New(60), + // IsDebug: false, + //} + + data := &conf.Data_Database{ + Driver: "mysql", + Source: "voucher:Lsxd@2024@tcp(voucher.rwlb.cn-chengdu.rds.aliyuncs.com:3306)/voucher?parseTime=True&loc=Local", + MaxIdle: 20, // 空闲连接池 + MaxOpen: 200, // 最大连接数 + MaxLifetime: durationpb.New(60), // 5分钟 + IsDebug: false, + } + gormDb, cleanup := db(data) + defer cleanup() + + start2 := time.Now() + + concurrency := 10000 // 调整并发数 + errCount := 0 + + var wg sync.WaitGroup + wg.Add(concurrency) + + for i := 0; i < concurrency; i++ { + go func(i int) { + defer wg.Done() + + //ctx := context.Background() var info model.Order tx := gormDb. - WithContext(ctx). + //WithContext(ctx). Model(model.Order{}). //Clauses(hints.UseIndex("udx_out_biz_no_type")). Where(model.Order{Type: vo.OrderTypeCmb.GetValue(), OutBizNo: fmt.Sprintf("174252390990605ngywYrSAGE83e1%d", i)}). First(&info) + if tx.Error != nil { if errors.Is(tx.Error, gorm.ErrRecordNotFound) { t.Errorf("未找到记录") @@ -64,6 +151,7 @@ func Test_gorm_db(t *testing.T) { errCount += 1 } } + time.Sleep(1 * time.Microsecond) }(i) } diff --git a/internal/data/repoimpl/order.go b/internal/data/repoimpl/order.go index 8593e27..d594f92 100644 --- a/internal/data/repoimpl/order.go +++ b/internal/data/repoimpl/order.go @@ -19,16 +19,16 @@ import ( // OrderRepoImpl . type OrderRepoImpl struct { Base[model.Order, bo.OrderBo] - db *data.Db + db *data.GormDb } // NewOrderRepoImpl . -func NewOrderRepoImpl(db *data.Db) repo.OrderRepo { +func NewOrderRepoImpl(db *data.GormDb) repo.OrderRepo { return &OrderRepoImpl{db: db} } func (p *OrderRepoImpl) DB(ctx context.Context) *gorm.DB { - return p.db.DB(ctx).Model(model.Order{}) + return p.db.Client.WithContext(ctx).Model(model.Order{}) } func (p *OrderRepoImpl) FindInBatches(ctx context.Context, w *bo.FindInBatchesUseBo, fun func(ctx context.Context, rows []*bo.OrderBo) error) error { @@ -81,9 +81,12 @@ func (p *OrderRepoImpl) Create(ctx context.Context, req *bo.OrderBo) (*bo.OrderB info.Status = vo.OrderStatusSuccess.GetValue() } - tx := p.DB(ctx).Create(info) + db := p.DB(ctx) + tx := db.Create(info) if tx.Error != nil { + sqlDB, _ := db.DB() + log.Warnf("order create 当前打开连接数:%d,空闲连接数:%d", sqlDB.Stats().OpenConnections, sqlDB.Stats().Idle) return nil, fmt.Errorf("create db fail %w", tx.Error) }