2016-04-13 45 views
11

Tôi đang sử dụng hồ bơi kết nối JDBC Tomcat cùng với khởi động Spring, mẫu JDBC và SQL Server. Tôi cần phải biết những gì đang đi bên trong hồ bơi kết nối trong khi ứng dụng đang chờ kết nối cơ sở dữ liệu. Chẳng hạn như ....Làm thế nào để Gỡ lỗi/Ghi nhật ký kết nối JDBC của Tomcat Connection Pool?

  • Không kết nối hoạt động
  • Không kết nối nhàn rỗi
  • Không kết nối bị chặn, thông tin bổ sung tại sao kết nối này bị chặn
  • Không kết nối sẵn
  • và. ..

Có cách nào để có được những thông tin này bằng cách gỡ lỗi hoặc sử dụng khung ghi nhật ký như log4j không?

Bất kỳ ý tưởng nào cũng sẽ được đánh giá cao.

+1

một số giá trị này được đăng ký là thuộc tính JMX. bạn có thể theo dõi chúng bằng cách sử dụng http://wiki.apache.org/tomcat/FAQ/Monitoring Tomcat JDBC-POOL được đăng ký là bean JMX sử dụng thuộc tính jmxEnabled (mặc định là đúng). bạn có thể nhận được các giá trị khác bằng cách sử dụng jdbcInterceptors – Nitin

+0

Cảm ơn bạn đã gợi ý Nitin –

Trả lời

14

Sau nhiều nghiên cứu, tôi có thể tìm 3 cách để ghi lại & hồ bơi kết nối cơ sở dữ liệu giám sát.

https://tomcat.apache.org/tomcat-8.0-doc/jdbc-pool.html

  1. Giám sát sử dụng Xuân Boottính.

  2. Giám sát sử dụng JMX (Extensions quản lý Java) (như @nitin gợi ý)

  3. Giám sát sử dụng Xuânkhía cạnh.

Cách thứ nhất: Giám sát sử dụng thuộc tính Khởi động mùa xuân.

Tôi tìm thấy bên dưới Thuộc tính khởi động mùa xuân sẽ hữu ích khi đăng nhập & hồ bơi kết nối cơ sở dữ liệu giám sát.

Các thuộc tính này (và một số chi tiết khác nữa) là không được ghi lại. Vui lòng tham khảo vấn đề github dưới đây để biết thêm chi tiết. https://github.com/spring-projects/spring-boot/issues/1829

#Maximum no.of active connections 
spring.datasource.max-active=10 

#Log the stack trace of abandoned connection 
spring.datasource.log-abandoned=true 

#Remove abandoned connection,So, new connection will be created and made available to threads which are waiting for DB connection 
spring.datasource.remove-abandoned=true 

#If any connection is not used for 10 seconds, consider that connection as "abandoned" 
spring.datasource.remove-abandoned-timeout=10 

#Number of ms to wait before throwing an exception if no connection is available. 
spring.datasource.max-wait=1000 

Danh sách này chứa nhiều thuộc tính có liên quan đến nguồn dữ liệu chỉ (lấy từ liên kết ở trên)

spring.datasource.abandon-when-percentage-full 
spring.datasource.access-to-underlying-connection-allowed 
spring.datasource.alternate-username-allowed 
spring.datasource.auto-commit 
spring.datasource.catalog 
spring.datasource.commit-on-return 
spring.datasource.connection-customizer 
spring.datasource.connection-customizer-class-name 
spring.datasource.connection-init-sql 
spring.datasource.connection-init-sqls 
spring.datasource.connection-properties 
spring.datasource.connection-test-query 
spring.datasource.connection-timeout 
spring.datasource.data-source 
spring.datasource.data-source-class-name 
spring.datasource.data-source-j-n-d-i 
spring.datasource.data-source-properties 
spring.datasource.db-properties 
spring.datasource.default-auto-commit 
spring.datasource.default-catalog 
spring.datasource.default-read-only 
spring.datasource.default-transaction-isolation 
spring.datasource.driver-class-loader 
spring.datasource.fair-queue 
spring.datasource.idle-timeout 
spring.datasource.ignore-exception-on-pre-load 
spring.datasource.init-s-q-l 
spring.datasource.initialization-fail-fast 
spring.datasource.isolate-internal-queries 
spring.datasource.jdbc-interceptors 
spring.datasource.jdbc-url 
spring.datasource.jdbc4-connection-test 
spring.datasource.leak-detection-threshold 
spring.datasource.log-abandoned 
spring.datasource.log-validation-errors 
spring.datasource.log-writer 
spring.datasource.login-timeout 
spring.datasource.max-age 
spring.datasource.max-lifetime 
spring.datasource.max-open-prepared-statements 
spring.datasource.maximum-pool-size 
spring.datasource.metrics-tracker-class-name 
spring.datasource.minimum-idle 
spring.datasource.num-tests-per-eviction-run 
spring.datasource.pool-name 
spring.datasource.pool-prepared-statements 
spring.datasource.pool-properties 
spring.datasource.propagate-interrupt-state 
spring.datasource.read-only 
spring.datasource.record-metrics 
spring.datasource.register-mbeans 
spring.datasource.remove-abandoned 
spring.datasource.remove-abandoned-timeout 
spring.datasource.rollback-on-return 
spring.datasource.suspect-timeout 
spring.datasource.test-on-connect 
spring.datasource.thread-factory 
spring.datasource.transaction-isolation 
spring.datasource.use-disposable-connection-facade 
spring.datasource.use-equals 
spring.datasource.use-lock 
spring.datasource.validation-interval 
spring.datasource.validation-query-timeout 
spring.datasource.validator 
spring.datasource.validator-class-name 
spring.datasource.xa 
spring.datasource.xa.data-source-class-name 
spring.datasource.xa.properties 

