Golang通用连接池高性能连接多种TCP连接、实例rabbitmq、mysql、redis.

完整的代码是

Package Pool

//@ time3360 2020年3月13日12:27:33

//@ author3360 lemy hello

//@Desc:通用连接池

Import(

" Errors "

Fmt '

“同步”

“时间”

)。

Var(

//ErrMaxActiveConnReached连接池溢出

errmaxactiveconnreached=errors . new(' maxactiveconnreached ')

)。

//Config连接池相关配置

Type Config struct {

//连接池中的最小连接数

InitialCap int

//最大并发生存连接数

MaxCap int

//最大空闲连接

MaxIdle int

//如何创建连接

Factoryfunc () (interface {},error)

//断开连接方法

Closefunc(接口{})错误

//如何验证连接是否有效

Ping func(接口{})错误

//连接到期的最长空闲时间

IdleTimeout

}

//保存channelPool连接信息

Type channelPool struct {

Conns chan *idleConn

Factoryfunc () (interface {},error)

Closefunc(接口{})错误

Ping func(接口{})错误

IdleTimeout、waitTimeOut

最大化int

OpeningConns int

}

Type idleConn struct {

Conn interface{}

t

}

Var(

//Errclosed连接池关闭了Error

errclosed=errors . new(' pool is closed ')

)。

//Pool基本方法

Type Pool界面{

Get() (interface{},error)

Put(接口{})错误

Close (interface {})错误

Release()

Len() int

}

//初始化NewChannelPool连接

func newchannelpool(pool config * config)(pool、error) {

If!====0 ){

Return nil,errors . new(' invalid capacity settings ')

}

If==nil {

Return nil,errors . new(' invalid factory func settings ')

}

If==nil {

Return nil,errors . new(' invalid close func settings ')

}

C:=通道池{

Conns: make(chan *idleConn)、

工厂:

Close:

IdleTimeout:

最高活动3360,

OpeningConns:

}

If!=nil {

C.ping=

}

for I :=0;I;I {

Conn,err :=c.factory()

If err!=nil {

C.发行()

Returnnil,(' factory is not able to fill the pool :% s ',err)

}

C.conns-idleconn {conn3360 conn,t: ()}

}

Return c、nil

}

//getConns获取所有连接

Func (c *通道池)getconns () chan * idleconn {

C.mu.Lock()

Conns :=c.conns

C.mu.Unlock()

Return conns

}

从//Get pool导入连接

Func (c *通道池)get()(接口{},错误){

Conns :=c.getConns()

If conns==nil {

Return nil,ErrClosed

}

For {

Select {

案例wrapConn :=-conns:

If wrapConn==nil {

Return nil,ErrClosed

}

//决定是否超时,忽略超时

if time out :=c . idle time out;Timeout 0 {

Ifwra (timeout)。before(){

//删除并关闭连接

C.Close)

Continue

}

}

//决定是否无效,无效,废弃,如果用户未设置ping方法,则不进行确认

If c.ping!=nil {

if err :=c . Ping);Err!=nil {

C.Close)

Continue

}

}

Return wra、nil

Default:

C.mu.Lock()

Defer c.mu.Unlock()

If c.openingConns=c.maxActive {

Return nil,errmaxactiveconnreached

}

If c.factory==nil {

Return nil,ErrClosed

}

Conn,err :=c.factory()

If err!=nil {

Return nil、err

}

C.openingConns

Return conn,nil

}

}

}

//Put连接重新插入pool

Func (c *通道池)put (conninterface {})错误{

If conn==nil {

returner rors . new(' connection is nil . rejecting ')

}

C.mu.Lock()

If c.conns==nil {

C.mu.Unlock()

Return c.Close(conn)

}

Select {

case c . conns-idle conn { conn : conn,t: ()} :

C.mu.Unlock()

Return nil

Default:

C.mu.Unlock()

//连接池已满,直接关闭连接

Return c.Close(conn)

}

}

//Close关闭单个连接

Func (c *通道池)close (conninterface {})错误{

If conn==nil {

returner rors . new(' connection is nil . rejecting ')

}

C.mu.Lock()

Defer c.mu.Unlock()

If c.close==nil {

Return nil

}

C.openingConns -

Return c.close(conn)

}

//Ping检查单个连接是否有效

Func (c *通道池)ping (conn interface {})错误{

If conn==nil {

returner rors . new(' connection is nil . rejecting ')

}

Return c.ping(conn)

}

//Release断开连接池中的所有连接

发行Func (c *通道池)(){

C.mu.Lock()

Conns :=c.conns

C.conns=nil

C.factory=nil

C.ping=nil

CloseFun :=c.close

C.close=nil

C.mu.Unlock()

If conns==nil {

Return

}

关闭(conns)

For wrapConn :=范围连接{

(“类型% v \ n”,re)

CloseFun)

}

}

//Len连接池中已存在的连接

Func (c *通道池)len () int {

Return len()

}调试主函数实例

Package main

//@ time3360 2020年3月13日19:35336035

//@ author3360 lemy hello

//@演示如何使用Desc: Pool连接池获取TCP的各种应用程序实例

Import(

Fmt '

GI;

" Net "

“时间”

Tcp-pool/Pool '

)。

Var(

Mq URL=' AMQP ://ROOT : ROOT @ 127 . 0 . 0 . 1:5672/TEST '/根据实际情况填写MQ配置连接

MqPool Pool。Pool

)。

Func main() {

Rabbitmq()

Mysql()

Redis()

//获取连接

Mq,_ :=mqPool。Get()

//实例化对象

Mqconn:=mq。(* amqp.connection)

//将连接重新插入连接池

Defer mqPool。Put(mq)

//rabbitmq作业开始.

Mqconn。Channel()

//do something.

}

//rabbitmq rabbitmq连接池

Func rabbitmq() {

//如何创建factory连接

factory :=func()(interface { },error) {returnamqp.dial (MQ URL)}

//close断开连接方法

close :=func(v interface { })error { return v .)。close ()}

//创建连接池:初始化2、最大连接数5、空闲连接4

PoolConfig :=Pool。Config{

InitialCap: 2、

MaxIdle: 5、

MaxCap: 4、

factory : factory,

Close: close、

//连接空闲时连接EOF,为防止自动过期问题,连接关闭的最长空闲时间

IdleTimeout: 15 *、

}

Mqpool,_=pool . newchannelpool(pool config)

//从连接池获取连接

//v,err :=p.Get()

//do something

//conn :=v .(* amqp . connection)

//将连接重新插入连接池

(v)

//断开连接池中的所有连接

()

//查看当前连接的数量

当前:=mqpool.len()

(' len=',current)

Return

}

//mysql MySQL连接池

Func mysql() {

}

//redis redis连接池

Func redis() {

}最后,测试连接池是否正常工作

完美。

。。