HikariCP + ScalaActiveRecord + MySQL5.1 をやってみた
何故にメモかというと、HikariCP がそもそもサンプル無さ過ぎて地獄を見たから。
まずは基本的な ScalaActiveRecord アプリを作る
Play のサンプルアプリケーションをまずは作る。
play new HikariSample
ウィザードくらいは任せた。
で、速攻、 ScalaActiveRecord を突っ込む。
build.sbt はこれ
name := "HikariSample" version := "1.0-SNAPSHOT" libraryDependencies ++= Seq( jdbc, anorm, cache, "com.github.aselab" %% "scala-activerecord" % "0.2.3", "com.github.aselab" %% "scala-activerecord-play2" % "0.2.3", "mysql" % "mysql-connector-java" % "5.1.22" ) play.Project.playScalaSettings
そしたら、下記の様にまずは書く。
conf/play.plugins
9999:com.github.aselab.activerecord.ActiveRecordPlugin
conf/application.conf
# 下記を追加 db.activerecord.driver=com.mysql.jdbc.Driver db.activerecord.url="jdbc:mysql://localhost:3306/testdb" db.activerecord.user="root" db.activerecord.password="test" activerecord.schema=models.Tables
で、モデルは下記の通り。
package models import com.github.aselab.activerecord._ import com.github.aselab.activerecord.dsl._ case class Todo(name: String, description: String) extends ActiveRecord object Todo extends ActiveRecordCompanion[Todo] object Tables extends ActiveRecordTables { val todos = table[Todo] on(todos)(s => declare( s.description is(dbType("text")) )) }
controlllers/Application.scala
package controllers import play.api._ import play.api.mvc._ import play.api.data._ import play.api.data.Forms._ import models._ import com.github.aselab.activerecord.dsl._ object Application extends Controller { def form = Form(mapping( "name" -> nonEmptyText, "description" -> nonEmptyText )(Todo.apply)(Todo.unapply)) def index = Action { implicit request => Ok(views.html.index(form, Todo.all.toList)) } def post = Action { implicit request => val req = form.bindFromRequest() if (!req.hasErrors) { req.value.foreach(v => { v.save() }) } Ok(views.html.index(req, Todo.all.toList)) } }
conf/routes
GET / controllers.Application.index POST / controllers.Application.post GET /assets/*file controllers.Assets.at(path="/public", file)
そして、views/index.scala.html を
@(form: Form[models.Todo], todos: List[models.Todo]) @main("Welcome to Play") { @for(todo <- todos){ <div> <strong>@todo.name</strong>&nbsp; <span>@todo.description</span> </div> } @helper.form(action = routes.Application.index()) { @helper.inputText(form("name")) @helper.inputText(form("description")) <input type="submit" value="送信"/> } }
実験環境を作る
実験環境を色々するのめんどいので、Vagrant するか。Vagrant 知らない人はここ参照。*1
HikariSample ディレクトリの外で適当なディレクトリを掘って Vagrant コマンド。
vagrant init test https://github.com/2creatives/vagrant-centos/releases/download/v6.5.3/centos65-x86_64-20140116.box
デプロイめんどいから、適当に共有かけるか。
Vagrantfile 開いてごりごり
# -*- mode: ruby -*- # vi: set ft=ruby : # Vagrantfile API/syntax version. Don't touch unless you know what you're doing! VAGRANTFILE_API_VERSION = "2" Vagrant.configure(VAGRANTFILE_API_VERSION) do |config| config.vm.box = "test" config.vm.box_url = "https://github.com/2creatives/vagrant-centos/releases/download/v6.5.3/centos65-x86_64-20140116.box" config.vm.network "private_network", ip: "192.168.33.10" config.vm.synced_folder "/Users/azalea/Documents/HikariSample", "/vagrant_data" end
で、実行環境を整えて
vagrant up vagrant ssh sudo su - yum install -y mysql-server wget yum install -y java-1.7.0-openjdk-devel service mysqld start mysql -u root create database testdb SET PASSWORD FOR root@localhost=PASSWORD('test'); exit
後は起動するだけ。
play とか sbt めんどいので、sbt dist
しておく。
cd /vagrant_data/ cd /opt cp /vagrant_data/target/universal/hikarisample-1.0-SNAPSHOT.zip ./ unzip hikarisample-1.0-SNAPSHOT.zip cd hikarisample-1.0-SNAPSHOT ./bin/hikarisample
http://192.168.33.100/ でアクセスできれば OK
HikariCP に乗り換える
HikariCP ってなんぞ?と思ったらここをクリック
要するに BoneCP がいつまで経ってもバグだらけだから嫌がって作ったそうな。
ScalaActiveRecord の Play plugin は playframwork からコネクションを拾ってるから、バックエンドが変わるくらいは問題なく動作できる。
まずは build.sbt
を編集。
name := "HikariSample" version := "1.0-SNAPSHOT" resolvers += Resolver.url("Edulify Repository", url("http://edulify.github.io/modules/releases/"))(Resolver.ivyStylePatterns) libraryDependencies ++= Seq( jdbc, anorm, cache, "com.github.aselab" %% "scala-activerecord" % "0.2.3", "com.github.aselab" %% "scala-activerecord-play2" % "0.2.3", "com.edulify" % "play-hirakicp_2.10" % "1.0.0", "mysql" % "mysql-connector-java" % "5.1.22" ) play.Project.playScalaSettings
次に application.conf でデフォルトの DBPlugin(BoneCP) を停止 & DB設定。
dbplugin=disabled # db.activerecord.driver=com.mysql.jdbc.Driver # db.activerecord.url="jdbc:mysql://localhost:3306/testdb" # db.activerecord.user="root" # db.activerecord.password="test" db.activerecord.hikaricp.file="conf/hikaricp.prod.properties"
hikaricp.prod.properties
には下記設定
dataSourceClassName=com.mysql.jdbc.jdbc2.optional.MysqlDataSource dataSource.url=jdbc:mysql://localhost:3306/testdb dataSource.user=root dataSource.password=test dataSource.cachePrepStmts=true dataSource.prepStmtCacheSize=250 dataSource.prepStmtCacheSqlLimit=2048 dataSource.useServerPrepStmts=true connectionTestQuery=SELECT 1 connectionInitSql=SELECT 1 maximumPoolSize=20
お次は conf/play.plugin
に追加。
1500:com.edulify.play.hikaricp.HikariCPPlugin
これで準備は整った。
ちなみに、maximumPoolSize はMySQL の設定にあわせておく事。 (デフォルトでは 150 あったはず)
これで dist して再度起動。
[root@vagrant-centos65 hikarisample-1.0-SNAPSHOT]# ./bin/hikarisample Play server process ID is 3020 [info] application - Loading Hikari configuration from Play configuration. [info] application - Loading from file configured by db.default.hikaricp.file that is Some(conf/hikaricp.prod.properties) [info] application - Loading Hikari configuration from conf/hikaricp.prod.properties [info] application - Properties: {dataSource.useServerPrepStmts=true, dataSource.user=root, dataSource.password=test, dataSourceClassName=com.mysql.jdbc.jdbc2.optional.MysqlDataSource, connectionTestQuery=SELECT 1, maximumPoolSize=20, connectionInitSql=SELECT 1, dataSource.prepStmtCacheSqlLimit=2048, dataSource.prepStmtCacheSize=250, dataSource.cachePrepStmts=true, dataSource.url=jdbc:mysql://localhost:3306/testdb} [error] n.s.e.Cache - Unable to set localhost. This prevents creation of a GUID. Cause was: vagrant-centos65.vagrantup.com: vagrant-centos65.vagrantup.com: Name or service not known java.net.UnknownHostException: vagrant-centos65.vagrantup.com: vagrant-centos65.vagrantup.com: Name or service not known at java.net.InetAddress.getLocalHost(InetAddress.java:1473) ~[na:1.7.0_55] at net.sf.ehcache.Cache.<clinit>(Cache.java:214) ~[net.sf.ehcache.ehcache-core-2.6.6.jar:na] at net.sf.ehcache.config.ConfigurationHelper.createCache(ConfigurationHelper.java:296) [net.sf.ehcache.ehcache-core-2.6.6.jar:na] at net.sf.ehcache.config.ConfigurationHelper.createDefaultCache(ConfigurationHelper.java:219) [net.sf.ehcache.ehcache-core-2.6.6.jar:na] at net.sf.ehcache.CacheManager.configure(CacheManager.java:722) [net.sf.ehcache.ehcache-core-2.6.6.jar:na] at net.sf.ehcache.CacheManager.doInit(CacheManager.java:439) [net.sf.ehcache.ehcache-core-2.6.6.jar:na] Caused by: java.net.UnknownHostException: vagrant-centos65.vagrantup.com: Name or service not known at java.net.Inet6AddressImpl.lookupAllHostAddr(Native Method) ~[na:1.7.0_55] at java.net.InetAddress$1.lookupAllHostAddr(InetAddress.java:901) ~[na:1.7.0_55] at java.net.InetAddress.getAddressesFromNameService(InetAddress.java:1293) ~[na:1.7.0_55] at java.net.InetAddress.getLocalHost(InetAddress.java:1469) ~[na:1.7.0_55] at net.sf.ehcache.Cache.<clinit>(Cache.java:214) ~[net.sf.ehcache.ehcache-core-2.6.6.jar:na] at net.sf.ehcache.config.ConfigurationHelper.createCache(ConfigurationHelper.java:296) [net.sf.ehcache.ehcache-core-2.6.6.jar:na] [info] application - Starting HikariCP connection pool... [info] application - database [activerecord] connected at jdbc:mysql://localhost:3306/testdb [info] play - Application started (Prod) [info] play - Listening for HTTP on /0:0:0:0:0:0:0:0:9000
てなことで起動した。
*1:Version若干古いけど、使い方変わらんから大目に見て