高并发系统设计 40 问
唐扬
美图公司技术专家
49013 人已学习
新⼈⾸单¥59
登录后,你可以任选4讲全文学习
课程目录
已完结/共 49 讲
高并发系统设计 40 问
15
15
1.0x
00:00/00:00
登录|注册

07 | 池化技术:如何减少频繁创建数据库连接的性能损耗?

一课一思
课程小结
池化技术的缺陷
池化技术的优势
线程池
连接池
池化技术

该思维导图由 AI 生成,仅供参考

在前面几节课程中,我从宏观的角度带你了解了高并发系统设计的基础知识,你已经知晓了,我们系统设计的目的是为了获得更好的性能、更高的可用性,以及更强的系统扩展能力。
那么从这一讲开始,我们正式进入演进篇,我会再从局部出发,带你逐一了解完成这些目标会使用到的一些方法,这些方法会针对性地解决高并发系统设计中出现的问题。比如,在 15 讲中我会提及布隆过滤器,这个组件就是为了解决存在大量缓存穿透的情况下,如何尽量提升缓存命中率的问题。
当然,单纯地讲解理论,讲解方案会比较枯燥,所以我将用一个虚拟的系统作为贯穿整个课程的主线,说明当这个系统到达某一个阶段时,我们会遇到什么问题,然后要采用什么样的方案应对,应对的过程中又涉及哪些技术点。通过这样的讲述方式,力求以案例引出问题,能够让你了解遇到不同问题时,解决思路是怎样的,当然,在这个过程中,我希望你能多加思考,然后将学到的知识活学活用到实际的项目中。
接下来,让我们正式进入课程。
来想象这样一个场景,一天,公司 CEO 把你叫到会议室,告诉你公司看到了一个新的商业机会,希望你能带领一位兄弟,迅速研发出一套面向某个垂直领域的电商系统。
在人手紧张,时间不足的情况下,为了能够完成任务,你毫不犹豫地采用了最简单的架构:前端一台 Web 服务器运行业务代码,后端一台数据库服务器存储业务数据。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

文章介绍了连接池技术和线程池技术在提升系统性能方面的重要性和应用。通过虚拟垂直电商系统的案例,阐述了频繁创建数据库连接可能导致性能下降的问题,并介绍了连接池的工作原理。同时,还详细讨论了线程池的实现原理和适用场景。文章强调了连接池和线程池的最小值和最大值设置的重要性,以及池子的预热和空间占用情况的关注。作者还分享了在实际项目中使用池化技术的经验和注意事项,以及对池化技术的思考和展望。总的来说,本文通过生动的比喻和实际案例,深入浅出地介绍了连接池和线程池技术的原理和应用,对读者快速了解并应用于实际项目中具有指导意义。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《高并发系统设计 40 问》
新⼈⾸单¥59
立即购买
登录 后留言

