This is the second day of my participation in Gwen Challenge

This article is participating in “Java Theme Month – Java Development in Action”, see the activity link for details

preface

Recently, I used a framework of the company. After being deployed to the site, the site operation and maintenance started to maintain the site data. In the process of continuous operation, the system crashed. So began the search. Record it here.

Trying to start

The first error reported in the background is this.

exception=org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.exceptions.PersistenceException:
### Error querying database. Cause: org.springframework.jdbc.CannotGetJdbcConnectionException: Could not get JDBC Connection; nested exception is com.alibaba.druid.pool.GetConnectionTimeoutException: wait millis 60000, active 10, maxActive 10
Copy the code

The number of first response maxActive Settings is too small. So it’s 100. Restart and manipulate large amounts of data again. Found that after a period of time 100 also full.

Now the problem is not simple. It seems that there is code using the program after the connection, not released.

The next step is to determine whether the cause is releasable or not.

Druid connection pool used in the project. Druid connection pooling comes with graphical monitoring tools. Start the configuration in your project and start the Druid connection pool.

import com.alibaba.druid.support.http.StatViewServlet; import com.alibaba.druid.support.http.WebStatFilter; import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.boot.web.servlet.ServletRegistrationBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class DruidConfig { @Bean public ServletRegistrationBean statViewServlet(){ ServletRegistrationBean srb = new ServletRegistrationBean(new StatViewServlet(),"/druid/*"); // Set the console admin user srb.addInitParameter("loginUsername","root"); srb.addInitParameter("loginPassword","root"); Srb. addInitParameter("resetEnable","false"); return srb; } public FilterRegistrationBean druidStatFilter() {public FilterRegistrationBean druidStatFilter() { FilterRegistrationBean bean = new FilterRegistrationBean(new WebStatFilter()); // Add filter rules. Bean.addurlpatterns ("/*"); / / add don't need to ignore the format of the information. Beans. AddInitParameter (" exclusions ", "*. Js, *. GIF, * JPG, *. PNG, *. CSS, *. Ico, / druid / *"); return bean; }}Copy the code

After restarting, access: localhost:8081/druid. This path may be suspected if I am managed through the gateway microservices framework, do I need to access through the gateway forward? In fact, it is not necessary, through the gateway can also jump to the address of direct access.

The login page is displayed.

Enter the user name and password you just configured in the code to enter successfully.

The key metric is here. If the connection pool is open and closed normally, the two values should be equal.

Now look at the number of active connections

Is 0, which is normal because no operation has been performed.

The next step is to replay the previous action and lock down the specific action. Repeat the previous onsite o&M operations.

By constantly clicking the function and narrowing the function range, we finally found that as long as we click the left tree, the logic opening connection and logic closing times will be inconsistent.

The number of active connections is between the two. After a few minutes, the same thing happened. So there is a problem with the code, the connection should not be released. So with all that code, how do you find the location of specific code?

Next, configure druid’s abandon policy. With abandon, you can force a database connection to be reclaimed. When active connections are reclaimed, the stack information is printed, which tells you where the SQL code was not freed.

The configuration is as follows:

spring:
  datasource:
    druid:
      remove-abandoned: true
      remove-abandoned-timeout: 30
      log-abandoned: true
Copy the code

Restart the project, at which point durID’s function to monitor the number of active connections will see the code information.

We click on the following location:

The stack above pops up. Where you blur out the details of the code, it’s marked up. The developer goes to the class in response to find the corresponding code to look at.

After looking at the code, we found that there was a problem with the connection release of the code. Is a self-encapsulated SQL query class. After changing the writing method of mybatis, the problem is solved.