线程池、连接池、对象池从0到1
做互联网研发,最早接触使用jdbc技术,为了数据库连接能够复用,会用到c3p0、dbcp等数据库连接池。应该是研
发人员最早接触的数据库连接池,再到httpclient http连接池,再到微服务netty连接池,redis客户端连接池,以及jdk中线
程池技术。
这么多数据库、http、netty连接池,jdk线程池,本质上都是连接池技术,连接池技术核心是连接或者说创建的资源复
用。
连接池技术核心:通过减少对于连接创建、关闭来提升性能。用于用户后续使用,好处是后续使用不用在创建连接以
及线程,因为这些都需要相关很多文件、连接资源、操作系统内核资源支持来完成构建,会消耗大量资源,并且创建、关
闭会消耗应用程序大量性能。
网络连接本身会消耗大量内核资源,在linux系统下,网络连接创建本身tcp/ip协议栈在内核里面,连接创建关闭会消耗
大量文件句柄(linux中万物皆文件,一种厉害抽象手段)系统资源。当下更多是应用tcp技术完成网络传输,反复打开关闭
,需要操作系统维护大量tcp协议栈状态。
连接池本质上是构建一个容器,容器来存储创建好的线程、http连接、数据库连接、netty连接等。对于使用方相当于黑
盒,按照接口进行使用就可以了。各个连接池构建、使用管理详细过程大概分成以下三部分。
第一部分:首先初始化连接池,根据设置相应参数,连接池大小、核心线程数、核心连接数等参数,初始化创建数据库、
http、netty连接以及jdk线程。
第二部分:连接池使用,前边初始化好的连接池、线程池,直接从连接池、线程中取出资源即可进行使用,使用完后要
记得交还连接池、线程池,通过池容器来对资源进行管理。
第三部分:对于连接池维护,连接池、线程池来维护连接、线程状态,不可用连接、线程进行销毁,正在使用连接、线
程进行状态标注,连接、线程不够后并且少于设置最大连接、线程数,要进行新连接、线程创建。
通过上边可以了解到各种连接池技术以及线程池原理或者说套路,理解原理才能不被纷繁复杂表象掩盖。
下面谈谈构建自己连接池,其实理解了连接池、线程原理,可以使用ArrayList来构建自己连接池、线程池。初始化时创建
配置连接数、线程,存储在ArrayList容器中,使用时从ArrayList从取出连接、线程进行使用,执行完任务后,提交回ArrayList
容器。前提条件是单线程,在多线程状态下要用线程安全容器。
前边根据原理介绍了一个简单连接池、线程池怎样构建,实际工业级别线程池还要考虑到连接状态,短连接重连,线程池
维护管理高效,线程池稳定等多个因素。
需要用到连接池而又没有相关开源产品可用时,java连接池可以使用common-pool2来构建,比如google开源gRPC技术,
本身是高性能跨平台技术,但目前作为微服务使用,没有连接池、负载均衡等相应配套,这时可以根据需要自己基于Java容器
构建自己连接池。也可以利用common-pool2构建连接池来提升应用性能,以及保持高可用。common-pool2本身不仅仅可以构
建连接池使用,还可以用来构建对象池。
连接池还有一个副作用就是实现了高可用,在微服务场景下一个连接不可用,那么再从netty连接池中取出一个进行使用,
避免了连接不可用问题。
掌握原理从比较全面掌握各种池技术,避免数据库连接池,再到httpclient http连接池,再到微服务netty连接池,redis客户端
连接池,以及jdk中线程池,对象池各种各样池技术,使我们眼花缭乱,花费过多时间,掌握原理机制以不变应万变。
推广一下这个方法,其他技术也是类似,深入掌握其原理,就可以明白其他类似技术相似原理,避免疲于应对各种新技术。但
每一种架构设计与实现又与领域有着关系,也不可讲原理不顾实际情况扩展。理论与架构设计、源码学习相结合才是最好的,希望
有帮助。
扫码关注公众号