2017-05-06 20 views
0

私は、HikariCP jdbc接続プールを使用して実行中のPlayアプリケーションを持っています。プレイフレームワーク:DB接続プールシャットダウン

アプリケーションはしばらくは正常に動作しますが、短時間の間接続プールがシャットダウンし、アプリケーションを使用できなくなります。

SBTのビルド:

name := "virtual-betting" 
version := "1.0" 

lazy val root = (project in file(".")).enablePlugins(PlayJava).settings(javacOptions ++= Seq("-source", "1.8", "-target", "1.8")) 

scalaVersion := "2.11.8" 

libraryDependencies ++= Seq(
    javaJdbc, 
    javaJpa, 
    javaJpa.exclude("org.hibernate.javax.persistence", "hibernate-jpa-2.1-api"), 
    "org.hibernate" % "hibernate-core" % "5.1.0.Final", 
    "org.hibernate" % "hibernate-entitymanager" % "5.1.0.Final", 
    "com.typesafe.play" % "play-java-jpa_2.11" % "2.5.3", 
    "org.springframework" % "spring-context" % "4.2.4.RELEASE", 
    "org.webjars" % "bootstrap" % "3.3.4", 
    "mysql" % "mysql-connector-java" % "5.1.42", 
    cache, 
    javaWs, 
    "org.jsoup" % "jsoup" % "1.7.2", 
    "org.apache.commons" % "commons-email" % "1.4", 
    "org.apache.cxf" % "cxf-rt-rs-client" % "3.1.6", 
    "com.google.code.gson" % "gson" % "2.7", 
    "com.squareup.okhttp3" % "okhttp" % "3.4.1" 
) 

fork in run := false 


fork in run := true 

application.conf:

## Database Connection Pool 
# https://www.playframework.com/documentation/latest/SettingsJDBC 
# ~~~~~ 
# Play doesn't require a JDBC database to run, but you can easily enable one. 
# 
# libraryDependencies += jdbc 
# 

play.db { 
    # The combination of these two settings results in "db.default" as the 
    # default JDBC pool: 
    config = "db" 
    default = "default" 

    pool = "hikaricp" 
    # Play uses HikariCP as the default connection pool. You can override 
    # settings by changing the prototype: 

    prototype { 
    pool = "hikaricp" 

    # Sets a fixed JDBC connection pool size of 50 
    hikaricp.minimumIdle = 0 
    hikaricp.maximumPoolSize = 30 
    hikaricp.connectionTimeout = 30000 
    hikaricp.idleTimeout = 600000 
    hikaricp.maxLifetime = 1800000 
    hikaricp.leakDetectionThreshold = 5000 
    hikaricp.connectionTestQuery = "SELECT 1" 
    hikaricp.readOnly = false 

    hikari.dataSourceClassName = com.mysql.jdbc.jdbc2.optional.MysqlDataSource 
    # The database url 
    #url = "jdbc:mysql://localhost:3306/madduxsp_sportsbook?autoReconnect=true&useUnicode=true&characterEncoding=UTF-8" 

    registerMBeans = true 
    poolName = "sportsbook_pool" 
    } 
} 

db.default.driver=com.mysql.jdbc.Driver 
db.default.url="jdbc:mysql://localhost:3306/madduxsp_sportsbook_new?autoReconnect=true&useUnicode=true&characterEncoding=UTF-8" 
db.default.username=root 
db.default.password=mypassword 
db.default.jndiName=DefaultDS 
jpa.default=defaultPersistenceUnit 

application.secret="mysecret" 

spring.context.location=application-context.xml 

それが原因非アクティブにシャットダウンされた場合には、私は、それが動作しますが、生きているDB接続を維持するためにいくつかのコードを書いています。

マイDbKeepAliveService:この除き

package services; 

import play.Logger; 
import play.db.jpa.JPAApi; 
import util.DbKeepAliveTask; 

import javax.inject.Inject; 
import javax.inject.Singleton; 
import java.util.Timer; 

@Singleton 
public class DbKeepAliveService { 

    private final JPAApi jpa; 

    @Inject 
    public DbKeepAliveService(JPAApi jpa) { 
     this.jpa = jpa; 

     DbKeepAliveTask dbKeepAliveTask = new DbKeepAliveTask(jpa); 
     Logger.info("Application has started"); 

     Timer timer = new Timer("dbKeepAlive", true); 
     timer.schedule(dbKeepAliveTask, 0, 1200000); 
    } 
} 

