告警通知群报错:数据库连接池的连接获取异常,导致tomcat线程池活跃的线程参数达到阈值。
org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.exceptions.PersistenceException: Error querying database. Cause: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection; nested exception is com.alibaba.druid.pool.GetConnectionTimeoutException: wait millis 1000, active 100, maxActive 100, creating 0, runningSqlCount 5 因为给线上数据库的一张表临时增加了一个索引,引发了一个
我们公司使用的mysq版本是5.1.7,创建索引时,表会被完全锁定,阻塞所有的读写操作。
(1)技术人员A:连接池中设置线程1s超时会让tocamt线程池打满 (2)B:拿链接100ms,感觉可能会导致失败变多?小了等于快速失败,没有容错,多了线程池打满拒绝请求,所以我得先看看 (3)专家:tomcat响应不了请求就都错了,快速超时返回,我们还可以处理一部分请求。就设100ms 观察一下,我以前都设50ms的。这个保守一点,可以多调几次,慢慢往下调,1s肯定是不行的。 技术人员之间的讨论反映了不同的设计哲学和对系统健壮性的关注。以下是对这些讨论的详细分析和理解:
1s超时会让Tomcat线程池打满
A 认为设置 1 秒的超时时间会导致 Tomcat 线程池被占满。原因如下:
拿链接100ms,感觉可能会导致失败变多?小了等于快速失败,没有容错,多了线程池打满拒绝请求
B 的担心是:
没事的,Tomcat响应不了请求,就都错了,快速超时返回,我们还可以处理一部分请求。就设100ms,观察一下,我以前都设50ms的。这个保守一点,可以多调几次,慢慢往下调,1s肯定是不行的
专家解释了更短的超时时间的优势:
这段对话中的主要观点强调了协作和逐步优化的重要性。通过持续监控和调整,可以找到一个平衡点,使系统在高效和稳定间取得最佳状态。
这里的意思并不是说1s真的等同于无限长时间,但在实际系统应用中,1s 是一个很长的等待时间,特别是在高并发和高要求的系统中。
资源占用:
系统反应迟缓:
选择 100ms 作为超时时间是基于经验和系统对延迟的承受能力,这会使系统更快地反应并调整。以下是选择 100ms 的一些理由:
快速反馈:
负载均衡:
逐步调整:
资深技术专家建议将数据库连接池的连接超时时间设为 100ms,是为了通过快速失败机制尽快释放线程资源,提升系统整体响应能力,提高系统在高并发和资源紧张时候的表现。
具体数值(1s 和 100ms)是基于经验和对系统性能的需求得出来的:
你说得对,设置数据库连接池的超时时间确实和数据库的处理时间密切相关。虽然没有一个具体的“一刀切”公式,但我们可以通过以下思路和假设来推导一个合理的超时时间设置。
假设我们有以下系统特性:
**数据库处理一个查询的时间($ T_{db} $)**是系统设置超时的基础。我们假设我们希望设置的超时时间必须保证大部分请求不会因为等待连接而失败。
**并发连接数($ N_{max} $)**决定了同时能够处理多少个请求。如果高于这个数值,新的请求将需要等待连接释放。
**超时时间($ T_{timeout} $)**是我们希望每个连接请求等待的最大时间。
我们希望超时时间能够容忍在高并发情况下的正常操作,而不会造成大量的超时失败。一个简单的推导公式可以基于以下事实:
T t i m e o u t ≥ T d b × N c o n c u r r e n t N m a x T_{timeout} \geq \frac{T_{db} \times N_{concurrent}}{N_{max}} Ttimeout≥NmaxTdb×Nconcurrent
假设系统高峰期的最大并发请求数($ N_{concurrent} $) 和数据库能处理的最大并发连接数($ N_{max} $)。如果 $ N_{concurrent} \leq N_{max} $,那么超时相对可忽略。
但在高峰期,如果超过最大并发连接数,一些请求就需要等待。假设一个查询平均处理时间为 $ T_{db} $,则所有请求完成时间为:
T t o t a l = N c o n c u r r e n t N m a x × T d b T_{total} = \frac{N_{concurrent}}{N_{max}} \times T_{db} Ttotal=NmaxNconcurrent×Tdb
超时时间需要大于等于每个请求的等待时间,
T t i m e o u t ≥ T d b × N c o n c u r r e n t N m a x T_{timeout} \geq \frac{T_{db} \times N_{concurrent}}{N_{max}} Ttimeout≥NmaxTdb×Nconcurrent
假设:
根据上述公式,超时设置为 100ms 是合理的,因为它能够在这种高并发情况下,让大多数请求在合理的时间内获得连接。
实际系统中,最好结合实际监控数据逐步调整和优化超时时间:
超时时间的设置必须考虑数据库的处理时间、并发请求数量以及连接池的最大连接数。尽管没有一个普适的公式,上述推导可以作为一个合理起点,结合实际应用中的监控和调优使系统保持高效和稳定。