理解连接池

1. 池化技术

池化技术 (Pool) 是一种很常见的编程技巧,
在请求量大时能明显优化应用性能,降低系统频繁建连的资源开销
日常工作中常见的有数据库连接池、线程池、携程池,对象池
它们的特点都是将 “昂贵的”、“费时的” 的资源维护在一个特定的 “池子” 中,
规定其最小连接数、最大连接数、阻塞队列等配置,
方便进行统一管理和复用,
通常还会附带一些探活机制、强制回收、监控一类的配套功能。

2. 数据库连接池

数据库连接池负责分配、管理和释放数据库连接,
它允许应用程序重复使用一个现有的数据库连接,而不是再重新建立一个;
并且释放空闲时间超过最大空闲时间的数据库连接
来避免因为没有释放数据库连接而引起的数据库连接遗漏。这项技术能明显提高数据库操作的性能。

2.1 数据库连接池

数据库连接池技术带来的优势:

  • 资源重用, 减少内存碎片
    由于数据库连接得到重用,避免了频繁创建、释放连接引起的大量性能开销。
    在减少系统消耗的基础上,
    另一方面也增进了系统运行环境的平稳性,减少了内存碎片以及数据库临时进程/线程的数量

  • 因为连接已提前准备好, 所以有更快的服务响应速度
    数据库连接池在初始化过程中,往往已经创建了若干数据库连接置于池中备用。
    此时连接的初始化工作均已完成。
    对于业务请求处理而言,直接利用现有可用连接,
    避免了数据库连接初始化和释放过程的时间开销,从而缩减了系统整体响应时间。

  • 新的资源分配手段,强制收回被占用连接, 从而避免某一应用独占所有数据库资源
    对于多应用共享同一数据库的系统而言,可在应用层通过数据库连接的配置,实现数据库连接池技术。
    通过对应用最大可用数据库连接数的限制,避免某一应用独占所有数据库资源。
    统一的连接管理,避免数据库连接泄漏
    在较为完备的数据库连接池实现中,可根据预先的连接占用超时设定,
    强制收回被占用连接,从而避免了常规数据库连接操作中可能出现的资源泄漏。

2.2 数据库连接池的参数设计

sql.DB 通过以下方法来配置maxOpen, maxIdle 和 maxLifeTime。

SetMaxOpenConns()
SetMaxIdleConns() 
SetConnMaxLifetime()
  • 最大连接数maxOpen
    最大连接数一般是((核心数 * 2) + 有效磁盘数)
  • 最大空闲连接数maxIdle
    默认情况下sql.DB,最多允许2个空闲连接保留在连接池中
  • 当前总连接数
    当前总连接数 = 当前空闲连接数 + 当前工作连接数
  • 连接的最长时间maxLifeTime
    超过这个时间, 连接被清理。

2.3 获取连接,释放连接,清理连接

2.3.1 获取连接:

分两种情况:

  • 工作连接数 < 最大连接数:表示用户有机会获取连接
  • 当前连接数 >= 最大连接数:Connection 的创建达到了上限,用户只能等待重试工作连接数

在有机会获取连接条件下,又分为两种情况:

  • 如果空闲连接池的 size>0,直接从空闲连接池中获取连接
    即空闲连接池中的弹出一个 Connection,把这个Connection 加入到工作连接池。
  • 如果空闲连接池的 size=0,创建一个新的 Connection 给用户
2.3.2 释放连接:

任何一个连接使用完毕之后需要归还给连接池,这也是数据库连接池实现中比较重要的逻辑,
通常还伴随着对连接的可靠性检测,
如果连接异常关闭,那么不应该继续还给连接池,而是应该新建一个连接进行替换。
如果空闲连接池未满,直接添加进去,并把工作连接池中相应的连接移除;
如果空闲连接池满了,直接close()掉,并把工作连接池中相应的连接移除。

2.3.3 清理连接:

一个数据库连接无法保证长期有效,
例如,MySQL 侧会强制 kill 掉长时间空闲的连接(8h)。
在 sql.DB 中提供了 maxLifeTime 选项设置连接被复用的最大时间,
注意这个时间并不是连接空闲时间,
而是从连接建立到这个时间点就会被回收,从而保证连接活性。

3. 最大连接数并不是设置的越大越好的原因

  1. cpu原因:
    单核CPU的计算机也能“同时”运行数百个线程,但这只不过是操作系统用时间分片玩的一个小把戏。
    一颗CPU核心同一时刻只能执行一个线程,然后操作系统切换上下文,核心开始执行另一个线程的代码,
    以此类推。给定一颗CPU核心,其顺序执行A和B永远比通过时间分片“同时”执行A和B要快,
    一旦线程的数量超过了CPU核心的数量,再增加线程数系统就只会更慢,而不是更快。
    所以仅从CPU的角度来考虑,设置线程数等于CPU核数,能提供最优的性能。
  2. 磁盘, 网络原因
    磁盘,网络等因素。在I/O等待时间内,线程是在“阻塞”着等待磁盘,
    此时操作系统可以将那个空闲的CPU核心用于服务其他线程,此时就产生了线程的切换,
    所以,由于线程总是在I/O上阻塞,我们可以让线程/连接数比CPU核心多一些,
    这样能够在同样的时间内完成更多的工作。
    最终合理的连接数:
    最大连接数 = ((核心数 * 2) + 有效磁盘数)
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值