如果把互联网应用比作冲浪,你可能需要先学会在“池子”里游泳。入门级人工智能赋能万物。老码农的小伙伴们也开发了基于图数据库的知识问答系统。压测时发现,随着并发数的增加,响应延时明显变长。查看延迟分布,应用与图数据库的交互延迟过长。结构没有调整。对图数据库进行优化后,发现并发量增加后效果依然不明显。看代码,观察ELK中的日志,发现了问题——并发高的时候连接的创建时间比较长。由于时间关系,换成httpclient的连接池。post和get都使用pool中的connection,性能问题就迎刃而解了。在编程的世界里,我们经常会遇到连接池,那么连接池到底是什么?什么是池,资源抽象的可视化表示。编程世界中的池是一组可以随时使用,但不能随时创建和释放的资源。资源池(resourcepool)被认为是一种设计模式。这里的资源主要是指系统资源,并不是某个进程或内部资源独有的。客户端从池中请求资源,并使用返回的资源执行指定的操作。当客户端结束使用资源时,它将资源放回池中而不是释放或丢弃它。任何技术都有自己的应用边界。作为一种资源使用技术,典型的使用场景是:当获取资源的成本高时当请求资源的频率高而资源使用总量低时当面临性能问题时,当涉及到处理时间延迟时,池中主要有两类资源:需要系统调用(systemcalls)的系统资源,或者需要网络通信的远程资源,比如数据库连接,socket连接,线程,以及内存分配等等。池中的资源一般不包括字库、图片等大数据对象,这些资源的存储一般采用数据缓存或数据库技术实现。由于资源池的存在,从池中获取资源所需的时间变得可预测,从而在一定程度上解决了性能问题。根据资源的类型,资源池一般包括连接池、线程池和内存池。连接池连接池是一种用于创建和管理网络连接资源池的技术,这些资源池通常已准备好供需要它们的任何线程或进程使用。网络连接按照连接的生命周期大致可以分为两种:长链接和短链接。对于web应用来说,短连接就是一般的http请求,长连接就像websockets。短链接适用于大多数应用程序。当远程方法的执行时间远大于连接创建时间(根据网络情况大约几毫秒),连接创建时间可以忽略不计。这时候短连接策略基本不会有很大的性能损失。此外,短连接策略也适用于对不频繁调用的延迟时间不敏感的业务。对于高并发或者高吞吐量的应用,网络连接的创建消耗很大。对于这样的应用程序,应该使用具有长期连接策略的连接池。连接池中的几个常用参数在各种连接池的实现中,常用的参数一般与连接数有关,与连接时间有关,与有效性有关。连接数设计一个连接池,需要确定池中的连接数,包括最小空闲连接数、最大空闲连接数、连接池持有的最大连接数。当然,连接数是可以改变的,动态缩放,每次增加/减少的连接数是确定的。连接的有效性保证了连接池中连接的有效性,相当于增加了连接心跳的检测。同时,还有从池中获取客户端接口的有效性和将客户端接口归还给连接池的有效性。在配置或实现相关管理服务时,可以通过管理工具观察连接池的使用情况。例如,对于Java应用,如果配置了JMX服务,则可以通过JMX管理工具来观察Java连接池的状态。连接有效性测试可以减少长连接失败导致的远程调用失败。对于那些对连接失败导致的调用失败敏感的服务,可以启用各种合适的连接有效性测试策略,以确保获取的客户端是连接的。普通的。时间相关参数为了保持池中连接的有效性,空闲连接检测时间也就是心跳间隔,这往往取决于业务使用连接池的场景。另外还有从连接池中获取连接的最大等待时间,一般默认为-1,即没有可用连接时会抛出异常,设置为0时表示无穷。网络通信连接池网络通信的连接池主要是节省创建TCP连接的时间,从而减少请求的总处理时间。客户端为每个服务器实例维护一个连接池。如果连接池中有空闲连接,则重用这个连接。如果连接池中没有空闲连接,则建立新的TCP连接或者池中出现空闲连接。当客户端使用池中的连接处理请求时,如果连接池中的空闲连接数小于连接池的大小,则将当前使用的连接放入连接池中。如果连接池中的空闲连接数大于等于连接池的大小,则关闭当前使用的连接。http短连接的连接池只有在服务器支持keepalive的情况下才有效。如果服务端关闭keepalive,效果相当于短连接,没有连接池功能。同样,如果连接池的大小设置为0,也相当于短连接方式。当服务器支持Keepalive时,它??可以减少CPU和内存使用,允许请求和响应的HTTP流水线操作,减少后续请求的延迟,并在不关闭TCP连接的情况下报告错误。一般对于延迟敏感的业务,可以使用连接池机制。开头的数据库连接池例子就是一个数据库连接池。数据库连接池也可以理解为维护数据库连接的缓存,以便在需要对数据库的请求时可以重用连接。为每个用户打开和维护一个数据库连接会消耗大量资源,而数据库连接池用于提高在数据库中执行命令的性能,减少用户等待的时间。在数据库连接池中,连接创建后就放入连接池中,再次使用时无需重新建立新连接。如果使用了所有连接,则会创建新连接并将其添加到池中。基于Web的应用程序和企业应用程序通常都使用应用程序服务器来处理连接池。当页面需要访问数据库时,它只是简单地使用池中现有的连接,只有在池中没有空闲连接时才建立新连接。这减少了连接数据库以响应单个请求的开销,需要频繁访问数据库的本地应用程序也可以从数据库连接池中受益。有些库不仅实现了数据库连接池,还实现了相关的SQL查询池,简化了数据库操作密集型应用中连接池的实现。Java中常用的数据库连接池有:DBCP、C3P0、BoneCP、Proxool、DBPool、XAPool、Primrose、SmartPool、MiniConnectionPoolManager、Druid。通过配置连接池,限制最小连接数、最大连接数和空闲连接数,可以优化数据库连接池在特定场景和环境下的性能。由于互联网速度不可控,尤其是广域网,尤其是移动互联网(基于3G/4G)速度的不确定性,端上的应用也将连接池作为重要的技术手段。以Chrome浏览器为例,它的网络库使用连接池来管理连接的建立、分配和释放。当请求可以直接从连接池中获取多路复用连接时,可以减少建立连接的时间消耗。除了websocket连接池之外,还有三种连接池:TransportClientSocketPoolSSLClientSocketPoolSOCKSClientSocketPool其中,TransportClientSocketPool是低层连接池,SSLClientSocketPool和SOCKSClientSocketPool是高层连接池,高层连接池包含了低级连接池或其他高级连接池的对象。连接池类可以组合各种连接池对象。打开chrome://net-internals/#sockets可以看到浏览器当前的连接状态。在应用程序中,连接池也被广泛使用,主流的网络通信库都支持连接池,比如Okhttp。平台层也是如此,比如Android平台中的binder连接池。线程池在计算机程序设计中,线程池是计算机程序中实现并发执行的一种软件设计方法。一个线程池维护着多个线程等待主管分配任务并发执行。通过维护线程池,可以提高性能并避免执行延迟。可用线程数取决于程序可用的计算资源,例如并行处理器、内核、内存和网络套接字。一种常见的线程执行任务调度方式是同步队列,称为任务队列。池中的线程从队列中移除等待任务,并在执行完成时将它们放入已完成任务队列中。线程池的大小是为执行任务预留的线程数,通常是一个可调参数,通过调整可以优化程序性能。与为每个任务创建一个新线程相比,线程池的主要好处是线程创建和销毁的开销仅限于池的初始创建,这可以带来更好的性能和更好的系统稳定性。通常,创建和销毁线程及其相关资源是一个耗时的过程。但是,池中的线程过多会浪费内存,可运行线程之间的上下文切换也会导致性能问题。连接到另一个网络主机的套接字可能需要很多CPU周期,通过将套接字与多个网络事务中使用的线程相关联,可以更有效地维护套接字。根据等待任务的数量,线程的数量可以在应用程序的生命周期中动态调整。例如,如果许多网页同时发出请求,Web服务器可以添加线程,并在请求逐渐减少时删除线程。使用线程池需要注意的问题:创建太多线程会浪费资源关注已创建但未使用的线程销毁大量线程并花费更多时间重新创建它们创建线程太慢可能会导致客户端性能恶化销毁线程太慢可能会饿死其他处理过程。内存池。内存池使用pools进行内存管理,这样动态内存分配就可以达到malloc或者new的效果。由于内存碎片的存在,一个有效的解决办法是预先分配一些大小相同的内存块。许多实时操作系统使用内存池。一个简单的内存池实现如下图所示:对于内存池应用程序,可以通过以下方式分配、访问和释放内存:从池中分配内存时,函数将确定所需块的池。如果该池的所有块都已保留,则该函数会尝试在下一个更大的池中找到一个。分配的内存块由句柄表示。获取指向已分配内存的访问指针释放先前分配的内存块内存池将句柄划分为池索引、内存块索引和版本以在内部解释句柄。池和内存块索引允许使用句柄快速访问相应的块,而在每次新分配时递增的版本允许检测释放内存块的句柄。内存池允许以恒定的执行时间分配内存。池中数千个对象的内存释放只是一次操作,而不是一个一个释放。内存池也可以采用树形结构,用于特殊的编程行为,如循环、递归等。固定大小的块内存池不需要为每个块分配元数据存储,也不需要描述分配块的大小等特性。内存池也可以用于对象。在这种情况下,对象本身没有外部资源,只占用内存。已经创建的对象避免在创建对象时分配内存。当创建对象的成本很高时,对象池很有用,但在某些情况下,这种简单的对象池可能效率不高,实际上可能会降低性能。总结Pool是一种资源共享和重用的技术,它将管理的概念引入了编程世界。从基本的内存池,到线程池,再到各种连接池,还可以根据应用场景进一步细分,比如句柄池、缓冲池……几乎覆盖了互联网应用的绝大部分角落。如果你想上网,你可能需要先学习如何在游泳池里游泳。【本文来自专栏作家“老曹”原创文章,作者微信公众号:哦家ArchiSelf,id:wrieless-com】点此阅读更多本作者好文
