ラベル Heroku の投稿を表示しています。 すべての投稿を表示
ラベル Heroku の投稿を表示しています。 すべての投稿を表示

2015年1月10日土曜日

Play!アプリとBoneScriptの通信 - 1.構成

余分なジャンパが苦闘の痕跡を示すのだった

表題の通り、PIRセンサーの状態をBeaglebone black上のBoneScriptで読み取ってHeroku上のPlayアプリへ送り、D3.jsを使ってグラフ表示する方法をまとめました。

  1. 構成
  2. Playアプリ
  3. BoneScript

■アナログは苦手■

前回の記事の後PIRセンサの調子が悪くなってしまい、対応に追われました。どうもPIRモジュールの温度特性が良くないようで、プルアップ抵抗などを調整してうまく動くようにした後、外出や就寝で暖房がきれると徐々に特性が悪化してしまいます。

今回使っているPIRの最終段はオープンコレクタなのですが…コレクタ側に100Ωの保護抵抗が入っているためlowでも電圧がすっきり落ちてくれません。プルアップで調整するのも面倒になってきたので、これは2SC1815でバッファ入れて解決しました。ベースを10k、コレクタを1kΩで3.3vからプルアップし、エミッタをGND、コレクタからBBBのGPIOにつないでます。



あともう一つ、PIRからのノイズなのか、そのままだとGNDに200mVぐらいのスパイクノイズが乗ってしまってます。これも使い始めたころはなかったのですが、室温が15度を切るようになったから悪化したように思います。なので、4.7μFのケミコンと0.1μのセラコンを入れたところ見違えるように安定しました。

いやはや。

■ハードウェア構成■

センサには秋月の焦電型赤外線センサモジュールを用い、Beaglebone blackの5v電源出力とGNDを接続、上記回路で安定させてからBBBのP8_19に接続しています。非常に単純です。

