/**
* Get a db connection from the pool.
*
* If removeAbandoned=true, recovers db connections which
* have been idle > removeAbandonedTimeout and
* getNumActive() > getMaxActive() - 3 and
* getNumIdle() < 2
*
* @return Object jdbc Connection
* @throws Exception if an exception occurs retrieving a
* connection from the pool
*/
public Object borrowObject() throws Exception {
if (config != null
&& config.getRemoveAbandoned()
&& (getNumIdle() < 2)
&& (getNumActive() > getMaxActive() - 3) ) {
removeAbandoned();
}
Object obj = super.borrowObject();
if (obj instanceof AbandonedTrace) {
((AbandonedTrace) obj).setStackTrace();
}
if (obj != null && config != null && config.getRemoveAbandoned()) {
synchronized (trace) {
trace.add(obj);
}
}
return obj;
}
/**
* Return a db connection to the pool.
*
* @param obj db Connection to return
* @throws Exception if an exception occurs returning the connection
* to the pool
*/
public void returnObject(Object obj) throws Exception {
if (config != null && config.getRemoveAbandoned()) {
synchronized (trace) {
boolean foundObject = trace.remove(obj);
if (!foundObject) {
return; // This connection has already been invalidated. Stop now.
}
}
}
super.returnObject(obj);
}
worker.node1.connection_pool_minsize=25
worker.node1.connection_pool_timeout=600
Hmm,既然已经注意到了这点,我们就可以把Tomcat的connectionTimeout调得比较大,让它完全包容mod_Jk counterpart,又或者把mod_jk的connection_pool_minsize 设成0,再或者在mod_jk中设置worker.node1.prepost_timeout=10000 ,通过断开死连接的方式,都是可以解决这个问题的。写到这,忽然想起之前封装的那个高性能的HttpClient。为什么我敢“吹牛”它是高性能呢?原因很简单,Apache的性能参数之前我们已经进行了调优(通过分析日志统计出连续HTTP请求出现的次数、间隔时间、访问量, 以确定 MaxKeepAliveRequests 和 KeepAliveTimeout 的值。说到这里,我有必要提醒大家注意一下Timeout和KeepAliveTimeout的区别,用两段官方的解释说明一下吧,个人觉得很贴切:
The TimeOut directive currently defines the amount of time Apache will wait for three things:
1. The total amount of time it takes to receive a GET request.
2. The amount of time between receipt of TCP packets on a POST or PUT request.
3. The amount of time between ACKs on transmissions of TCP packets in responses.
The number of seconds Apache will wait for a subsequent request before closing the connection.Once a request has been received, the timeout value specified by the Timeout directive applies.
),那么我封装HttpClient的时候,只需要对接apache的MPM参数(具体可参看:http://blog.csdn.net/fengjia10/article/details/7315279),那么在设计,编码阶段就可以解决大部分性能问题,剩下的就是根据业务场景稍作调优即可。
小结:通过这篇博客,我想说的是,作为职业架构师,我们不仅要读的通源码,玩得起perf tool(分析问题,解决问题),更需要的是将你的优化意识尽可能早的引入到软件的研发周期中(根据以往的经验,过早考虑性能,也可能会导致代码晦涩难懂。建议在设计中作为非功能需求考量,并在代码的优化阶段(也可能是提测后)实施性能调优),即架构设计,甚至是基础代码的编写过程中。尽可能的运用数学模型去验证你的性能参数选择。请牢牢记住:意识永远比技术更重要。
1. http://commons.apache.org/dbcp/configuration.html
2. http://software.intel.com/zh-cn/articles/book-Multicore-Multithread-Technology_tuning_cycle/