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

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

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

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

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

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

     4
     15
  • 大卫
    2019-10-04
    我在设计一个产品要求的专辑详情页中使用到了自定义的线程池。

    专辑详情页中包含多个板块,部分几个板块要求动态请求搜索或者推荐接口获取数据,板块与板块之间要求内容去重,搜索推荐对于本系统来说属于第三方接口。

    经过考量,使用了CompletableFuture来实现并行请求,同时自定义线程池,使用有界队列,设置合理的线程池大小。根据压测结果,调整出一个合适的线程池大小,使该接口性能达到预期。
    展开

    作者回复: 👍

    
     7
  • 613
    2019-10-09
    phper太难了

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

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

    5.请教环节,系统的线程池我自己埋点压过,确如老师所说,cpu密集线程池看核数就够了,io密集可以多些并行,因为数据传输不需要cpu。但是,从我自己压,捣鼓出来的结果看。io操作的线程确实可以在不处于cpu操作的时间片内时,继续做数据传输,但是,它不让渡时间片,也就是当一个cpu调度到一个执行io操作的线程,这条线程不会快速让渡出时间片给其他cpu操作的线程,就像sleep似的。我想问下老师,为什么这样设计,出于什么考量,更或者是我自己捣鼓错了?
    展开

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

     3
     4
  • 高源
    2019-10-02
    老师理论听的挺明白,还是需要动手实战啊,有些东西理解起来很模糊,但实践上有可能一下子就明白了😊

    作者回复: 😄

    
     3
  • 逍遥
    2019-11-11
    老师,我还是没理解,那我们自己写代码创建的线程池,如果是按jdk原生线程池的流程先放入队列,那不就只适合cpu密集型的场景?这个是怎么解决?还是说tomcat帮我们处理了?

    作者回复: 是tomcat中使用的线程池与原生的线程池不同,tomcat使用的线程池是先增加线程,后放入队列

    
     1
  • 雷霹雳的爸爸
    2019-11-05
    坑啊,jedis的连接池,旧版的jedis有个奇怪的玩意儿,.returnBrokenResource,得写段套路得代码避免把一个坏掉的连接又在之后被使用,结果我们那东西没按套路来,自己一通乱封装,还是个多租户的系统,写到别人家去了,然后就是如文章所说,maxThreadCount设小了,自己给自己把吞吐量给限制住了,怎么压也压不上去...

    作者回复: 😂😂

    
     1
  • 无形
    2019-11-01
    要使用连接池,程序需要常驻内存,如果像PHP使用nginx phpfpm方式,每来一个请求fork一个子进程来处理,处理完子进程就结束了,似乎没法使用连接池
    
     1
  • 永光
    2019-10-11
    validationQuery = "SELECT 1" ,testWhileIdle ,testOnBorrow
    老师好,
    1、请问testWhileIdle和testOnBorrow这两个配置项有什么区别呀?
    2、testWhileIdle和testOnBorrow的校验都依赖与validationQuery配置的语句吗?
    谢谢。

    作者回复: testOnBorrow是在获取连接的时候校验连接
    testWhileIdle是有周期性的校验
    这两个都依赖validationQuery

    
     1
  • longslee
    2019-10-10
    哈哈,老师我之前一直用Executor的FixedPool,它是无界的队列,所以也 core == max,但是我拿它来处理数据库相关的了,看来以后我得改过来~ 还有,max满了不一定是丢弃呀,可以实现接口自定义满空间的操作,可以丢弃,也可以重试,也可以记录什么的,但是重试一定要给它一定的时间,否则过快提交会StackOverFlow嗷~

    作者回复: 嗯那 可以自定义策略

    
     1
  • xu晓晨
    2019-10-08
    学完这节课我发现php不是最好的语言了。
    另外想问一下phper想学另外一名语言 是选择java还是go呢?

    作者回复: go,😂

     1
     1
  • 约书亚
    2019-10-03
    还有一种是内存池,用的地方相对较少,基本都是重型武器才有,比如netty这种。
    这门课总会提到实际工作中遇到的坑,还挺不错

    作者回复: 是的,内存池也是一种常见的池化技术的常见实现

     2
     1
  • jc9090kkk
    2019-10-02
    国庆打卡,感谢老师的分享,对于这篇文章存有个疑问,希望老师能解答一下:
    1.文中说的最小连接数是10和最大连接数是20-30,这个数是如何计算出来的?有没有参考标准或者计算公式?根据具体的业务场景或者规模,有什么可以套用的配置经验吗?
    2.这个最大连接数跟mysql配置参数中的max_connections有什么联系吗?如果连接池的最大连接数设置成100,最后的连接请求还是会打到mysql上,如果max_connections这个值太小,还是会报错的啊?这两个值应该一起配合使用吧?我的理解有问题吗?

    作者回复: 1. 其实这些是经验所得,这个数值需要在实际运行中来调整,初期可以按照这个来设置
    2. 连接池的最大连接数肯定要小于max_connections的,你的理解没错~

    
     1
  • Geek_908e99
    2020-02-07
    没有完全理解线程池的那一段关于CPU密集系统和IO密集系统的区别,为什么IO密集的系统适合创建大于coreThreadCount数目的线程?一个任务在被线程执行时,如果遇到IO操作需要等待,那这个任务就被放回队列了,这个线程就被释放了,可以执行其他的任务。如果线程池的线程数大于CPU核心数的话,不是会有和CPU密集型系统同样的上下文切换的问题吗?除非这里的假设是IO密集型系统的线程池里的线程永远是有一部分空闲的,但是如果是那样的话为什么还要创建更多线程呢?

    作者回复: 其实主要的问题是,io密集型的系统,CPU会不那么繁忙,所以可以处理更多线程的安排的任务

    
    
  • 张珂
    2020-01-21
    老师好,相似的还有在以高效操作内存的场景下,内存资源管理也使用“池化”思想实现的,比如memcache或其他内存组件,使用“内存池”,内存申请到后一般不再还给系统,自己管理起来,以便于后续复用,省去了反复申请释放内存的时间。

    作者回复: 是的,内存池化也是比较常见的

    
    
  • 王宝
    2020-01-14
    http连接池
    
    
  • 折枳
    2020-01-07
    刚看完丁奇老师的MySQL实战45讲,有说到“select 1 成功返回,只能说明这个库的进程还在,并不能说明主库没问题”,需要了解的同学可以去看下第29讲

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

    
    
  • 耀
    2019-12-27
    连接池接触的比较少,只是用过一次,就如同作者讲的,设置了最小连接和最大连接,只是那个链接的队列大小没有做限制,目前没有遇到流量很大的场景,若是遇到了很可能会有作者相同的问题。这便是学习专栏最直接的价值,能让我们避开陷阱,或者发现没有意识到的bug。

    作者回复: 是的 这个在高并发场景下是标配

    
    
我们在线,来聊聊吧