<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Testwhileidle on Joonlog</title><link>https://joonlog.github.io/tags/testwhileidle/</link><description>Recent content in Testwhileidle on Joonlog</description><generator>Hugo -- gohugo.io</generator><language>ko-kr</language><lastBuildDate>Thu, 19 Jun 2025 09:00:00 +0900</lastBuildDate><atom:link href="https://joonlog.github.io/tags/testwhileidle/index.xml" rel="self" type="application/rss+xml"/><item><title>죽은 Connection 사용 중인 Tomcat Troubleshooting</title><link>https://joonlog.github.io/p/%EC%A3%BD%EC%9D%80-connection-%EC%82%AC%EC%9A%A9-%EC%A4%91%EC%9D%B8-tomcat-troubleshooting/</link><pubDate>Thu, 19 Jun 2025 09:00:00 +0900</pubDate><guid>https://joonlog.github.io/p/%EC%A3%BD%EC%9D%80-connection-%EC%82%AC%EC%9A%A9-%EC%A4%91%EC%9D%B8-tomcat-troubleshooting/</guid><description>&lt;h3 id="문제-상황"&gt;문제 상황
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;웹 서비스 접근 시 500 에러 출력&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="원인-분석"&gt;원인 분석
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;웹 서비스에 DB 서버 2대를 이중화하여 구성 중, 2번 서버로 DB Failover된 후 장애 발생&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;application log 확인&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;org.springframework.jdbc.support.SQLErrorCodesFactory&lt;span class="o"&gt;]&lt;/span&gt; Error &lt;span class="k"&gt;while&lt;/span&gt; extracting database product name - falling back to empty error codes
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;org.springframework.jdbc.support.SQLStateSQLExceptionTranslator&lt;span class="o"&gt;]&lt;/span&gt; Extracted SQL state class &lt;span class="s1"&gt;&amp;#39;JD&amp;#39;&lt;/span&gt; from value &lt;span class="s1"&gt;&amp;#39;JDBC-90405:ERRJD&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;org.springframework.transaction.interceptor.TransactionInterceptor&lt;span class="o"&gt;]&lt;/span&gt; Application exception overridden by rollback exception
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;org.apache.catalina.core.StandardWrapperValve.invoke Servlet.service&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; servlet &lt;span class="o"&gt;[&lt;/span&gt;...&lt;span class="o"&gt;]&lt;/span&gt; threw exception &lt;span class="o"&gt;[&lt;/span&gt;...&lt;span class="o"&gt;]&lt;/span&gt; with root cause
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Tomcat에서 Failover 이전 DB 서버로의 Connection을 계속 사용해서 &lt;code&gt;SQLException&lt;/code&gt; 오류 발생하여 500 에러 출력&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="조치-내용"&gt;조치 내용
&lt;/h3&gt;&lt;blockquote&gt;
&lt;p&gt;즉각적인 웹 서비스 정상화를 위한 임시 조치&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ol&gt;
&lt;li&gt;Tomcat 재기동 후 웹 서비스 정상 접근 확인&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="추가-조치-방안"&gt;추가 조치 방안
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;Tomcat의 server.xml 혹은 &lt;code&gt;context.xml&lt;/code&gt;에서 &lt;code&gt;testWhileIdle&lt;/code&gt; 설정
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;testWhileIdl&lt;/code&gt;: Tomcat이 Connection을 반환하기 전, 주기적으로 유휴 Connection 생존 여부를 검사&lt;/li&gt;
&lt;li&gt;&lt;code&gt;timeBetweenEvictionRunsMillis&lt;/code&gt;: 30초마다 검사&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;testWhileIdle&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;true&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;timeBetweenEvictionRunsMillis&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;30000&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="결론"&gt;결론
&lt;/h3&gt;&lt;p&gt;Tomcat의 JDBC Connection Pool은 &lt;code&gt;testWhileIdle&lt;/code&gt; 옵션이 &lt;code&gt;false&lt;/code&gt;일 경우, 장애 이후에도 죽은 Connection을 계속 사용할 수 있어 장애가 지속됨. 이 설정을 &lt;code&gt;true&lt;/code&gt;로 변경하고 &lt;code&gt;timeBetweenEvictionRunsMillis&lt;/code&gt;를 설정해서 DB Failover 시 자동적으로 Connection을 복구하도록 설정&lt;/p&gt;
&lt;h3 id="참고"&gt;참고
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://blog.naver.com/wasgosu-2010/90189771881" target="_blank" rel="noopener"
&gt;https://blog.naver.com/wasgosu-2010/90189771881&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item></channel></rss>