2011-02-09 44 views
9

Chúng tôi đang nhận được một CommunicationException (từ DBCP) sau khi iding một thời gian (một vài giờ). Thông báo lỗi (trong Ngoại lệ) là ở phần cuối của câu hỏi này - nhưng tôi không thấy wait_timeout được định nghĩa trong bất kỳ tệp cấu hình nào. (Chúng ta nên tìm đâu? Một nơi nào đó nằm ngoài thư mục tomcat/conf?).Cấu hình Tomcat bằng cách sử dụng DBCP

Thứ hai, như được đề xuất bởi Ngoại lệ, nơi nào người ta đặt "Kết nối/thuộc tính kết nối J 'autoReconnect = true'"? Đây là định nghĩa tài nguyên trong tệp conf/context.xml trong thiết lập tomcat:

<Resource name="jdbc/TomcatResourceName" auth="Container" type="javax.sql.DataSource" 
      maxActive="100" maxIdle="30" maxWait="10000" 
      removeAbandoned="true" removeAbandonedTimeout="60" logAbandoned="true" 
      username="xxxx" password="yyyy" 
      driverClassName="com.mysql.jdbc.Driver" 
      url="jdbc:mysql://127.0.0.1:3306/dbname?autoReconnect=true"/> 

Thứ ba, tại sao JVM đợi cho đến khi cuộc gọi đến executeQuery() để ném ngoại lệ? Nếu kết nối đã hết thời gian, phương thức getConnection sẽ ném Ngoại lệ, phải không? Đây là phần của mã nguồn tôi đang nói về:

 try { 
       conn = getConnection (true); 
       stmt = conn.createStatement (ResultSet.TYPE_SCROLL_INSENSITIVE, 
               ResultSet.CONCUR_READ_ONLY); 
       rset = stmt.executeQuery (bQuery); 
       while (rset.next()) { 
        .... 

Cuối cùng, sau đây là một vài dòng 1 của dấu vết ngăn xếp ...

com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: The last packet successfully received from the server was 84,160,724 milliseconds ago. The last packet sent successfully to the server was 84,160,848 milliseconds ago. is longer than the server configured value of 'wait_timeout'. You should consider either expiring and/or testing connection validity before use in your application, increasing the server configured values for client timeouts, or using the Connector/J connection property 'autoReconnect=true' to avoid this problem. 
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) 
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57) 
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) 
at java.lang.reflect.Constructor.newInstance(Constructor.java:532) 
at com.mysql.jdbc.Util.handleNewInstance(Util.java:406) 
at com.mysql.jdbc.SQLError.createCommunicationsException(SQLError.java:1074) 
at com.mysql.jdbc.MysqlIO.send(MysqlIO.java:3291) 
at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1938) 
at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2107) 
at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2642) 
at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2571) 
at com.mysql.jdbc.StatementImpl.executeQuery(StatementImpl.java:1451) 
at org.apache.tomcat.dbcp.dbcp.DelegatingStatement.executeQuery(DelegatingStatement.java:208) 

Đây là những lý do một số người trong chúng ta suy nghĩ "quên dbcp, nó có thể phụ thuộc vào cấu hình IDE và ma thuật dưới mui xe mà DriverManager.getConnection (...) có thể đáng tin cậy hơn". Bất kỳ ý kiến ​​về điều đó? Cảm ơn bạn vì thông tin chi tiết của bạn, - MS

Trả lời

14

Kể từ DBCP tiếp tục quay trở lại các kết nối mysql mở cho các yêu cầu kết nối sắp tới, họ rơi nạn nhân đến MySQL Server timeout.

DBCP có một số tính năng có thể trợ giúp (có thể được sử dụng bắt đầu bằng Tomcat 5.5 IIRC).

validationQuery="SELECT 1" 
testOnBorrow="true" 

Xác thực đảm bảo rằng kết nối hợp lệ trước khi trả về kết nối với webapp thực hiện phương thức 'mượn'. Lá cờ tất nhiên, cho phép tính năng này.

