Spring 引导休息服务在正常工作数小时后引发 JPA 连接错误
Spring Boot Rest Service raising JPA connection error after hours of working correctly
我在 linux ubuntu 服务器上的 Tomcat 7 容器上将 Spring Boot Rest 服务部署为 war。
其余服务仅公开一个 /detections 端点,其中 returns JSON 表示 mysql 数据库中 table 的最后 N 条记录(运行在同一台服务器上)。我的控制器通过 Spring Data JPA 访问数据库。
将服务部署到 tomcat 后,服务似乎运行良好,并且持续了几个小时。但是,如果我在第二天早上检查,该服务似乎由于 JPA 异常而崩溃(见下文)。如果我 sudo service tomcat7 restart,该服务将再次开始正常工作,而这又只会持续几个小时。
这是 logback 输出,我试图在其中分离出最相关的行
*(webapp working correctly for a number of hours)*
.
.
.
155. 2016-05-04 14:07:00,553 INFO [http-bio-8080-exec-26] o.h.t.h.SchemaUpdate [SchemaUpdate.java:218] HHH000102: Fetching database metadata
156. 2016-05-04 14:07:04,581 ERROR [http-bio-8080-exec-26] o.h.t.h.SchemaUpdate [SchemaUpdate.java:226] HHH000319: Could not get database metadata
157. com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: Could not create connection to database server. Attempted reconnect 3 times. Giving up.
.
.
381. Caused by: java.sql.SQLException: Access denied for user 'myuser'@'localhost' (using password: YES)
.
.
.
391. 2016-05-04 14:07:04,588 ERROR [http-bio-8080-exec-26] o.h.t.h.SchemaUpdate [SchemaUpdate.java:272] HHH000299: Could not complete schema update
392. com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: Could not create connection to database server. Attempted reconnect 3 times. Giving up.
.
.
.
615. 2016-05-04 14:07:06,854 INFO [http-bio-8080-exec-26] o.s.b.a.s.AuthenticationManagerConfiguration [AuthenticationManagerConfiguration.java:170]
616.
617. Using default security password: 161b39f3-9d55-453f-b9e9-310244de426b
.
.
.
851. 2016-05-04 14:07:24,649 WARN [http-bio-8080-exec-26] o.h.j.i.EntityManagerFactoryRegistry [EntityManagerFactoryRegistry.java:80] HHH000436: Entity manager factory name (default) is already registered. If entity manager will be clustered or passivated, specify a unique value for property 'hibernate.ejb.entitymanager_factory_name'
.
.
.
902. 2016-05-04 14:37:55,360 INFO [http-bio-8080-exec-28] o.s.w.s.DispatcherServlet [FrameworkServlet.java:485] FrameworkServlet 'dispatcherServlet': initialization started
903. 2016-05-04 14:37:55,377 INFO [http-bio-8080-exec-28] o.s.w.s.DispatcherServlet [FrameworkServlet.java:504] FrameworkServlet 'dispatcherServlet': initialization completed in 17 ms
904. 2016-05-04 14:37:59,849 WARN [http-bio-8080-exec-28] o.h.e.j.s.SqlExceptionHelper [SqlExceptionHelper.java:144] SQL Error: 0, SQLState: 08001
905. 2016-05-04 14:37:59,849 ERROR [http-bio-8080-exec-28] o.h.e.j.s.SqlExceptionHelper [SqlExceptionHelper.java:146] Could not create connection to database server. Attempted reconnect 3 times. Giving up.
906. 2016-05-04 14:38:00,297 ERROR [http-bio-8080-exec-28] o.s.b.c.w.ErrorPageFilter [ErrorPageFilter.java:177] Forwarding to error page from request [/detections] due to exception [Could not open JPA EntityManager for transaction; nested exception is javax.persistence.PersistenceException: org.hibernate.exception.JDBCConnectionException: Could not open connection]
907. org.springframework.transaction.CannotCreateTransactionException: Could not open JPA EntityManager for transaction; nested exception is javax.persistence.PersistenceException: org.hibernate.exception.JDBCConnectionException: Could not open connection
.
.
.
*(similar error patterns repeat)*
这是我的 application.properties 文件(当然,mydatabase、myuser 和 mypassword 替换了实际的连接数据):
spring.jpa.database-platform=org.hibernate.dialect.MySQL5InnoDBDialect
spring.datasource.driverClassName=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/mydatabase?autoReconnect=true
spring.datasource.username=myuser
spring.datasource.password=mypassoword
spring.jpa.hibernate.ddl-auto=update
spring.data.jpa.repositories.enabled=true
spring.jpa.show-sql=true
在 mysql 中,我将对 mydatabase 的所有访问权限授予用户 'myuser'@'localhost' 实际上我可以声明问题与错误的凭据无关,因为正如我提到的该服务实际上设法连接了好几个小时。在试图解决问题的第二阶段添加了 ?autoReconnect=true,但没有任何改变。
这是我的 REST 控制器的(非常简单的)代码(同样,只有相关部分)。
@RestController
@Transactional
public class DetectionController {
@Autowired
public DetectionRepository detectionRepository;
.
.
.
@RequestMapping(value="/detections", method=RequestMethod.GET )
public Object getDetectionsLimit( @RequestParam(required=false, defaultValue="0") int limit )
{
try {
List<Detection> detections = detectionRepository.findTop5ByOrderByTimestampDesc();
return detections;
} catch (final Exception e ) {
return new Object() {
public String error = e.getMessage();
};
}
}
.
.
.
}
在此先感谢您的帮助
我遇到了类似的问题,添加下面提到的属性解决了我的问题,您可以试一试。
spring.datasource.test-on-borrow= true
spring.datasource.validation-query= SELECT 1
我在 linux ubuntu 服务器上的 Tomcat 7 容器上将 Spring Boot Rest 服务部署为 war。
其余服务仅公开一个 /detections 端点,其中 returns JSON 表示 mysql 数据库中 table 的最后 N 条记录(运行在同一台服务器上)。我的控制器通过 Spring Data JPA 访问数据库。
将服务部署到 tomcat 后,服务似乎运行良好,并且持续了几个小时。但是,如果我在第二天早上检查,该服务似乎由于 JPA 异常而崩溃(见下文)。如果我 sudo service tomcat7 restart,该服务将再次开始正常工作,而这又只会持续几个小时。
这是 logback 输出,我试图在其中分离出最相关的行
*(webapp working correctly for a number of hours)*
.
.
.
155. 2016-05-04 14:07:00,553 INFO [http-bio-8080-exec-26] o.h.t.h.SchemaUpdate [SchemaUpdate.java:218] HHH000102: Fetching database metadata
156. 2016-05-04 14:07:04,581 ERROR [http-bio-8080-exec-26] o.h.t.h.SchemaUpdate [SchemaUpdate.java:226] HHH000319: Could not get database metadata
157. com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: Could not create connection to database server. Attempted reconnect 3 times. Giving up.
.
.
381. Caused by: java.sql.SQLException: Access denied for user 'myuser'@'localhost' (using password: YES)
.
.
.
391. 2016-05-04 14:07:04,588 ERROR [http-bio-8080-exec-26] o.h.t.h.SchemaUpdate [SchemaUpdate.java:272] HHH000299: Could not complete schema update
392. com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: Could not create connection to database server. Attempted reconnect 3 times. Giving up.
.
.
.
615. 2016-05-04 14:07:06,854 INFO [http-bio-8080-exec-26] o.s.b.a.s.AuthenticationManagerConfiguration [AuthenticationManagerConfiguration.java:170]
616.
617. Using default security password: 161b39f3-9d55-453f-b9e9-310244de426b
.
.
.
851. 2016-05-04 14:07:24,649 WARN [http-bio-8080-exec-26] o.h.j.i.EntityManagerFactoryRegistry [EntityManagerFactoryRegistry.java:80] HHH000436: Entity manager factory name (default) is already registered. If entity manager will be clustered or passivated, specify a unique value for property 'hibernate.ejb.entitymanager_factory_name'
.
.
.
902. 2016-05-04 14:37:55,360 INFO [http-bio-8080-exec-28] o.s.w.s.DispatcherServlet [FrameworkServlet.java:485] FrameworkServlet 'dispatcherServlet': initialization started
903. 2016-05-04 14:37:55,377 INFO [http-bio-8080-exec-28] o.s.w.s.DispatcherServlet [FrameworkServlet.java:504] FrameworkServlet 'dispatcherServlet': initialization completed in 17 ms
904. 2016-05-04 14:37:59,849 WARN [http-bio-8080-exec-28] o.h.e.j.s.SqlExceptionHelper [SqlExceptionHelper.java:144] SQL Error: 0, SQLState: 08001
905. 2016-05-04 14:37:59,849 ERROR [http-bio-8080-exec-28] o.h.e.j.s.SqlExceptionHelper [SqlExceptionHelper.java:146] Could not create connection to database server. Attempted reconnect 3 times. Giving up.
906. 2016-05-04 14:38:00,297 ERROR [http-bio-8080-exec-28] o.s.b.c.w.ErrorPageFilter [ErrorPageFilter.java:177] Forwarding to error page from request [/detections] due to exception [Could not open JPA EntityManager for transaction; nested exception is javax.persistence.PersistenceException: org.hibernate.exception.JDBCConnectionException: Could not open connection]
907. org.springframework.transaction.CannotCreateTransactionException: Could not open JPA EntityManager for transaction; nested exception is javax.persistence.PersistenceException: org.hibernate.exception.JDBCConnectionException: Could not open connection
.
.
.
*(similar error patterns repeat)*
这是我的 application.properties 文件(当然,mydatabase、myuser 和 mypassword 替换了实际的连接数据):
spring.jpa.database-platform=org.hibernate.dialect.MySQL5InnoDBDialect
spring.datasource.driverClassName=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/mydatabase?autoReconnect=true
spring.datasource.username=myuser
spring.datasource.password=mypassoword
spring.jpa.hibernate.ddl-auto=update
spring.data.jpa.repositories.enabled=true
spring.jpa.show-sql=true
在 mysql 中,我将对 mydatabase 的所有访问权限授予用户 'myuser'@'localhost' 实际上我可以声明问题与错误的凭据无关,因为正如我提到的该服务实际上设法连接了好几个小时。在试图解决问题的第二阶段添加了 ?autoReconnect=true,但没有任何改变。
这是我的 REST 控制器的(非常简单的)代码(同样,只有相关部分)。
@RestController
@Transactional
public class DetectionController {
@Autowired
public DetectionRepository detectionRepository;
.
.
.
@RequestMapping(value="/detections", method=RequestMethod.GET )
public Object getDetectionsLimit( @RequestParam(required=false, defaultValue="0") int limit )
{
try {
List<Detection> detections = detectionRepository.findTop5ByOrderByTimestampDesc();
return detections;
} catch (final Exception e ) {
return new Object() {
public String error = e.getMessage();
};
}
}
.
.
.
}
在此先感谢您的帮助
我遇到了类似的问题,添加下面提到的属性解决了我的问题,您可以试一试。
spring.datasource.test-on-borrow= true
spring.datasource.validation-query= SELECT 1