Posts Tagged ‘Scala’

EventStatsはherokuとMongoLabとさくらVPSで動いている

Posted by ReSTARTR - 28/12/11 at 09:12 pm

今月頭にブログ書きましたが、EventStatsという勉強会の参加者の推移が見れるサービスを公開しました。

まぁ自分が欲しかっただけなんですけど、使ってみて頂ければ幸いです。

今回はそのサービスの構成とかについて書いてみます。

アジェンダ

  1. 全体像
  2. システム構成
  3. Gitリポジトリ
  4. MongoDBのPaaS
  5. 各イベント管理サービスAPIの違い
  6. 開発メモ

1.全体像

開発環境も含めて全体像を図にしてみました。(初Cacooですが超べんりですね!)
赤い線がGit操作で、黒い点線がMongoDBへのアクセスです。

全体像

2.システム構成

大きく分けてwebとクローラーの2つです。

webはherokuに、クローラーはさくらのVPSに配置。
まずは優先してデータ蓄積を…ということでクローラーをpythonとmongodbで作成しました。
(サービス的にはやいとこデータためないと意味ないので。)

クローラーは5分おきに起動するのでScalaよりPythonを選択しました。起動コスト重視です。
(Scalaでサクサク開発できる程のスキルではないというのもありますが…)

実行場所はherokuのworkerも考えたましたが、最終的に既に利用していたさくらVPSでcronジョブとして運用することに。
ということでScalaのWebはデータ参照のみで、データの更新はしません。

3.Gitリポジトリ

webとクローラーは分けてGitで管理。リモートリポジトリはどちらもさくらのVPS上においています。
ただし、本番リリースは開発PCからherokuに別途pushします。
※webもさくらVPSにリモートリポジトリを持って、本番データを参照するステージング環境として利用しています。

eventstats-web

eventstats-crawler

4.MongoDBのPaas

herokuプラグインとしてMongoLabMongoHQの2つが提供されています。どちらも無料枠があるのですが、MongoLabの方が無料で利用できる容量が大きいのでこちらを選択。
月額の利用料金は以下です。(括弧内は1MBあたりの金額の目安です)

これ以上の容量も利用可能ですが個人で払う範囲ではないと思い除外してます。

MongoLab

MongoHQ

5.各イベント管理サービスAPIの違い

まずはatnd, zusaar, partake.inの3サービスに対応
それぞれ検索APIを提供してくれているのですが、当然ながら規格とかもないのでリクエストもレスポンスも違いがあります。 データ蓄積する際にそのAPIの差異を吸収して、webアプリから参照する際は気にしなくていい戦略をとりました。

APIの違い検索のみに特化して違いをまとめると以下の通りです。

atnd

イベント数も多いので、このAPIをスタンダードに設定。

zusaar

基本的にはatnd準拠っぽい感じだけど細かい違いがあります。

atndとの違い

partake.in

全然違うAPI。APIリストにあっても未実装がほとんどなので、利用する際はソースを確認したほうが良いです。

今回必要になりそうなAPIは2つくらいでした。

その他の特徴は以下。

上記をふまえ、atnd/zusaarはJSON形式でAPIからデータ取得。
partake.inのみイベントのリストをAPIから取得して、ユーザー数はWebページのスクレイピングで対応しました。

6.開発メモ

web(heroku)からもクローラー(さくらのvps)からも離れた場所にある

開発PC上だと気にならなかったのですが、1件1件findしてinsertやupdateをしていると当然遅いです。なのである程度まとめて一気にinsertする方針に変更しました(ベンチ結果はありません ^^;)。

更新はクローラーの1プロセスからのみ実行されるので、トランザクションとか意識しなくて良いです。なので比較的自由な構成がとれます。

ScalaでJSON API

まずはUnfilteredでJSON APIを作成。けど、jsでjson取得〜チャート生成の実行時間が思いの外大きいので、jsonも1枚のHTMLに埋め込む方針に変更。

さいごに

ざっと書きだすとこんな感じです。まぁこんな構成もあるよ、ってくらいにしか言えませんが。
webとクローラーを分けたことで、開発中のスキーマ変更が柔軟に行えたのは良かったのですが、スキーマ定義を共通で管理していないので、そのあたりうまく管理できると良いなと思ったり。

当初はもう少しwebの機能も多かったのですが、効率化をしているうちにシンプルな形に落ち着きました。Scalaのコードもかなり小規模なものになっています。

イベント管理者の方からのご意見ご要望などいただけると嬉しいです :)

Fork me on GitHub

If you enjoyed this article please consider staying updated via RSS. Links to your own social media pages could be added here.

Scalaで設定ファイルを使いたい時どうしたらいいの?

Posted by ReSTARTR - 30/08/11 at 12:08 am

2011.08.31 kmizushimaさんから頂いたコメントを元に、下記の記述を修正&追記しました。

  • Twitterのutil-evalの一時ファイル生成について
  • AkkaのConfigファイルのパース手法について

TwitterのOAuthの鍵やDB接続情報など、アプリを書く上で環境によって切り替える設定が大抵の場合あると思います。普段使っているPHPの場合、設定を外部ファイルに書きだす場合、ini,yaml,xml,phpのいずれかを使うことが多いのですが、Scalaの場合、設定ファイルってどうするのか気になりました。

ということで、適当に思いついたライブラリやフレームワークがどのように対応しているのか調査。

ライブラリ

propertiesファイル

path/to/conf.properties

1
hoge = "moge"
1
2
3
val p = new java.util.Properties()
val config = p.load(new java.io.FileInputStream("path/to/conf.properties");
config.get("hoge") // "moge"

twitterのconfiggy

twitterのutil-eval

設定のtraitを定義

src/main/scala/com/restartr/utilSample/MyConfig.scala

1
2
3
4
5
package com.restartr.utilSample
trait MyConfig {
  val num: Int
  val str: String
}

実際の設定ファイルでは、設定のTraitを継承してインスタンス生成
※クラスインスタンスでなくても文字列やリストでもOK。

path/to/config/MyConfig.scala

1
2
3
4
5
import com.restartr.utilSample.MyConfig
new MyConfig {
  val num = 1
  val str = "san"
}

使いたい場所でEval。

1
2
3
val conf = Eval[MyConfig](new java.io.File("path/to/config/MyConfig.scala"))
conf.num // 1
conf.str // "san"

configrity

各種フレームワーク

以下のフレームワークはすべて独自実装でした。Propertiesじゃ役不足だし、かといってデファクトな設定用ライブラリがないからなのでしょうか。

akkaのconfig

1
2
3
4
5
akka {
  cluster{
    name = "test-cluster"
  }
}

play!frameworkのconfig

Lift

ざっと調べて使ってみたところ、手軽にやるならProperties、フレームワークを使うならそれに則り、厳密にやるならTwitterのEvalや、設定ファイルを読み書きできる独特なConfigrityなんかがよさそうです。

XMLは…まぁないでしょうね。

If you enjoyed this article please consider staying updated via RSS. Links to your own social media pages could be added here.