谈谈从连接池到内存池
作者:媒体转发 时间:2018-02-21 21:00
如果将互联网应用比喻成冲浪的话, 可能需要先学会在“池”中游泳。

引子
AI赋能万物,老码农的伙伴们也曾经开发了一个基于图数据库的知识问答系统,在压力测试的时候发现随着并发数的增加,响应的时延明显变长,看时延分布,是应用程序与图数据库之间的交互时延过长。结构不做调整,优化图数据库后,发现在并发量上来之后,效果仍不明显。
看代码,观察ELK中的日志,发现了问题所在————高并发时连接的创建时间较长。时间所限,替换为httpclient的连接池,post 和 get都采用池中的连接,性能问题迎刃而解。
在编程的世界里,经常会遇到连接池,那连接池到底是什么呢?

什么是池
池,一种资源抽象的形象化说法。编程世界中的池是一组资源, 可以随时使用, 但不随时地创建和释放。
资源池(resource pool)被认为是一种设计模式,这里的资源主要是指系统资源, 这些资源不专属于某个进程或内部资源。客户端向池请求资源, 并使用返回的资源进行指定的操作。当客户端使用完资源后, 会把资源放回池中而不是释放或丢弃掉。
任何技术都有自己的应用边界,池作为一种资源使用技术,典型的使用情形是:
当获取资源的成本较高的时候
当请求资源的频率很高且使用资源总数较低的时候
当面对性能问题,涉及到处理时间延迟的时候
池中的资源主要有两类:需要系统调用(system call) 的系统资源,或主演需要网络通信的远程资源, 如数据库连接、套接字连接、线程和内存分配等等。池中的资源一般不包括像字体库或图片等大的数据对象, 那些资源的存储一般是通过是数据缓存或数据库技术实现的。由于资源池的存在, 从池中获取资源所需的时间变成了可预知的,从而在一定程度上解决性能的问题。
根据资源的类型,资源池一般包括连接池、线程池和内存池。
连接池
连接池是创建和管理一个网络连接资源池的技术,这些连接一般预先准备好被任何需要它们的线程或者进程使用。
网络连接根据连接的生命周期可以粗略的分为两种:长链接和短链接。就web应用而言,短连接就是一般的http请求,长连接如websocket。
短链接适合大部分应用。对于远程方法的执行时间远大于连接创建时间(看网络情况大约为数毫秒)的时候,其连接创建时间可以被忽略,此时短连接策略基本不会有较大性能损失。另外,对于非频繁调用火灾对延迟时间不敏感的服务也适合使用短连接策略。
对于高并发或者高吞吐量的应用,网络连接的创建消耗是很大的,对于这种应用应该使用长连接策略的连接池实现。

连接池中的几个常用参数
在各种连接池的实现中,常用的参数一般有:连接数相关,连接时间相关,有效性相关。
连接数
设计一个连接池,要确定池中的连接数量,包括最小空闲连接数,最大空闲连接数,连接池最大持有连接数。当然连接数可以变化,动态缩放,确定每次增加/减少的连接数量。
连接的有效性
保证连接池中的连接有效性,相当于增加了连接心跳的检测。同时,还有从池中获取客户端接口时的有效性,将客户端接口归还连接池时的有效性,当配置或实现了相关的管理服务,可以通过管理工具观察连接池的使用情况。例如对于Java的应用,如果配置了JMX服务的话,可以通过JMX管理工具观察Java连接池的状态。
连接有效性测试可以减少长连接失效造成的远程调用失败,对于那些对连接失效而造成的调用失败很敏感的服务,可以开启各种合适的连接有效性测试策略来保障所取得的客户端是连接正常的。
时间相关参数
为了保持池中连接的有效性,空闲连接检测时间也就是心跳间隔,这往往取决于业务使用连接池的场景。另外,还有从连接池中获取连接的最大等待时间,一般地默认为-1,即无可用连接会抛出异常,当设为0时表示无穷大。
网络通信连接池
网络通信的连接池主要节省创建TCP连接的时间,从而降低了请求的总处理时间。客户端为每个服务端实例维护一个连接池。如果连接池中有空闲连接,则复用这个连接。如果连接池中没有空闲连接,则会建立一个新的TCP连接或者等待池中出现空闲的连接。