2 Way:. Giám sát sử dụng JMX (Extensions quản lý Java)

Hồ bơi JDBC Tomcat cung cấp MBean cụ thể là ConnectionPoolMBean.

https://tomcat.apache.org/tomcat-7.0-doc/api/org/apache/tomcat/jdbc/pool/jmx/ConnectionPoolMBean.html

Đăng ký khởi động Spring JMX tự động.Vì vậy, không cần phải đăng ký/xuất MBean này vào máy chủ MBean. Chỉ cần mở JConsole đang đến với JDK, Để mở, trong Windows-> Command prompt -> jconsole, thats it. Tham khảo ảnh chụp màn hình bên dưới để biết thêm thông tin.

enter image description here

enter image description here

MBean này cũng thông báo khi sự kết nối bị hủy, kết nối thất bại, khi một truy vấn được dành thời gian dài vv Hãy tham khảo hình dưới đây.

enter image description here

Way 3: Giám sát sử dụng các khía cạnh mùa xuân (chỉ dành cho phát triển môi trường/QA).

Tôi sử dụng khía cạnh này để đăng nhập Hồ bơi kết nối TomcatJdbc.

Tôi đã tạo một Spring Aspect sẽ chặn mọi cuộc gọi cơ sở dữ liệu.Điều này sẽ chắc chắn sẽ ảnh hưởng đến hiệu suất.

Vì vậy, hãy sử dụng khía cạnh này trong môi trường phát triển/QA, nhận xét phương pháp này khi không bắt buộc (ví dụ: trong quá trình triển khai sản xuất).

@Before("execution(* com.test.app.db.dao.*.*(..))") 
    public void logBeforeConnection(JoinPoint jp) throws Throwable { 
     String methodName = ""; 
     methodName += jp.getTarget().getClass().getName(); 
     methodName += ":"; 
     methodName += jp.getSignature().getName(); 
     logger.info("before method call : " + methodName + " : number of connections in use by the application (active) : "+ tomcatJdbcPoolDataSource.getNumActive()); 
     logger.info("before method call : " + methodName + " : the number of established but idle connections : "+ tomcatJdbcPoolDataSource.getNumIdle()); 
     logger.info("before method call : " + methodName + " : number of threads waiting for a connection : "+ tomcatJdbcPoolDataSource.getWaitCount()); 
    } 


@After("execution(* com.test.app.db.dao.*.*(..)) ") 
public void logAfterConnection(JoinPoint jp) throws Throwable { 
    String methodName = ""; 
    methodName += jp.getTarget().getClass().getName(); 
    methodName += ":"; 
    methodName += jp.getSignature().getName(); 
    logger.info("after method call : " + methodName + " : number of connections in use by the application (active) : "+ tomcatJdbcPoolDataSource.getNumActive()); 
    logger.info("after method call : " + methodName + " : the number of established but idle connections : "+ tomcatJdbcPoolDataSource.getNumIdle()); 
    logger.info("after method call : " + methodName + " : number of threads waiting for a connection : "+ tomcatJdbcPoolDataSource.getWaitCount()); 
    //tomcatJdbcPoolDataSource.checkAbandoned(); 
} 

Bây giờ, bạn có thể dễ dàng xác định cuộc gọi cơ sở dữ liệu cụ thể tạo rò rỉ kết nối trong ứng dụng của bạn.

+0

Tôi không thể tìm thấy thông tin về thuộc tính 'spring.datasource.log-writer' nói riêng. Tôi sẽ đánh giá cao nếu có ai có thể tìm thấy cú pháp cho điều đó. Tôi giả định rằng chúng ta đang nói với nguồn dữ liệu lớp mà nó sẽ sử dụng để viết nhật ký. – Chris

+1

Lưu ý rằng, để lộ MBean, bạn cần thêm 'spring.datasource.jmx-enabled = true' vào tệp' application.properties' của bạn. –

1

Cảm ơn @Sundararaj Govindasamy vì câu trả lời tuyệt vời. Dựa trên nó, tôi đã tạo một thành phần trong ứng dụng khởi động mùa xuân của mình để gỡ lỗi thông tin Cơ sở dữ liệu của tôi.

import org.apache.tomcat.jdbc.pool.DataSource; 
import org.aspectj.lang.JoinPoint; 
import org.aspectj.lang.annotation.After; 
import org.aspectj.lang.annotation.Aspect; 
import org.aspectj.lang.annotation.Before; 
import org.slf4j.Logger; 
import org.slf4j.LoggerFactory; 
import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.stereotype.Component; 

@Aspect 
@Component 
public class DataSourceAspectLogger { 

    protected final Logger logger = LoggerFactory.getLogger(this.getClass()); 

    @Autowired 
    private DataSource ds; 

    @Before("execution(* br.com.foo.core.repository.*.*(..))") 
    public void logBeforeConnection(JoinPoint jp) throws Throwable { 
     logDataSourceInfos("Before", jp); 
    } 

    @After("execution(* br.com.foo.core.repository.*.*(..)) ") 
    public void logAfterConnection(JoinPoint jp) throws Throwable { 
     logDataSourceInfos("After", jp); 
    } 

    public void logDataSourceInfos(final String time, final JoinPoint jp) { 
     final String method = String.format("%s:%s", jp.getTarget().getClass().getName(), jp.getSignature().getName()); 
     logger.info(String.format("%s %s: number of connections in use by the application (active): %d.", time, method, ds.getNumActive())); 
     logger.info(String.format("%s %s: the number of established but idle connections: %d.", time, method, ds.getNumIdle())); 
     logger.info(String.format("%s %s: number of threads waiting for a connection: %d.", time, method, ds.getWaitCount())); 
    } 
} 
Các vấn đề liên quan