Featured image of post 业务开发问题 代码篇(连接池)

业务开发问题 代码篇(连接池)

连接池一般对外提供获得连接、归还连接的接口给客户端使 用,并暴露最小空闲连接数、最大连接数等可配置参数,在内部则实现连接建立、连接心跳 保持、连接管理、空闲连接回收、连接可用性检测等功能。如下图示

连接池

我们先看一下涉及 TCP 连接的客户端 SDK,对外提供 API 的三种方式。在面对各种三方客 户端的时候,只有先识别出其属于哪一种,才能理清楚使用方式。

  1. 连接池和连接分离的 API:有一个 XXXPool 类负责连接池实现,先从其获得连接 XXXConnection,然后用获得的连接进行服务端请求,完成后使用者需要归还连接。通 常,XXXPool 是线程安全的,可以并发获取和归还连接,而 XXXConnection 是非线程 安全的。对应到连接池的结构示意图中,XXXPool 就是右边连接池那个框,左边的客户 端是我们自己的代码。
  2. 内部带有连接池的 API:对外提供一个 XXXClient 类,通过这个类可以直接进行服务端 请求;这个类内部维护了连接池,SDK 使用者无需考虑连接的获取和归还问题。一般而 言,XXXClient 是线程安全的。对应到连接池的结构示意图中,整个 API 就是蓝色框包 裹的部分。
  3. 非连接池的 API:一般命名为 XXXConnection,以区分其是基于连接池还是单连接的, 而不建议命名为 XXXClient 或直接是 XXX。直接连接方式的 API 基于单一连接,每次使 用都需要创建和断开连接,性能一般,且通常不是线程安全的。对应到连接池的结构示 意图中,这种形式相当于没有右边连接池那个框,客户端直接连接服务端创建连接。

创建连接池的时候很可能一次性创建了多个连接,大多数连接池考虑到性能,会在初始 化的时候维护一定数量的最小连接(毕竟初始化连接池的过程一般是一次性的),可以 直接使用。如果每次使用连接池都按需创建连接池,那么很可能你只用到一个连接,但 是创建了 N 个连接。 连接池一般会有一些管理模块,也就是连接池的结构示意图中的绿色部分。举个例子, 大多数的连接池都有闲置超时的概念。连接池会检测连接的闲置时间,定期回收闲置的 连接,把活跃连接数降到最低(闲置)连接的配置值,减轻服务端的压力。一般情况 下,闲置连接由独立线程管理,启动了空闲检测的连接池相当于还会启动一个线程。此 外,有些连接池还需要独立线程负责连接保活等功能。因此,启动一个连接池相当于启 动了 N 个线程。

连接池的配置不是一成不变的 为方便根据容量规划设置连接处的属性,连接池提供了许多参数,包括最小(闲置)连接、 最大连接、闲置连接生存时间、连接生存时间等。其中,最重要的参数是最大连接数,它决 定了连接池能使用的连接数量上限,达到上限后,新来的请求需要等待其他请求释放连接。 但,最大连接数不是设置得越大越好。如果设置得太大,不仅仅是客户端需要耗费过多的资 源维护连接,更重要的是由于服务端对应的是多个客户端,每一个客户端都保持大量的连接,会给服务端带来更大的压力。这个压力又不仅仅是内存压力,可以想一下如果服务端的 网络模型是一个 TCP 连接一个线程,那么几千个连接意味着几千个线程,如此多的线程会 造成大量的线程切换开销。当然,连接池最大连接数设置得太小,很可能会因为获取连接的等待时间太长,导致吞吐量 低下,甚至超时无法获取连接。

使用 Hugo 构建
主题 StackJimmy 设计

发布了 16 篇文章 | 共 31507 字