なお、別のところでも書きましたが、最初は以前秋月で売っていたParallaxのPIR Rev.Aを使ってみたのですが…室内での人の動きと無関係に信号が出ていて、どうやっても改善しなかったので諦めました。現在秋月での扱いが終了しているのは、何か問題があったからではないか?と邪推している今日このごろ。貧乏サラリーマンの数百円を無駄にした恨み、思い知るがいい(違

■まずPlay側■

あっちこっちのサンプルの寄せ集めですが、こんな構成になっています。
controllers---Application.java
              Secured.java
models--------SensorData.java
              SensorDataRest.java
views---------graph.scala.html
              index.scala.html
              login.scala.html
              main.scala.html
Secured.javaなんてファイル名はまさにこのサンプルそのまま、笑ってやってください。

このアプリをHeroku上で稼働させています。データベースには同じくHerokuのPostgreSQLを用いています。どっちも無料枠内。PaaS万歳。

グラフ表示アプリには必要最小限の認証を付けました。でないと「留守・就寝中を世界に向けて発信する」アプリになってしまいますので。

グラフの表示にはD3.jsを使っています。ブラウザ上のD3からPlayアプリのAPIを叩いてJsonで過去24時間分の1分ごとのデータを受け取り、15分単位に集計してグラフを表示します。

■BBB側■

Beaglebone black Rev.Cはほぼ素のママで、BoneScriptを動かしています。0.1秒ごとにサンプリングして1分間のうち何秒間センサが動きを検出したかを集計し、1分ごとにHeroku上へとJSON形式のデータを送っています。

今のところ、送信エラー時のリトライは行っていません。Herokuは24時間に一度勝手にインスタンスがリスタートするので、エラーが出たらバッファにためといて再送するような仕組みを入れておくべきなのですが…。

■次回■

Play!のソースについてご説明します。公開しました。

2015年1月4日日曜日

PlayとD3とBeaglebone



会社でのお仕事として年明けからPlay+Spring+Emberを使ってサイトを1つ立ち上げることになっているのですが、どれもチュートリアルをなぞった程度で本格的に使ったことありません。しかし:

  • 休み中はしっかり休みたい。
  • でも勉強しておかないと死ぬのは確実。
  • でも休み中は電子工作方面に浸りきりたい

ので、この3つを満たすために「Beagleboneで収集したデータをPlay! frameworkで書いたHeroku鯖へ送り、グラフ化して表示」ってやつを作ろうと思います。visualizeには同僚さんに教えてもらったD3jsというフレームワークのグラフがあまりにもきれいなので、それ使います。EmberとSpringのことはとりあえず忘れます。

■動作フロー■

基本的にこんな動き。まずセンサ〜収集系:
  1. Beaglebone Black Rev.c上でPIRセンサーを読み取り人の動きを検出
  2. 検出した結果は1分あたり動いた秒数として出力し、Heroku鯖へ送る
  3. Heroku上で動くアプリはWeb APIとしてデータを受信する。
  4. 受信したデータはHerokuのPostgreSQL上にリングバッファ的に保存(Herokuのポスグレは10k行まで無料で使えるので)。
続いてデータ表示系:
  1. ブラウザからのリクエストを受けてHTMLを返す
  2. HTML上でD3.jsがHerokuへデータをリクエスト、Jsonで返す
  3. D3.jsがグラフを描画
D3.jsはデータ形式も多彩でcsv, tsv, json, xmlなど思いつくものはだいたい入ってます。

■予備実験■

BBB+PIRセンサーは現在絶賛安定稼働中なので、未体験要素としてD3jsでのグラフ生成を試してみます。棒グラフを出すだけならChart.jsの方が圧倒的に簡単なのですが、もうね、表現力が圧倒的すぎるのですよD3様は(そこまで使いこなせるかどうかは別の話)。

ということで、まずチュートリアルからサンプルソースをコピペ。こんな立派なグラフがこれだけで?と思うぐらいソース短い。

■Play 2.3.7■

しばらく自宅MacでPlayをいじっていなかったら、ターミナルでactivatorとタイプしてもエラーになってしまう。のでbrewでアンインストール&インストール(安易だ)。
brew uninstall typesafe-activator
brew install typesafe-activator
で、プロジェクトを作る:
activator new ShowSensors
起動後、play-java templateを選択。戻ってきたらactivator uiを起動
cd ShowSensors
activator ui
しばらくしてブラウザ上にIDEが開く。最近ブラウザIDEが流行ってますねぇ。ただ、エディタがタブ対応でないならviの方がマシだし、何よりcompile/runがうまくいかないので今回も利用を見合わせます。Play2の場合、Eclipseを使うメリットがあんまり感じられないのでsublime text2使います。ctrl+cで終了し、
activator run
ビルドその他のメッセージがおとなしくなったところでブラウザで localhost:9000 を開けばいつものページ、緑色の「Your new application is ready」のメッセージがお出迎えしてくれます。

■ヘンなエラー■

ひと通り実装をしたところで試すとこんなエラーが:

[error] play - Cannot invoke the action, eventually got an error: java.lang.RuntimeException: Error getting BeanDescriptor for path User from models.User
ググってもどうもピンと来ない。何となくEbean系の間違いのようなので、
  • とりあえず@OneToMany / @ManyToOneなどを消して見る
  • とりあえずactivator clean / activator updateなどを試す

などやってみたのですが、ダメ。その後、トレースしてみると、
User user = find.fetch("user").where() .eq("email", inEmail) .findUnique();
ここで落ちてました。そりゃそうだ。ここを
User user = User.fetch().where() .eq("email", inEmail) .findUnique();
に変えたら通りました。先にUserの生成と検索についてのtestを書いてりゃ容易に切り分けが出来ていたケースですね…反省(@元日)。

■で、Web API■

フツーにRoutesにURIとコントローラを書いて、
GET /fetchFromHours controllers.Application.fetchFromHoursGet()
コントローラでdbからデータをfetchし(仮にarrayDataとする)、最後に return ok(Json.toJson(arrayData)); と書けばOKです。以下は過去24時間の計測データを返すAPIの処理:
// curl --header "Content-type: application/json" --request GET http://localhost:9000/fetchFromHours
public static Result fetchFromHoursGet(String inEmail) {
User owner = User.findByEmail(inEmail);
Calendar calFrom = Calendar.getInstance();
calFrom.setTime(new Date());
calFrom.add(Calendar.HOUR_OF_DAY, -24);
calFrom.set(Calendar.MILLISECOND, 0);
Integer hours = 24;
List<SensorData> sds = SensorData
                       .findByUserSinceDateForHours(owner, calFrom, hours);
if (sds == null || sds.size() == 0) {
return badRequest("no data found");
}
List<SensorDataRest> sdr = new ArrayList<SensorDataRest>();
for (SensorData sd : sds) {
sdr.add(new SensorDataRest(sd));
}
return ok(Json.toJson(sdr));
}

■Macにポスグレをインストールして起動■

brew install postgresql
initdb /usr/local/var/postgres -E utf8
postgres -D /usr/local/var/postgres &
これで
psql -l
とやってデータベース一覧(初期状態の設定テーブルが2-3個あるはず)が見えればOK

■Web APIでURLパラメータを渡すには■

今回は使いませんでしたが、http://.........../apiName?name=kura&email=foo@bar.comという処理をしたい場合には、routesに
GET /apiName  controllers.Application.api(name:String, email:String)
と書き、ソースに
public static Results api(String inName, String inEmail) {
....
}
と書けばOKです。routesにはパラメータが省略された時の値を指定することも可能で
GET /apiName controllers.Application.api(name:String ?="kura", email:String ?="tare@panda.com")
と書きます。RESTfulな書き方については簡単に見つかるんですが?&でパラメータを渡す方法がなかなか見つからなかったのでメモしておきます。

■Heroku上のpostgreSQLへ接続■

まずHeroku上のpostgreSQLを有効にします。

すると、URLやid, passwordなどが通知されますので、それに基づいてapplication.confを書き換えてdatabaseをH2からpostgreSQLに変更し

build.sbtにpostgreSQLのドライバを追加します。
libraryDependencies ++= Seq(
  javaJdbc,
  javaEbean,
  cache,
  javaWs,
  "com.fasterxml.jackson.core" % "jackson-databind" % "2.4.4",
  "com.fasterxml.jackson.core" % "jackson-annotations" % "2.4.4"
,
  "postgresql" % "postgresql" % "9.1-901-1.jdbc4"

)
ま、上の設定が決まるまで一発では動いてはくれなかったんですが…その辺は末尾の「ハマりリスト」をご笑覧くださいorz

■Herokuへdeploy■

これはもうここに書いてあるそのまんまです。
  Heroku へのデプロイ(playframework.com)
便利になったものです…初回はdependencyのチェックでエラい時間かかるけど、待ってりゃ終わります。終わったところで

で、以下の様な表示が出ればOK
koichi$ heroku ps
=== web (1X): `target/universal/stage/bin/showsensors -Dhttp.port=$PORT`
web.1:
up 2015/01/04 08:36:10 (~ 2s ago)

大事なのはここのupってところ。これがcrushedだとデプロイor起動に失敗したということ。もう見飽きるほど見ましたよ…ええ…。

■BoneScript変更■

テストではcsvに書き出すだけでしたが、コードを追加しました。まずpayloadを作って
var body = JSON.stringify({
    date:  sDate,
    count: sCount,
    email: "kkurahashi@me.com"
});
POSTします。
var request = new http.ClientRequest({
    hostname: "ホスト名",
    port: 80,
    path: "/receive",
    method: "POST",
    headers: {
        "Content-Type": "application/json",
        "Content-Length": Buffer.byteLength(body)
    }
});
request.write(body);
request.end();
通常のPlayアプリだとポートは9000ですが、Herokuにデプロイすると特に設定しなくても80でつながります。他にエラー処理もあるけど、あとでGithubに上げるのでそっちをご覧くださいませ。

■できあがり■

8:48はトイレに行ってた

■今後■

上記は生データ表示なので24時間収集すると表示が細かすぎます。これを5分か15分にサマライズします。あとはローカルとリモートのPostgresをdev/deployで自動的に切り替わるような設定も組み込まないといけません。ぽすぐれと接続できないでウロウロしてた時にその辺の設定は全部後回しにしてしまい、現状はapplication.confを手動で切り替えておりますw

それからソースを掃除してからGithubでプロジェクトを公開します。まぁ今度の週末にでも。

そして以下は今回の作業でハマった箇所です。改めて見直すと…我ながら…アホです。でも失敗して覚える…というか失敗しないと学習しないタイプなので、とっても勉強になりました。正月休みはウォーキングにも行かないでこればっかりやってたせいで3kg太ってけども。

餅は危険です。

■ハマりリスト■

  • テストが作動しない
    • せっかくテストコードを書いたのに activator test を実行しても新しいテストコードが認識されないことがある。そういう場合には、activator cleanを実行すると直る。もしダメなら一度activatorからexitして(もし起動していれば)Eclipseを終了させ、activator cleanを実行してから再度activatorに戻ってtestを試してみる。
    • 全般的にソースを追加した場合にはcleanするかactivatorを一度終了した方がいいかもしれない。また、application.confやsbt関連ファイルを弄った場合にはactivatorを終了/再起動しないとダメっぽい。
    • あと、activatorを起動しっぱなしで半日作業したら「メモリが足りない」ってエラーが出たことがありました。Eclipseばかりではなく、たまにはコンソールも見ましょう。
  • @Constraints.Requiredが機能しない
    • Ebeanでは @NotNull を使うorz
  • @ManyToOne(fetch=FetchType.EAGER)が効かない
    • objをfetchしてきた時、obj.toOneには値が入っているけどobj.toOne.someとやるとnullになってしまう。toOneをprivateに変更し、getter/setterを設けることで解決。
    • StackOverflowには「Play!のバグじゃね?」って意見もあるけど、どーなんでしょうね。
  • 複数項目を対象にしたunique属性
    • @Entityの後に @Table(uniqueConstraints = @UniqueConstraint(name="制約につける名前", columnNames = { "attr1", "attr2" })) ...とカラム名を列挙する。
    • なお、java上のattribute名ではなくdb上のカラム名なので、対象となるattributeには@Columnでカラム名を指定するか、Evolution表示で出てくるカラム名を使うこと。
  • PostgreSQLと接続できない
    • application.confでのURI書式が違ってたorz
      db.default.driver=org.postgresql.Driver
      db.default.url="jdbc:postgresql://localhost:5432/データベース名"
      db.default.user=ユーザ名
      db.default.password=パスワード
  • PostgreSQLでテーブルができない
    • userというテーブル名は予約語なので作れませんorz
    • クラス名を変更するか、@Table(name="users")を追加してテーブル名を変更する。
  • その後、UserをUsersに変更したけど、evolutionで生成されるSQLが古いままでcleanなどをやってもcreate userのまま
    • 中途半端なところでevolutionが止まったため、管理テーブルplay_evolutionsだけがpostgreSQL上に出来ていたのが原因っぽい。
    • ので、drop databaseでまるごと削除したら動いた。
  • 以下、Herokuへデプロイできた後の話
  • コンソールやpsqlで見るとデータがあるのにAPIでfetchできない
    • Herokuがアメリカ時間だったため。以下の記事を参考にして、JSTに変更したら治った。インスタンスの再起動も不要でした。
    • http://blog.ruedap.com/2011/02/10/heroku-timezone-japan-jst
    • コマンドラインで heroku config:add TZ=Asia/Tokyo

2012年9月21日金曜日

WebObjects + Heroku:その3・WOのWARを作る

■ProjectWOnderのセットアップ■

ここを参考にして進めます→「Project Wonder Installation

Step1-4までありますが、3まででOKです。「Step 4:  Import Project Wonder into your Eclipse workspace」はちょっと説明が必要なのでこの後の節で。

■WOnderのセットアップ■

大まかな手順は
  1. WOnderソースコードのダウンロード
  2. Java環境変数の確認と設定
  3. ビルド&インストール
です。前提として、以下の作業はhomeディレクトリ直下で行いますが、home下であればどこでも結構です。

まずはソースをダウンロードします。「Getting the Wonder Source Code」を参考にしました。

・Homeディレクトリへ移動
    $ cd

・WOnderソースコードのダウンロード
    $ git clone git://github.com/projectwonder/wonder.git WonderSource
    $ cd WonderSource

・最新版の確認とダウンロード
     $ git checkout integration


次に、javacの環境設定の確認です。ターミナルで
    $ setenv | grep JAVA_TOOL_OPTIONS
    JAVA_TOOL_OPTIONS=-Dfile.encoding=UTF-8
    $

のようにエンコーディングが指定されていればいいのですが、ない場合には適当なエディタで.csrcを開き、 setenv JAVA_TOOL_OPTIONS -Dfile.encoding=UTF-8 と追加します。追加したらシェルを再起動します。ターミナルごと再起動するか新しいウィンドウを開いてもOKです。上記のsetenv...を使って、設定が反映されていることを確認してください。

では、ビルドとインストールです。ターミナルから
    $ ant frameworks; sudo ant frameworks.install

を実行します。数分かかりますが、エラーやワーニングが出ていないか注意してください。buildが終わったところで一旦動きが止まり、sudoのパスワードを求められます。最後に
    BUILD SUCCESSFUL
    Total time: 25 seconds

が表示されれば終わりです。こう書くとあっという間なんですが…いろいろ試行錯誤があって数日ツブれました…いや、愚痴ですけどね。

■WOアプリを作る■

ではいよいよWOのアプリを作ります。

Eclipseで File>New>Wonder Application を選びます。Wonder Applicationが選択肢として出てこない場合には、PerspectiveをWOLipsに切り替えてからもう一度。プロジェクト名は WOHeroku にしてFinishボタンをクリックします。

プロジェクトを開き、Sources>your.app>Application.javaを右クリックし、Run As>WO Applicationを選びます。


コンソールに起動ログが真っ赤な字で表示されますが、お気になさらず。そのまま数秒後ブラウザ上に Hello World が表示されます。これでWOアプリが動くことは確認できました。


■ServletとしてDeployし、Herokuへ■

プロジェクト名を右クリックし、Properties>WOLips Deploymentを選びます。ここで「Servlet Deployment」と「Autogenerate web.xml」をチェックし、OKをクリックします。この時点でHerokuで動かせないことに気づきました。SDDオプションがありません。SDDでないとWOFが組み込まれないので…。

プロジェクトメニューを右クリックし、WOLips Ant Tools>Installを選びます。ビルドが行われますが、通常のビルドよりも時間がかかります。問題がなければ数分後、BUILD SUCCESSFULの表示が出てApplicationディレクトリにWOHerokuとWOHeroku.woaディレクトリ, WOHeroku.warが出来ているはずです。


が、私の環境もそうでしたが、/Library/WebObjects/Applicationディレクトリのパーミッションがユーザに対して許可されていないとBUILD FAILEDになります。対処方法は二つ、開発マシン上なら1、運用マシン上でビルドも行うのであれば2でしょうか。

1.パーミッションを変更する


標準的なインストール環境であれば、ターミナルで
    $ cd /Library/WebObjects/Versions/WebObjects543/Library/WebObjects
    $ sudo chmod 775 Applications/
    Password:
    $ sudo chgrp staff Applications/

などと設定します。ともかく、自分がApplicationに書き込みできるような権限を付与します。775とは古いねしかしorz

2.インストール先を変更する


プロジェクトWOHerokuディレクトリの直下にある build.properties に dist.dir=dest という一行を追加します。こうすると、ビルドした結果がWOHerokuディレクトリ直下のdestディレクトリに変更されます。

これでWOHeroku.warができました! ここまでホントに長かった…。

■HerokuへDeployment、できません■

ターミナルで、WOHeroku.warのあるディレクトリへ移動し、デプロイします。

    $ heroku deploy:war --war WOHeroku.war
     !    No app specified.
     !    Run this command from an app folder or specify which app to use with --app <app name>
    $
    $ heroku deploy:war --war WOHeroku.war -app WOHeroku
     !    No app specified.
     !    Run this command from an app folder or specify which app to use with --app <app name>
    $

と、いうことでapplicationとして認識してもらえません。mavenさんでWOFも送り込むようなpom.xmlを書いたりすれば技術的には可能だと思いますが、これからmavenさんを勉強するスキルがありません。

ごめんなさい。

ただ、今後もWOを趣味程度にいじっていこうと思ってます。最近会社にもMacが入ってXcode三昧だったりするので、家と会社では違うことをやらないとね。

2012年9月20日木曜日

WebObjects + Heroku:その2・WARを直接Herokuへ

■前回の続き■

前回はHerokuのアカウント取得、RubyサンプルのHerokuへのデプロイ、Tomcatのインストール、TomcatサンプルのHerokuへのデプロイ…まで済ませました。今回は下記の通り、ローカルでビルドしたWARを直接Herokuへデプロイして動かすところまで。

  • Eclipse+Tomcat
  • TomcatプロジェクトからWARを作成
  • HerokuへDeployment

■Eclipse+Tomcat■

EclipseでTomcatアプリ開発」を参考にしました。うーむデザインに時代を感じる…。

大まかな流れとしては、
  1. EclipseにTomcatプラグインを入れる
  2. EclipseからTomcatが起動・終了できることを確認する
  3. 新規にJava/Tomcatプロジェクトを作り、上記サンプルソースを貼ってEclipseのDebugまたはRunボタンをクリック→コンソールにエラーが出ないことを確認
  4. ブラウザでhttp://localhost:8080/アプリ名/servlet/helloを表示し、Hello, World!
最後のところでURLでちょっとハマりました。TomcatのManager画面にはアプリ名が表示されているのですが、そこをクリックしてもnot foundになってしまう。てっきりTomcatの設定の問題かとあちこちググったりしても思い当たらない。で、上記のページをよく見直したら、URLはアプリ名+web.xmlのurl-patternになっていました。素人はこういうところでハマるから困ったもんです。

ともかく、EclipseでTomcatアプリを作って動かすところまではOK。

■TomcatプロジェクトからWARを作成■

Tomcat JavaプロジェクトをWARにするのは:
  1. プロジェクトを右クリック>Properties
  2. Tomcat>WARエクスポート設定タブ

ここで「エクスポートするWARファイル」の出力先パスを指定します。私の環境ではなぜか「参照」ボタンからファイルダイアログを指定してもパスを選べなかったので、出力先をフルパスで入力し、OKをクリックします。

なお、「.javaファイルをエクスポート」してしまうとソースも一緒にエクスポートされてしまうのでご注意を。それにしても私の環境は日本語化していないのに、どうしてここだけ日本語なんでしょ?


続いて、プロジェクトを右クリック>Tomcat プロジェクト>


を選びます。さっき指定したところにWARができているはずです。


ということで、このwarを直接HerokuへPushします。

■WARをHerokuへDeployment■

参考にしたのはここです→「Getting started with WAR deployment on Heroku

記事にもありますが、Heroku toolbeltのインストールとHeroku Accountが必要です。またHerokuのバージョンは2.24.0以上が必要です。

まずツールをセットアップします。これはターミナルで以下の通りタイプするだけです。
    $ heroku plugins:install https://github.com/heroku/heroku-deploy

あとは、さっき作ったTestTomcat.warの置いてあるディレクトリに移動してから、HerokuにDeployするだけです。
    $ cd
    $ heroku deploy:war --war TestTomcat.war
    $ heroku open

…ここでブラウザが開きますが、エラーが出ます。


泣いてはいけません。ローカルで走らせた時と同様にブラウザ上のURL末尾に /servelet/hello/ を追加して再表示します。今度こそHello Worldが表示されます。って書くと2行だけど、実際は/servlet/hello/をすっかり忘れてて数時間グーグル先生と旅をしていまいたorz

ということで、次回いよいよWebObjectsのWARファイルを作って、Herokuへデプロイします。その前にPostgreSQLに対応したTomcatサンプルを作ってHerokuで動くことを確認したら?という声が聞こえますが、TomcatでのDB取り扱いを勉強しても将来おそらく使うことはないと思うので省略します。

その1でも書きましたが、WOはHerokuにはデプロイはできません。ただ、日本語のMac環境にWonder framework入れようとするとコケるので、その辺の情報提供としてその3を公開します。

2012年9月16日日曜日

WebObjects + Heroku:その1・準備編

■残念なお知らせ■

HerokuにWebObjectsを載せることはできませんでした。ということで、この記事はHeroku超入門+WOLips超入門です。夢を見せてくれてありがとう…Single Directory Deploymentがサポートされていないとは思わなかったよ…。

■何を今更WebObjects■

「Herokuに対して直接WARをデプロイできる」ということを知ったのがキッカケでした。

Rubyに馴染みがないのでHerokuには触っていなかったのですが、Javaなら何とかなるしEclipse使えば必要最小限の作業でWARを吐き出せますからね。で、どうせWARを作るのであれば好きなフレームワークで試そうと思った次第です。

会社の仕事ともぶつからないし。

でもいきなりHerokuでWOを動かそうとしても上手く行かなかった場合に原因の切り分けが難しくなるので、1)まずHerokuを試し、2)TomcatのWARを作ってHerokuにデプロイ、3)最後にWebObjectsでWARを作ってHerokuで動かす…という段階を踏みます。

