自營串連池工具

來源:互聯網
上載者:User
這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。

剛剛開始寫串連池時的一些想法:
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}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.