は動作しません。ここに私のログは、次のとおりです。

2017-05-06 06:12:15,010 [INFO] from application in dbKeepAlive - Keeping database connection alive... 
2017-05-06 06:32:15,010 [INFO] from application in dbKeepAlive - Keeping database connection alive... 
2017-05-06 06:52:15,010 [INFO] from application in dbKeepAlive - Keeping database connection alive... 
2017-05-06 06:58:35,894 [INFO] from application in Thread-8 - Application shutdown... 
2017-05-06 06:58:36,054 [INFO] from application in Thread-8 - Shutting down connection pool. 

誰もが、それはDB接続プールをシャットダウンし続ける理由を任意のアイデアを持っていますか?私はそれが私の構成と関係があると思っていますが、確かに確信が持てません。

私はプロダクションモードでアプリケーションを実行していないこともありますが、秘密を設定しています。 conf/production.confファイル内play.crypto.secretプロパティセットで

./bin/virtual-betting -Dconfig.file=conf/production.conf -Dplay.crypto.secret="mysecret" & 

は、私は、次のコマンドを使用してアプリケーションを実行します。

これは長らく見てきましたので、大変お手伝いしています!

答えて

0

私の問題が何であったのかが分かりました。それは本当に本当に馬鹿だった。

nohupコマンドでアプリを起動していませんでした。結果として、アプリケーションはSIGTERMメッセージでOSによって終了されていました。

だから、基本的には...>ヌル

ライブ

と学びをdevのための出力うち配管とnohupを

全く私のアプリとは何の関係もなかったです。

0

あなたは30の接続プールのサイズが十分か良くない場合もチェックしますかHikariCP

hikaricp.minimumIdle = 0 

HikariCP reference

でデフォルトに設定することを推奨してminimumIdle設定を削除したい場合があります。

+0

ありがとうございます。@ジャヤントこれまで非常にイライラしたプロセスでしたが、私は言わなければなりません。私は両方を見てみましょう - ありがとう! –

+0

残念ながら、これは問題ではないようです。私は今朝それを見に来て、それは再び失敗しました。 –

2

ログを見ると、データベース接続プールがシャットダウンする理由は、アプリケーション(再生)がシャットダウンしたためです。 Play documentationで述べたように

あなたはstartコマンドを実行すると、フォークに新しいJVMを再生すると、デフォルトネッティーHTTPサーバーを実行します。標準出力ストリームはPlayコンソールにリダイレクトされ、そのステータスを監視することができます。

サーバのプロセスIDがブートストラップ時に表示され、RUNNING_PIDファイルに書き込まれます。実行中のPlayサーバーを強制終了するには、アプリケーションを適切にシャットダウンするプロセスにSIGTERMを送信すれば十分です。

Ctrl + Dと入力すると、Playコンソールは終了しますが、作成されたサーバープロセスはバックグラウンドで実行され続けます。フォークされたJVMの標準出力ストリームは閉じられ、logs/application.logファイルからログを読み取ることができます。

したがって、それはプロセスのいずれかが、Playアプリケーションがplay runの代わりplay startで開始されたと誰かがコンソールでCtrl + Dを使用したり、おそらくサーバがあるため、プロセスを強制終了され、SIGTERMシグナルを受信して​​いる可能性がありますメモリが不足していることやOOM killerを参照してください、あなたのアプリケーションのメモリリークを示していてもいなくてもよい:

を必死にメモリ不足の条件下では、アウトオブメモリ(OOM)キラーでのキックとは、殺すためにプロセスを選びます時間とともに進化してきた一連の発見的手法を使用しています。

アプリケーションのプロファイルを作成し、サーバーのメモリを監視することをお勧めします(サーバーログを調べて、カーネルがプロセスを強制終了したかどうかを確認することもできます)。

HikariCPModuleを拡張してcloseメソッドをオーバーライドできる場合は、現在のスレッドのstacktraceを出力するロガー呼び出しを追加して、実際にcloseを呼び出すものを確認します。シャットダウンフックか何か他のもの。

override def close(dataSource: DataSource) = { 
    Logger.info("Shutting down connection pool.") 
    Thread.dumpStack() 
    dataSource match { 
     case ds: HikariDataSource => ds.close() 
     case _ => sys.error("Unable to close data source: not a HikariDataSource") 
    } 

「com.zaxxer.hikari」のためとプレイのデバッグログを有効にすると、さらにデータベースのセットアップ/アプリケーションと間違って何診断に役立つことがあります。

幸運を祈る!