golang中怎么利用channel 实现一个连接池
发表于:2025-01-24 作者:千家信息网编辑
千家信息网最后更新 2025年01月24日,这篇文章给大家介绍golang中怎么利用channel 实现一个连接池,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。何为通用?连接池的实现不依赖具体的实例,而依赖某个接口,本文的
千家信息网最后更新 2025年01月24日golang中怎么利用channel 实现一个连接池
这篇文章给大家介绍golang中怎么利用channel 实现一个连接池,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。
何为通用?
连接池的实现不依赖具体的实例,而依赖某个接口,本文的连接池选用的是io.Closer
接口,只要是实现了该接口的对象都可以被池管理。
当然,你可以实现基于interface{}
的连接池,这样任何对象都可以被管理。
实现原理
将连接句柄存入channel中,由于缓存channel的特性,获取连接时如果池中有连接,将直接返回,如果池中没有连接,将阻塞或者新建连接(没超过最大限制的情况下)。
由于面向接口编程,所有创建连接的逻辑是不清楚的,这里需要传入一个函数,该函数返回一个io.Closer
对象。
实现
由于并发问题,在需要操作池中互斥数据的时候需要加锁。
package pool
import (
"errors"
"io"
"sync"
"time"
)
var (
ErrInvalidConfig = errors.New("invalid pool config")
ErrPoolClosed = errors.New("pool closed")
)
type factory func() (io.Closer, error)
type Pool interface {
Acquire() (io.Closer, error) // 获取资源
Release(io.Closer) error // 释放资源
Close(io.Closer) error // 关闭资源
Shutdown() error // 关闭池
}
type GenericPool struct {
sync.Mutex
pool chan io.Closer
maxOpen int // 池中最大资源数
numOpen int // 当前池中资源数
minOpen int // 池中最少资源数
closed bool // 池是否已关闭
maxLifetime time.Duration
factory factory // 创建连接的方法
}
func NewGenericPool(minOpen, maxOpen int, maxLifetime time.Duration, factory factory) (*GenericPool, error) {
if maxOpen <= 0 || minOpen > maxOpen {
return nil, ErrInvalidConfig
}
p := &GenericPool{
maxOpen: maxOpen,
minOpen: minOpen,
maxLifetime: maxLifetime,
factory: factory,
pool: make(chan io.Closer, maxOpen),
}
for i := 0; i < minOpen; i++ {
closer, err := factory()
if err != nil {
continue
}
p.numOpen++
p.pool <- closer
}
return p, nil
}
func (p *GenericPool) Acquire() (io.Closer, error) {
if p.closed {
return nil, ErrPoolClosed
}
for {
closer, err := p.getOrCreate()
if err != nil {
return nil, err
}
// todo maxLifttime处理
return closer, nil
}
}
func (p *GenericPool) getOrCreate() (io.Closer, error) {
select {
case closer := <-p.pool:
return closer, nil
default:
}
p.Lock()
if p.numOpen >= p.maxOpen {
closer := <-p.pool
p.Unlock()
return closer, nil
}
// 新建连接
closer, err := p.factory()
if err != nil {
p.Unlock()
return nil, err
}
p.numOpen++
p.Unlock()
return closer, nil
}
// 释放单个资源到连接池
func (p *GenericPool) Release(closer io.Closer) error {
if p.closed {
return ErrPoolClosed
}
p.Lock()
p.pool <- closer
p.Unlock()
return nil
}
// 关闭单个资源
func (p *GenericPool) Close(closer io.Closer) error {
p.Lock()
closer.Close()
p.numOpen--
p.Unlock()
return nil
}
// 关闭连接池,释放所有资源
func (p *GenericPool) Shutdown() error {
if p.closed {
return ErrPoolClosed
}
p.Lock()
close(p.pool)
for closer := range p.pool {
closer.Close()
p.numOpen--
}
p.closed = true
p.Unlock()
return nil
}
关于golang中怎么利用channel 实现一个连接池就分享到这里了,希望以上内容可以对大家有一定的帮助,可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到。
资源
接口
对象
最大
内容
函数
单个
更多
帮助
管理
不错
清楚
兴趣
前池
原理
句柄
实例
小伙
小伙伴
情况
数据库的安全要保护哪些东西
数据库安全各自的含义是什么
生产安全数据库录入
数据库的安全性及管理
数据库安全策略包含哪些
海淀数据库安全审计系统
建立农村房屋安全信息数据库
易用的数据库客户端支持安全管理
连接数据库失败ssl安全错误
数据库的锁怎样保障安全
数据库技术的主要特点包括
数据库 false
玖二柒互联网科技有限公司人事
缺氧数据库我的故事
株洲市网络安全执法案例
计算机网络技术四级证书有用吗
木瓜互联网科技股
吉林正规软件开发供应商
网络安全需要配置什么
安徽web前端软件开发哪里好
odbc数据库管理客户端
合肥励拓网络技术有限公司
根服务器在美国网络安全
海康行为分析服务器协议文档
数据库三元联系是什么原因
因式分解视频软件开发
数据库开发大概费用
粘土我的世界服务器
《软件开发清单》
网络安全设备上架前准备材料
网络安全防护兼职
济宁网络安全等级保护
海泰互联网科技虚拟现实
检察 信息网络安全
网络安全小故事用英语
网络安全教育读后感800字
北京高校校园网络安全建设
部队网络安全保密教育
荣耀手机服务器在哪里找
aws云服务器无法连接