■Herokuとは■

HerokuはPaaSです。Ruby, Scala, Node.jsなどで書かれたプロセスをクラウド上で走らせることができます。バックエンドサービスとしてPostgresSQL, Hadoopなども使えます。1プロセスの起動時間(CPU時間ではなく起動している時間)として750時間、PostgresSQLの容量5MBまで無料で使うことができます。

詳しくは「FAQ:Herokuってなに?メリットは?」をご参照ください。

■Herokuアカウント取得■


Heroku.com」ページの右下にある「Sign up」をクリックします。日本の美しい風景が描かれたSign upページからemailアドレスを入力すると、招待メールが届きます。

メール上のリンクをクリックしパスワードを登録するとめでたくheroku Dashboardが表示されます。

左側にある「Download Heroku Toolbelt for Mac OS」をダウンロードしておきます。herokuコマンドラインツール, gitその他がインストールされます。インストールが終わったら、画面右側にあるようにheroku loginとタイプし、emailとpasswordでログインします。その次にherokuとの通信のための秘密キーを何にするか尋ねてきますので、番号で指定します。もしssh public keyがないと言われたら、KeyChainを使って作成してからもう一度。作成した後で
    $ heroku keys:add
を実行してキーを登録します。

確認のために画面下にあるコマンドを試してみます。Rubyのサンプルをgithubからとってきて、Herokuに上げます。

