前言

牛牛在2020年面试腾讯时面试官问过这样一个场景:

以100每秒的速度向mysql写数据,持续5s,此时我们的程序和mysql建立了多少个tcp连接?

从编程的角度来看,一个问题的解答过程,无非是寻求输入输出,这里输出是多少个tcp连接,那么就要锁定输入,也就是参数,有哪些因素会影响这个问题?

在牛牛看来只有两点:mysql当前处理能力和连接池配置。

参数分析

1.mysql处理能力

如果负载正常的情况,mysql 1s内一定能处理100个请求。

如果负载比较高,那1s内就处理不完,为了方便讨论,这里假设1s能处理50个请求。

PS: 正常实体机的mysql,即使配置差到1核1G,也完全能胜任100/s的单纯插入请求。只有在mysql本身异常,或有其他进程占用系统资源时,才会出现1s处理不过来100个请求的情况。这里的两个分支只是逻辑上的讨论。

2.连接池

连接池是实现连接复用的手段,和mysql交互时,每次需要建立一个连接,用完就会关掉,这就是短连接。如果在高并发场景,反复建立连接的成本是很高的,所以我们可以使用长连接,即连接用完后先不关闭,放到一个池子里等待复用,这个池子就叫连接池。【腾讯二面】5s内建立多少个mysql连接?_java

如图所示,连接池暂存了使用完成之后的mysql连接以待复用,最大空闲连接数就是这个池子的大小。连接池通过一系列参数控制了针对mysql的连接复用策略,一般是由客户端引擎实现,支持哪些参数也由客户端引擎决定,通常而言所有的客户端引擎都支持如下几个主要参数:

  • 最大连接数:支持的最大连接数,即能打开连接的最大上限,如果超过这个阈值,就会出现too many connections的提示,这个数字通常可以设置得较大,以应对突如其来的峰值。

  • 最大空闲连接数: 这个参数在上图有标注,表示连接池中最多有多少个空闲连接 ,某个连接做完事务之后暂时空闲,如果连接池中空闲连接数没有达到上限,即可放入连接池。该参数其实可以理解为一共可维护多少个长连接来节约连接建立的成本。

  • 最长空闲时间: 连接池中连接使用完毕后会等到新的请求到来,表明了连接池中的连接在空闲时能在池子里摸鱼多久,如果长时间没有请求到来,说明请求量非常小,此时就需要释放掉连接来节省资源,等待多久,就是由该参数决定,本牛的建议是通常情况下10-20s就足够了。

  • 最小连接数: 连接池中最小空闲连接数,当连接数少于此值时,连接池会创建新的连接来进行补充,作用主要是保持连接池始终处于就绪状态,如果需要的长连接特别多,且请求是周期性的,比如晚上才有的情况下,可以考虑使用该参数。

  • 初始化连接数:初始化连接数目,实际意义不大,由最小连接数补齐即可。

可以看到,最大连接数、最大空闲连接数以及最大空闲时间,这三个参数是起决定作用的。最大连接数保证了长连接➕短连接的上限,避免了单一程序耗尽mysql的连接资源。最大空闲连接数决定了长连接的个数,最大空闲时间则决定了长连接的持续性。

参数正交

回到该题目上看,我们利用控制变量来分析,最大连接数和最大空闲时间我们假设足够大,以保证mysql的正常响应和长连接的可持续性。剩下的就是mysql本身消费能力,和最大空闲连接数即长连接数两个维度的正交了,我们分如下情况:

  1. 处理能力足够,且连接能完全复用:请求速度为100每秒,如果我们的最大空闲连接参数设置为100,而mysql处于正常状态,每秒能完成100个请求·,则一共建立了100个连接。

  2. 处理能力不足,最大空闲连接数足够大:请求以100每秒,如果我们的最大空闲连接数设置为100, 而mysql有负载压力,每秒完成50个请求,这里我们假设mysql处理都是按先入先出,即同一秒产生的请求,因为会先复用连接池,所以连接池那部分会先处理完毕,处理流程如图所示:

【腾讯二面】5s内建立多少个mysql连接?_java_02

圆圈中50:x表示这50个连接是在第x秒产生;长连接中doing表示准备处理中,done表示做完;短连接默认都是doing;红色字体表示下一秒就会处理,连线表明某个连接的前世今生。

时间结果
第一秒由于连接池为空,产生100个
第二秒复用连接池的50个,产生50个
第三秒复用连接池的50个,产生50个
第四秒复用连接池的50个,产生50个
第五秒连接池都在忙绿中,新产生100个
  1. 处理能力足够,但连接池最大空闲连接数较小:请求速度为100每秒,如果我们的最大空闲连接数设置为50,而mysql处于正常状态,每秒完成100个请求,则100➕4✖50

  2. 处理能力不足,且连接池最大空闲连接数较小:请求速度为100每秒,如果我们的最大空闲连接数设置为50,而mysql有负载压力,每秒只能完成50个请求。这种情况可按照场景2进行分析,欢迎有兴趣的读者在留言区交流。

小结

简简单单一个问题,牵引出的其实是mysql连接池的本质,这也是面试官面试时想考察的能力。

这个问题至少能考察出面试者两方面的能力,一是看面试者的思路是否清晰,在实际业务场景中提出来的需求,大多需要仔细思考来判断存在哪些影响因素,而在面试中留给面试者思考的时间并不多,大家的能力高下立判;第二点则是了解面试者对这些基本知识点的掌握情况,这也是对面试者的知识储备进行考察。

牛牛比较认可这种结合实际场景的面试题目,希望阅读完本篇文章之后大家能有所收获。

本文首发于公众号【牛牛码特】,欢迎关注:

原文链接:【腾讯二面】5s内建立多少个mysql连接?

也可以直接扫码关注牛牛哦~

【腾讯二面】5s内建立多少个mysql连接?_java_03