全部留言(87)

  • 最新
  • 精选
  • 每天晒白牙
    1.老师我想请教下文中说的线程池预热,既初始化核心线程数的线程,我看jdk的源码没看到预热过程。 而且请求过来,如果线程数小于核心线程数,就创建线程处理,如果线程数大于核心线程数,就往队列中添加,如果是有界队列,则判断队列是否满了,如果满了,且线程数没有达到最大线程数就继续创建线程,是这样的流程,没有在初始化时就创建核心线程数这个数量的线程 2.如果线程池采用无界队列,确实会存在内存撑爆的问题,且最大线程数这个参数就没用了,这种队列存在有意义吗? 3.我们工作中也用到了池化技术,线程池,各种连接池 4.我工作中遇到一个关于vertx-redis-clent的频繁fgc的问题,这个就是把请求放队列里,而队列是无界的,导致内存满了,频繁fgc,下面是我的排查过程,希望能对大家有帮助 https://mp.weixin.qq.com/s/fWsy26VeUvb8yPKON3OTmA

    作者回复: 1. ThreadpoolExecutor提供了prestartAllCoreThreads方法可以预先启动核心线程 2. 如果使用无界队列的话,最大线程数就没有意义了,因为永远不会用到,所以尽量不要使用无界队列

    2019-10-02
    21
    55
  • Chocolate
    重要线程池的队列任务堆积量,请问下老师,这个指标怎么监控。

    作者回复: jdk的ThreadPoolExecutor可以调用executor.getQueue().size()

    2019-10-02
    3
    37
  • helloworld
    老师在网上查了很多的资料对于TPS和QPS两个性能指标的区分,但是也没有搞清楚到底两者有什么区别,以及两者的计算公式,老师能不能详细解释下呢?感谢。打卡06.

    作者回复: 我理解的QPS是每秒查询数,是针对读请求的 TPS是每秒执行事务数,倾向于写请求

    2019-10-08
    5
    33
  • 613
    phper太难了

    作者回复: 怎么会,是最好的语言呀:)

    2019-10-09
    4
    17
  • 大卫
    我在设计一个产品要求的专辑详情页中使用到了自定义的线程池。 专辑详情页中包含多个板块,部分几个板块要求动态请求搜索或者推荐接口获取数据,板块与板块之间要求内容去重,搜索推荐对于本系统来说属于第三方接口。 经过考量,使用了CompletableFuture来实现并行请求,同时自定义线程池,使用有界队列,设置合理的线程池大小。根据压测结果,调整出一个合适的线程池大小,使该接口性能达到预期。

    作者回复: 👍

    2019-10-04
    2
    15
  • 折枳
    刚看完丁奇老师的MySQL实战45讲,有说到“select 1 成功返回,只能说明这个库的进程还在,并不能说明主库没问题”,需要了解的同学可以去看下第29讲

    作者回复: 是的,但是这是最轻量的

    2020-01-07
    4
    12
  • Jxin
    1.先回答课后题,池化的应用。池化就是空间换时间。万物皆对象,而java里面的对象是有生命周期的。对象的生死对应着有生时资源申请和死时资源释放这两步操作,而这些操作是有时间开销的。这个时候如果想降低这些开销,那么就要少生对象少死对象,而要少生少死就得复用,即干完继续干不准死,即延长对象生命周期并重用之。那么就可以采用池化,用的时候往里面拿,用完放回去。所以就出现了对象池,而对象即万物。也就是说,只要你是想降低对象生死开销的,那么就可以采用池化。但于我个人,我不喜欢池化。 2.我个人认为,池化仅用在线程池好点。其他都不咋地。因为线程是执行体本身,所以挺合适。其他池化操作,都属于资源,那么复用就要无状态,即拿出来和放回去要一个样,不然就会影响下一个人使用(下一个线程),那么在操作池化对象时要么得设计无状态要么得在归还或拿取做init操作,太麻烦,不直观,不喜。而且池化资源还是个竞量,这就是个提高复杂度的大坑,太糟糕了,弃了弃了。 3.说归说,其实用还是用的,毕竟也不全是jvm内部的“干净”对象池,有些对象池跟jvm外部资源有关系“不干净”。这种不干净的对象池,采用池化按需配置也是比较恰当的操作,毕竟外部关系这种开销大小不好确定,比如各种连接池。 4.但我个人做的工具,碰到这种空间换时间,随手就是线程空间绑定,虽然还有复用无状态的问题,但至少不担心竞量问题了。而各种数据链接池,如果开启了事务也是往线程空间内放该链接的(为了拿到同一条链接)。 5.请教环节,系统的线程池我自己埋点压过,确如老师所说,cpu密集线程池看核数就够了,io密集可以多些并行,因为数据传输不需要cpu。但是,从我自己压,捣鼓出来的结果看。io操作的线程确实可以在不处于cpu操作的时间片内时,继续做数据传输,但是,它不让渡时间片,也就是当一个cpu调度到一个执行io操作的线程,这条线程不会快速让渡出时间片给其他cpu操作的线程,就像sleep似的。我想问下老师,为什么这样设计,出于什么考量,更或者是我自己捣鼓错了?

    作者回复: 线程在等待io操作的时候确实会让出CPU时间片,可以说说你是如何测试的吗~

    2019-10-03
    11
    10
  • lofaith
    老师,我想问下,IOC容器技术是不是相当于一个对象池,里面放着一堆创建好的对象,当你需要的时候通过依赖注入提供给你,这也算池化技术的一种应用吗

    作者回复: 算是的

    2020-03-23
    9
  • sun
    老师你的发量还好吗?

    作者回复: 还好,谢谢关心~

    2019-10-15
    8
  • cai
    对ThreadPoolExecutor的每一个参数理解透彻很重要,曾经以为maximumPoolSize调大就可以增加线程数,其实不然,如果任务队列不满,线程数是不会增加的,所以导致任务在队列里面排队,然后线程池还是只有corePoolSize大小。

    作者回复: 是的,理解原理很重要

    2019-10-14
    2
    8
收起评论
显示
设置
留言
87
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部