Jenkins部署时连接AWS MySQL出现CommunicationsException问题排查
问题:Jenkins部署后无法连接AWS上的MySQL数据库
我正在对Web应用做自动化测试,应用需要从AWS部署的MySQL数据库拉取信息。数据库URL和端口已经核对过没问题。登录后要从数据库获取特定链接来推进流程,本地运行完全正常,但部署到Jenkins后就报通信链接失败的错误。
错误日志
com.mysql.cj.jdbc.exceptions.CommunicationsException: Communications link failure The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server. at com.mysql.cj.jdbc.exceptions.SQLError.createCommunicationsException(SQLError.java:174) at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:64) at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:829) at com.mysql.cj.jdbc.ConnectionImpl.<init>(ConnectionImpl.java:449) at com.mysql.cj.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:242) at com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:198) at java.sql.DriverManager.getConnection(DriverManager.java:664) at java.sql.DriverManager.getConnection(DriverManager.java:247) at com.bmw.automation.pages.abstraction.AbstractPageBmw.getLastLinkQRCode(AbstractPageBmw.java:115) at com.bmw.automation.pages.common.GmailBoxPage.openLinkQRcode(GmailBoxPage.java:575) at com.bmw.automation.bdd.stepsDefinition.GmailBoxPageStepsDefinition.i_extract_the_link(GmailBoxPageStepsDefinition.java:228) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at io.cucumber.java.Invoker.doInvoke(Invoker.java:66) at io.cucumber.java.Invoker.invoke(Invoker.java:24) at io.cucumber.java.AbstractGlueDefinition.invokeMethod(AbstractGlueDefinition.java:47) at io.cucumber.java.JavaStepDefinition.execute(JavaStepDefinition.java:29) at io.cucumber.core.runner.CoreStepDefinition.execute(CoreStepDefinition.java:66) at io.cucumber.core.runner.PickleStepDefinitionMatch.runStep(PickleStepDefinitionMatch.java:63) at io.cucumber.core.runner.ExecutionMode$1.execute(ExecutionMode.java:10) at io.cucumber.core.runner.TestStep.executeStep(TestStep.java:92) at io.cucumber.core.runner.TestStep.run(TestStep.java:64) at io.cucumber.core.runner.PickleStepTestStep.run(PickleStepTestStep.java:51) at io.cucumber.core.runner.TestCase.run(TestCase.java:104) at io.cucumber.core.runner.Runner.runPickle(Runner.java:71) at io.cucumber.testng.TestNGCucumberRunner.lambda$runScenario$0(TestNGCucumberRunner.java:116) at io.cucumber.core.runtime.CucumberExecutionContext.runTestCase(CucumberExecutionContext.java:117) at io.cucumber.testng.TestNGCucumberRunner.runScenario(TestNGCucumberRunner.java:113) at io.cucumber.testng.AbstractTestNGCucumberTests.runScenario(AbstractTestNGCucumberTests.java:31) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:133) at org.testng.internal.TestInvoker.invokeMethod(TestInvoker.java:598) at org.testng.internal.TestInvoker.invokeTestMethod(TestInvoker.java:173) at org.testng.internal.MethodRunner.runInSequence(MethodRunner.java:46) at org.testng.internal.TestInvoker$MethodInvocationAgent.invoke(TestInvoker.java:824) at org.testng.internal.TestInvoker.invokeTestMethods(TestInvoker.java:146) at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:146) at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:128) at java.util.ArrayList.forEach(ArrayList.java:1259) at org.testng.TestRunner.privateRun(TestRunner.java:794) at org.testng.TestRunner.run(TestRunner.java:596) at org.testng.SuiteRunner.runTest(SuiteRunner.java:377) at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:371) at org.testng.SuiteRunner.privateRun(SuiteRunner.java:332) at org.testng.SuiteRunner.run(SuiteRunner.java:276) at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:53) at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:96) at org.testng.TestNG.runSuitesSequentially(TestNG.java:1212) at org.testng.TestNG.runSuitesLocally(TestNG.java:1134) at org.testng.TestNG.runSuites(TestNG.java:1063) at org.testng.TestNG.run(TestNG.java:1031) at org.apache.maven.surefire.testng.TestNGExecutor.run(TestNGExecutor.java:62) at org.apache.maven.surefire.testng.TestNGDirectoryTestSuite.execute(TestNGDirectoryTestSuite.java:141) at org.apache.maven.surefire.Surefire.run(Surefire.java:180) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.apache.maven.surefire.booter.SurefireBooter.runSuitesInProcess(SurefireBooter.java:350) at org.apache.maven.surefire.booter.SurefireBooter.main(SurefireBooter.java:1021) Caused by: com.mysql.cj.exceptions.CJCommunicationsException: Communications link failure The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server. at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) at java.lang.reflect.Constructor.newInstance(Constructor.java:423) at com.mysql.cj.exceptions.ExceptionFactory.createException(ExceptionFactory.java:61) at com.mysql.cj.exceptions.ExceptionFactory.createException(ExceptionFactory.java:105) at com.mysql.cj.exceptions.ExceptionFactory.createException(ExceptionFactory.java:151) at com.mysql.cj.exceptions.ExceptionFactory.createCommunicationsException(ExceptionFactory.java:167) at com.mysql.cj.protocol.a.NativeSocketConnection.connect(NativeSocketConnection.java:89) at com.mysql.cj.NativeSession.connect(NativeSession.java:120) at com.mysql.cj.jdbc.ConnectionImpl.connectOneTryOnly(ConnectionImpl.java:949) at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:819) ... 62 more Caused by: java.net.ConnectException: Connection timed out (Connection timed out) at java.net.PlainSocketImpl.socketConnect(Native Method) at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:476) at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:218) at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:200) at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:394) at java.net.Socket.connect(Socket.java:606) at com.mysql.cj.protocol.StandardSocketFactory.connect(StandardSocketFactory.java:156) at com.mysql.cj.protocol.a.NativeSocketConnection.connect(NativeSocketConnection.java:63) ... 65 more
相关代码
public String getLastLinkQRCode() { String lastLinkQrCode = ""; Connection myConnection = null; try { if(PropertiesReader.getEnvironementName().equalsIgnoreCase("test")) { myConnection = DriverManager.getConnection(PropertiesReader.getBmwTestDatabaseUrl_PPV(), PropertiesReader.getBmwTestDatabaseLogin_PPV(), PropertiesReader.getBmwTestDatabasePassword_PPV()); } else { myConnection = DriverManager.getConnection(PropertiesReader.getBmwProdDatabaseUrl(), PropertiesReader.getBmwProdDatabaseLogin(), PropertiesReader.getBmwProdDatabasePassword()); } Statement myStatement = myConnection.createStatement(); ResultSet myResult = myStatement.executeQueriy("select link from t1 where mail ='x1x1x1x1@gmail.com' ORDER BY send_date DESC LIMIT 1"); while(myResult.next()) { lastLink= myResult.getString("link"); } myConnection.close(); } catch (SQLException e) { e.printStackTrace(); } System.out.println(lastLinkQrCode); return lastLink; }
解决方案
从错误栈里的java.net.ConnectException: Connection timed out可以明确,这是网络层面的连接超时问题,本地能连但Jenkins连不上,核心排查方向如下:
1. AWS安全组配置检查
- 确认AWS MySQL实例的安全组是否允许Jenkins服务器的公网IP(或内网IP,如果同属一个VPC)访问MySQL端口(默认3306,自定义端口需对应调整)。本地能正常连接说明你的IP在安全组白名单中,但Jenkins服务器的IP大概率未被添加,需要补充到安全组的入站规则里。
2. Jenkins服务器网络连通性验证
- 在Jenkins服务器上执行
telnet <数据库IP> <端口>或nc -zv <数据库IP> <端口>,确认端口是否能打通。如果不通,说明网络链路存在问题,比如公司防火墙拦截、VPC路由表配置错误、跨VPC peering未生效等。 - 若Jenkins部署在公司内网,可能需要配置代理或VPN才能访问AWS云资源,而本地已经配置了这些,但Jenkins环境未同步配置。
3. 数据库连接参数二次核对
- 虽然你已确认URL和端口,但需检查Jenkins环境加载的配置文件中,数据库URL是否正确(比如是否误用了内网地址而Jenkins处于外网环境,或者反过来),确保没有拼写错误,比如
jdbc:mysql://后的地址、端口号是否准确。
4. 代码细节修复(顺带优化)
- 代码存在笔误:
executeQueriy应为executeQuery,本地运行时可能未触发到该问题,但建议立即修正避免后续异常。 - 资源释放不规范:
Statement和ResultSet未关闭,推荐使用try-with-resources语法自动释放资源,避免连接泄漏,尤其在Jenkins这种持续运行的环境中:
public String getLastLinkQRCode() { String lastLink = ""; String dbUrl, dbUser, dbPwd; if(PropertiesReader.getEnvironementName().equalsIgnoreCase("test")) { dbUrl = PropertiesReader.getBmwTestDatabaseUrl_PPV(); dbUser = PropertiesReader.getBmwTestDatabaseLogin_PPV(); dbPwd = PropertiesReader.getBmwTestDatabasePassword_PPV(); } else { dbUrl = PropertiesReader.getBmwProdDatabaseUrl(); dbUser = PropertiesReader.getBmwProdDatabaseLogin(); dbPwd = PropertiesReader.getBmwProdDatabasePassword(); } try (Connection myConnection = DriverManager.getConnection(dbUrl, dbUser, dbPwd); Statement myStatement = myConnection.createStatement(); ResultSet myResult = myStatement.executeQuery("select link from t1 where mail ='x1x1x1x1@gmail.com' ORDER BY send_date DESC LIMIT 1")) { if(myResult.next()) { lastLink = myResult.getString("link"); } } catch (SQLException e) { e.printStackTrace(); } System.out.println(lastLink); return lastLink; }
内容的提问来源于stack exchange,提问作者Kim Kelly
相关产品推荐
相关产品推荐

