自营连接池工具

自营连接池工具,第1张

概述刚刚开始写连接池时的一些想法: 1、连接池最重要的是在于空闲、忙碌和峰值时连接的 *** 作逻辑; 2、连接池工具跟mysql、redis、tcp、没有什么特定的关系,只要生产模式是io.Closer接口即可; 3、连接池多数情况下在连接使用释放后会进行Rollback,这里的 *** 作是直接进行Close *** 作(多数 *** 作是直接进行连接回池复用),但是我这儿考虑到可能服务连接受网络波动,所以干脆进行Close?

刚刚开始写连接池时的一些想法:
1、连接池最重要的是在于空闲、忙碌和峰值时连接的 *** 作逻辑;
2、连接池工具跟MysqL、redis、tcp、没有什么特定的关系,只要生产模式是io.Closer接口即可;
3、连接池多数情况下在连接使用释放后会进行Rollback,这里的 *** 作是直接进行Close *** 作(多数 *** 作是直接进行连接回池复用),但是我这儿考虑到可能服务连接受网络波动,所以干脆进行Close?
4、有一个单独的协程不断的在监控连接池中的chan io.Closer不断进行连接补充、状态变化(如空闲、忙碌切换)

不多废话上pool.go代码

package coreimport (    "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 MysqLPoolfunc 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}//logfunc (this *Pool)log(value ...interface{}) {    if this.IsDeBUG {        fmt.Println("[pool]",this.name,value)    }}//set initfunc (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 poolfunc (this *Pool)Back(one io.Closer) error {    if one != nil {        return one.Close()    }    return errors.New("back instance is nil")}//get instancefunc (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")    }}

如何使用连接池呢?灰常简单
这里使用了gorm来创建MysqL连接的方式进行facotry pool工厂创建

package mainimport (    _ "github.com/go-sql-driver/MysqL"    "io"    "core")var pool *core.Poolfunction 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 factoryfunc 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}
总结

以上是内存溢出为你收集整理的自营连接池工具全部内容,希望文章能够帮你解决自营连接池工具所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/langs/1272633.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-08
下一篇 2022-06-08

发表评论

登录后才能评论

评论列表(0条)

保存