Nếu hết thời gian chờ (8 giờ tôi tin) và kết nối đã chết, khi đó kết nối mới sẽ được kiểm tra (nếu không còn kết nối nữa) được cung cấp cho webapp.

cách tiếp cận có thể khác:

  1. sử dụng các testWhileIdle="true" DBCP trong cài đặt tài nguyên của bạn để kiểm tra kết nối cũng nhàn rỗi trước khi yêu cầu hiệu quả được phát hiện.

  2. Sử dụng 'connectionProperties' để cứng kết nối MySQL của bạn (ví dụ autoReconnect/autoReconnectForPools=true)

+1

Nếu tôi hiểu bạn đúng, DBCP giữ kết nối của nó trong hồ bơi của nó nhưng máy chủ mySql đã hết thời gian, vì vậy khi kết nối này được gửi đến ứng dụng, nó là một kết nối đóng. Làm cho tinh thần, nhưng đó là sự hiểu biết chính xác của tôi? Một q: Có bất kỳ điểm nào trong việc sử dụng validationQuery/testOnBorrow như bạn đã đề cập cũng như testWhileIdle và autoRecon ... trong tệp context.xml không? Họ đi vào tập tin đó, phải không? –

+0

1. Hiểu biết của bạn là chính xác. Tất cả các giải pháp tôi chỉ định là bổ sung. Thiết lập một, không ngăn cản thiết lập những người khác. Belt và niềng răng là tốt hơn ;-) Tôi muốn thực hiện tất cả 3 giải pháp. kiểm tra trong khi nhàn rỗi có nghĩa là ít thời gian chờ đợi hơn tại thời điểm 'mượn'. Cài đặt thuộc tính sẽ làm giảm các ngắt kết nối không thích hợp. Có tất cả họ đi trong phần tài nguyên của context.xml webapp của bạn (sau này triển khai bởi tomcat trong $ CATALINA_HOME/conf/Catalina/localhost/yourwebapp.xml). –

+1

autoReconnect không được khuyến nghị - http://dev.mysql.com/doc/refman/5.0/en/connector-j-reference-configuration-properties.html – OrangeDog

0

DBCP không có nghĩa là để sử dụng trong sản xuất, thậm chí các tác giả nói rằng (xem bản trình bày này: http://www.infoq.com/presentations/Tuning-Tomcat-Mark-Thomas).

tôi khuyên bạn nên nhìn vào C3P0: http://www.mchange.com/projects/c3p0/index.html

+1

Đây không phải là * that true *. Có những chủ đề về sự so sánh của bạn và sự khác biệt không phải là hiển nhiên hay rõ ràng. http://stackoverflow.com/questions/520585/connection-pooling-options-with-jdbc-dbcp-vs-c3p0 và http://stackoverflow.com/questions/490288/is-dbcp-apache-commons-database- kết nối-pooling-still-related – Alfabravo

+0

Bài trình bày đó đề cập đến thời điểm sử dụng BIO và NIO, tùy thuộc vào độ dài phiên và các yêu cầu đồng thời (Chúng tôi thấp về cả hai vấn đề). Bất kỳ con trỏ nào về lý do tại sao nó không nên được sử dụng trong sản xuất?Chỉ cần cân nhắc tần suất kết nối cao? Btw, tôi đã xem xét C3P0, trông rất thú vị, chúng tôi có thể thử nó ra nếu DBCP giữ cho chúng ta vấn đề. Cảm ơn bạn đã thông tin, - MS. –

+0

Nếu tôi nhớ chính xác có một điểm trong bài thuyết trình này khi anh chàng nói "DBCP không bao giờ có nghĩa là để sử dụng trong sản xuất" hoặc một cái gì đó như thế. Vâng, đó là một cây kim trong đống cỏ khô, nhưng tôi không thể quên điều đó sau khi tôi đã nghe nó. – Spajus