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() {
}最后,测试连接池是否正常工作
完美。
。。