【发布时间】:2022-01-26 18:14:00
【问题描述】:
我们最近将我们的服务器从 Tomcat 6 升级到了 Tomcat 9,并且遇到了应用程序每隔几个小时就会停止运行的问题。到目前为止我收集的一些要点:
- 系统在本地计算机上加载时没有任何错误,并且这只发生在生产站点上。
- 应用程序运行 6-7 小时,然后出现此白屏问题。
- 重新启动 Tomcat 服务器后,系统会再次恢复几个小时,然后重复整个过程。
- 它通常会在几个小时后出现连接问题,并且当这种情况发生时,数据库中的客户端连接似乎非常高。
这是在 Tomcat 中记录的内容。在调试时,用户不是空的,所以我不确定真正的问题是什么。我不确定是否需要重做数据库连接,或者是否是 Tomcat 的配置问题。
26-Jan-2022 11:23:46.614 SEVERE [https-jsse-nio-443-exec-6] org.apache.catalina.core.StandardWrapperValve.invoke Servlet.service() for servlet [jsp] in context with path [] threw exception [An exception occurred processing [jsp/index.jsp] at line [86]
83: <%
84: AccountInfo accountInfo = new AccountInfo();
85: String user = testOBJECTS.getName();
86: accountInfo.init(user);
87:
Stacktrace:] with root cause
java.lang.IllegalStateException: Failed to get connection..
at test.library.TestConnectionFactory.getConnection(Unknown Source)
at test.model.AccountInfo.init(Unknown Source)
at org.apache.jsp.jsp.index_jsp._jspService(index_jsp.java:248)
at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:764)
at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:466)
at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:379)
at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:327)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:764)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:227)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:197)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:542)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:135)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:687)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:357)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:382)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:893)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1726)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191)
at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Unknown Source)
这是 index.jsp 页面中获取用户的代码。
<jsp:useBean id="testOBJECTS" class="test.mainJspBean"/>
<jsp:useBean id="testTop" class="test.loggedInBean"/>
<jsp:useBean id="aircraftFolder" class="test.library.AircraftFolder"/>
<%
testOBJECTS.setLogin(request);
if (testOBJECTS.getLoggedIn()) {
testTop.setServletTop(request, testOBJECTS.getLoggedIn(), null, testOBJECTS.getName());
AccountInfo accountInfo = new AccountInfo();
String user = testOBJECTS.getName();
accountInfo.init(user);
}
%>
这是设置用户的 MainJspBean.java 类。
package test;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.LogManager;
import test.library.SubscribeConnectionFactory;
import test.loginLibraries.Login;
public class mainJspBean
{
static Logger log = LogManager.getLogger(mainJspBean.class.getName());
private String clientPage = "";
private boolean loggedIn = false;
private String name = "";
public String getLogin()
{
return clientPage;
}
public void setLogin(HttpServletRequest request) throws SQLException {
String user = (String) request.getSession().getAttribute(Login.UID);
String pass = (String) request.getSession().getAttribute(Login.PASS);
boolean loggedin = loggedInBean.isLoggedIn(user, pass);
if (loggedin) {
this.loggedIn = loggedin;
name = user;
System.out.println("name: " + name);
clientPage += "<div align=\"justify\" class=\"style1\"><a href=\"https://" + IPs.WebAddress() + "/jsp/index.jsp\">TEST Online</a></div>\n";
} else {
clientPage += "<br><FORM autocomplete=\"off\" METHOD=\"post\" ACTION=\"https://"+ IPs.WebAddress() +"/test/login\" onSubmit=\"return checkWhiteSpace()\">\n" +
"<table border=\"0\" cellpadding=\"0\" cellspacing=\"0\" align=\"right\" valign=\"top\">\n" +
"<tr>\n" +
"<td nowrap align=\"right\" ><span class=\"topText\" align=\"right\">User Name: </span><input type=\"text\" name=\"uid\" id=\"uid\" size=\"8\" ></td>\n" +
"</tr>\n" +
"<tr>\n" +
"<td nowrap align=\"right\" ><span class=\"topText\" align=\"right\">Password: </span><input type=\"password\" name=\"auth\" size=\"8\"></td>\n" +
"</tr>\n" +
"<tr>\n" +
"<td nowrap colspan=\"2\" align=\"right\" ><input type=\"checkbox\" name=\"remember\" value=\"1\" checked> <span " + "class=\"topText\">Remember me.</span></td>\n" +
"</tr>\n" +
"<tr>\n" +
"<td align=\"right\" colspan=\"2\"><input type=\"submit\" class=\"IP\" name=\"login\" value=\"Login\">\n" +
"<a href=\"https://" + IPs.WebAddress() + "/payAsYouGoSignUp.jsp\">Register</a></td>\n" +
"</tr>\n" +
"</table>\n" +
"<script type=\"text/javascript\">\n" +
"<!--\n" +
"function checkWhiteSpace() {\n" +
" var s = document.getElementById(\"uid\").value;\n"+
" // Check for white space\n" +
" if (s.indexOf(\" \") > -1) {\n" +
" jAlert(\"The User Name that you entered contains a white space.\");\n" +
" return false;\n" +
" }\n" +
" return true;\n" +
"}\n" +
"//-->\n" +
"</script>\n" +
"</form>\n";
}
}
public String getWebAddress()
{
return IPs.WebAddress();
}
public boolean getLoggedIn()
{
return loggedIn;
}
public String getName()
{
return name;
}
}
这是实际的 TestConnection 页面。
public class TestConnectionFactory {
static final Runtime RUNTIME = Runtime.getRuntime();
static Logger log = LogManager.getLogger(TestConnectionFactory.class.getName());
DataSource ds = null;
long connectCount;
/**
* A handle to the unique Singleton instance.
*/
static private TestConnectionFactory instance = null;
/**
* The constructor could be made private
* to prevent others from instantiating this class.
* But this would also make it impossible to
* create instances of Singleton subclasses.
*/
protected TestConnectionFactory() {
log.debug("<init> freeMemory:"+RUNTIME.freeMemory());
if (ds == null) {
ds = getDataSource();
}
}
/**
* @return The unique instance of this class.
*/
static public synchronized TestConnectionFactory getInstance() {
if (instance == null) {
log.info("getInstance():creating new instance");
instance = new TestConnectionFactory();
log.debug("getInstance():reusing existing instance");
}
return instance;
}
public Connection getConnection() {
Connection connection = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
try {
connection = ds.getConnection();
} catch (SQLException e) {
e.printStackTrace();
}
return connection;
}
我试过的东西是指这个Java web app in tomcat periodically freezes up 发布的问题听起来与我的应用程序相似,但修复不起作用。我尝试过的事情:
- 更改 context.xml 文件中的 maxWaitMillis 和 maxActive。
- 增加客户端数据库连接的总数。
- 在 Java 代码中为空用户设置陷阱。
【问题讨论】:
-
乍一看,发生这种情况时,你可以从运行tomcat的机器(shell)连接到数据库(服务器)吗?数据库起来了?什么操作系统?
index.jsp是唯一的端点? -
@PeterMmm 我想是的。我只需要重新启动 tomcat 而不是 mysql 所以我假设它是但我需要在下次发生时再次仔细检查。它在 Windows 上。它是一个池连接,所以它在很多地方都被使用。这是似乎抛出此错误消息的众多页面之一。
-
你真的在使用
TestConnectionFactory.getConnection()的地方关闭连接吗? -
我的第一步是停止使用连接池。使用新的连接看看是否一切顺利。
-
您的 getConnection 方法的资源管理非常脆弱,如果验证失败,它会泄漏连接。此外,大多数连接池数据源将为您提供这些检查:无需自己动手。我的猜测是您使用的数据源发生了一些变化(例如,它不再回收泄漏的连接或类似的东西)。
标签: java mysql jdbc tomcat6 tomcat9