なお、4のところでRSAのパスワードを求められますが、間違えると以下のようメッセージが出て先に進めなくなります。
    Permission denied (publickey).
    fatal: The remote end hung up unexpectedly

その場合は間違ったキーを削除します。まず、以下のコマンドでKey名を表示し
    $ heroku keys
ここで出てきたkeyを
    $ heroku keys:remove keyname@domain
で削除し、下記コマンドで別のキーを登録しなおして
    $ heroku keys:add
もう一度4を実行します。間違えると勉強になるわ(泣

ともあれ、これでHerokuを使う準備ができました。Heroku Dashboardをみると、アプリが動いていることがわかります。アプリケーション名のリンクをクリックして、アプリケーション情報のページからOpen Applicationをクリックします。別ページが開いてHello, Worldが表示されればOKです。Herokuを無料で使えるのはWeb Dyno1本=インスタンス1本ですので削除しておきます。Settingsページの一番下からRemove Appしておきましょう。まぁ起動時間単位の課金なので、そんなに神経質になることもないのですが。

■HerokuのためのTomcat環境とサンプルを準備■

ここを参考にしました→「HerokuにEmbedded TomcatヘJava Web Applicationを作る

ただし、ここに掲載されているpom.xmlは壊れていてソースファイル名などにも記述漏れがあるので、上記記事の原本「Create a Java Web Application using Embedded Tomcat」からpom.xml, Main.java, HelloServlet.java, index.jspを拾ってきました。

ついでにTomcatも新しいのをインストールしなおしました。この辺が参考になりました→「[Tomcat]MacでのTomcatの環境構築」。最新は7.0.30ですが、Eclipse Tomcat pluginが対応していないので6.0.35を入れてください。

コマンドラインからsh target/bin/webappを実行してからブラウザでhttp://localhost:8080/を開き「Hello, Heroku!」の力強い文字w表示されればサンプルアプリの準備はOKです。ターミナルでctrl+C、ローカルで動いているアプリを止めます。

これで一応、ローカルでTomcatが動くようになりました。

■サンプルアプリをHerokuへ■

引き続き上記のページを参考にしながら、アプリをHeroku上で動かします。上記英語ページの「Deploy your application to Heroku」あたりから。同日本語ページにも記述があるのですが、ちょっと読みにくいかな…ともかく、あとはProcfile, system.propertiesを作ってコマンドをいくつか打ち込むだけです。最後のheroku openを実行すると、ブラウザ上にさきほどと同じ「Hello, Heroku!」が現れるはずです。お疲れ様でした。

■次回は■

慣れた人なら2-3時間でここまで来られると思うのですが、いくつかハマってしまって丸1日かかってしまいました…。

ということで、次回Tomcatアプリを作り、WARファイルを直接HerokuにDeployします。