几乎每一个网站都是这么一个设计模式,先是前端接入层,然后是一些后台的逻辑服务,最后则是数据库。大家都知道,做一个10人能够访问的程序非常简单,但是要做一个能够同时满足1万人,100万人同时使用的程序,却是非常的难。今天我们来介绍程序员高并发架构中的池化技术。

讲池化技术之前,我们来讲一个现实中的例子,相信大家都去过网吧吧,十几年前,那个时候SSD的硬盘还非常昂贵,很多网吧都是普通的磁盘,开机非常慢,有些网吧为了提升用户体验,就会提前帮你把机器开好,那样子你去上网的时候,就不需要开机,直接就能上网,这便是池化技术。早上的时候上网的人少些,网管可能只打开10台机器,到了晚上,可能人会多些,网管会打开30台机器,这便是池化技术中的池大小调节。

程序员的技术栈中有非常多的池,如线程池、连接池、对象池、内存池,今天我们就来简单的介绍介绍,各种池。

连接池

相信每一个程序员都不陌生,我们在使用Redis等缓存或者Mysql等数据库的时候,就常常需要配置连接池,相信每个Java程序员都配置过C3P0或者HikariCP的连接池,为什么我们需要连接池,它有什么好处?

如果没有连接池,当我们访问数据库的时候,会发生什么事情,首先我们需要建立连接把,建立连接,以为着要三次握手,这就需要花个好几毫秒的时间,紧接着,不是每个人都能访问数据库吧,数据库它也需要验证登陆的账户密码,这又要花个1,2毫秒,然后才是真正的数据查询,可能就花了1,2毫秒,一个10毫秒的请求,可能80%的时间都浪费了。

其次,连接池可以让服务更加稳定,举个例子,假如下游的数据库支持一千个并发,但是业务层支持一万个并发,这个时候有可能会发生什么事情,业务层的一万个请求同时请求数据库,超过的下游系统的最大负荷,这不是把服务搞死么?连接池可以让我们给不同的业务分配不同的连接数,让他们的总数不会超过系统的最大值。

对象池

在Java语言中,垃圾回收是非常令人头痛的事情,特别是FullGC总是会引发一些问题,不止是Java很多语言都有这样的一个问题。举个例子,假如我们开发一款游戏,士兵对象的一个实例表示一只长枪小兵,可能玩家在一把游戏中,要打死成千上百只小兵,那么每次一只小兵死亡我们就要注销掉这个实例,每次有小兵刷新我们就重新new一个实例。大家都知道,向操作系统申请内存是有代价的,可能你是款单机游戏还好,如果是大型的网络游戏,页面上频繁有各个玩家打斗发生,这个时候我们最好使用对象池技术,当小兵死亡的时候,将它回收,而不是直接释放,下次有新的小兵出现的时候,直接复用。

对象池技术,减少了程序频繁向操作系统申请内存,特别是大块内存,我们更需要使用对象池技术,更好地优化内存的使用,减少垃圾回收次数,从而让程序更加优化。

线程池

与对象池类似,我们可以理解线程也是操作系统使用的一个对象,在现代计算机开发中,多线程是非常常见且必须的,可以有效的利用到CPU多个核心的特点,但是操作系统创建线程跟销毁线程又有一定的开销,所以,我们可以使用池化技术,但操作系统运行完某个线程之后,不是立即销毁,而是让这个空闲的线程继续等待新的任务去执行。

内存池

内存池,这个可能使用C++的同学使用的比较多,最为代表的便是由谷歌开发的TcMalloc与Facebook开发的JeMalloc。其实,Java开发中也会用到内存池,Java中有一些Unsafe的方法,可以直接管理内存,在一些中间件的开发中,我们会经常用到。

内存池较大的作用,便是减少内存碎片,什么是内存碎片?很多同学不理解什么是内存碎片,我们举一个例子。我们得到了一块木材,想用来做椅子,如果不对椅子每个部件需要的木材进行规划,想用啥就在木头上切下来,那么最终这个木头的利用率肯定不高。内存也是如此,如果每次申请都是随便分配,那就容易形成很多内存碎片,最后让程序变慢。

总结

好了,今天我们就分享到这里,希望对你有所启发。欢迎大家关注我,会跟大家一起学习分享计算机相关知识。大家的支持是我继续唠嗑的动力。

(文章来源:沙茶敏碎碎念)