自营连接池工具
发布时间:2020-12-16 09:40:04 所属栏目:大数据 来源:网络整理
导读:刚刚开始写连接池时的一些想法: 1、连接池最重要的是在于空闲、忙碌和峰值时连接的操作逻辑; 2、连接池工具跟mysql、redis、tcp、没有什么特定的关系,只要生产模式是io.Closer接口即可; 3、连接池多数情况下在连接使用释放后会进行Rollback,这里的操作
刚刚开始写连接池时的一些想法: 不多废话上pool.go代码 package core import ( "errors" "time" "sync" "io" "fmt" ) //连接池生产 type PoolFactory func() (io.Closer,error) //连接池管理实例 type Pool struct { mu sync.Mutex MaxIdle int MaxOpen int IsDebug bool Name string busy bool factory PoolFactory stack chan io.Closer } //new MysqlPool func NewPool(factory PoolFactory,maxIdle int,maxOpen int,name string) *Pool { pool := new(Pool) pool.Name = name pool.factory = factory pool.setInit(maxIdle,maxOpen) return pool } //log func (this *Pool)log(value ...interface{}) { if this.IsDebug { fmt.Println("[pool]",this.Name,value) } } //set init func (this *Pool)setInit(maxIdle int,maxOpen int) error { if maxOpen < maxIdle { return errors.New("maxOpen can not less than maxIdle") } this.stack = make(chan io.Closer,maxOpen) go func() { for { busyState := this.busy && len(this.stack) < maxOpen idleState := len(this.stack) < maxIdle if maxIdle <= 0 || busyState || idleState { one,err := this.factory() if err == nil { this.stack <- one } this.log("create one",len(this.stack)) } time.Sleep(time.Microsecond * 10) } }() return nil } //back to pool func (this *Pool)Back(one io.Closer) error { if one != nil { return one.Close() } return errors.New("back instance is nil") } //get instance func (this *Pool)Get() (io.Closer,error) { this.mu.Lock() defer this.mu.Unlock() if this.MaxIdle > 0 && len(this.stack) < this.MaxIdle { this.busy = true } else { this.busy = false } select { case one := <-this.stack: this.log("use one") return one,nil case <-time.After(time.Microsecond * 10): this.busy = true return nil,errors.New("pool timeout") } } 如何使用连接池呢?灰常简单 package main import ( _ "github.com/go-sql-driver/mysql" "io" "core" ) var pool *core.Pool function main(){ pool = core.NewPool(poolMysqlFactory,5,50,"mysql") pool.IsDebug = true //use pool err,conn := pool.Get() //balabala use conn conn.Close() time.Sleep(time.Hour*1) } //mysql pool factory func poolMysqlFactory() (io.Closer,error) { conn,err := gorm.Open("mysql","username:password@tcp(localhost:3306)/test?charset=utf8&parseTime=True&loc=Local") if err != nil { return nil,err } return conn,nil } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |