2014年12月 9日 (火)

Scalaアプリケーションの最速Herokuデプロイ

この記事はScala Advent Calendar 2014の9日目です。

ネタはHerokuにScalaアプリケーションを高速にデプロイする方法。

元々の発端は今年のScala Matsuriで「HerokuにScalaアプリケーションをデプロイしようとするとタイムアウトすることがあるんだけど。。。」という話題が出たことです。

デプロイの制限時間は15分ですが、HerokuのSlug Compilerはすこぶる非力なので、タイムアウトをくらう人もちょいちょいいます。

ちなみに僕も春頃に一度くらってますが、その時はHerokuのサポートに連絡したら該当アプリの制限時間を30分に延ばしてくれました。(^^;;;
そんなんアリかよ?と思わなくもないですが、コンパイル時間を短くするべく頑張っているからしばらくそれでしのいでくれ、とのこと。

自前のbuildpackでどうにかするという構想はScala Matsuriの時点であったんですが、雑事にまぎれて放置している間にはや3ヶ月です。。。(--

Advent Calendarに登録すれば嫌でもやるだろと、自分にプレッシャーをかけてみたもののそうこうしているうちにGitHub Syncとかできちゃいましたね。。。

GitHub SyncではGitHubにコードをpushすれば自動的にHerokuへのデプロイが非同期で走ります。(Heroku gitへのpushはpreHookされているのに対しGitHub SyncはpostHookです。)

僕の場合、ストレスの要因はコンパイルが遅いことよりもコマンドが返ってこないことにあったので、もうこれで良いんじゃないかとも思いましたが、他に提供できるネタもないのでScala用の高速buildpackを作ります。


★ 高速化作戦

どうやって高速化するかを説明するためにまずは標準のScala buildpackがやっていること見ていきます。

大雑把に言うとだいたい以下のような手順でビルドを行っています。

  1. Gitからコードを取得
  2. Buildpackのダウンロード
  3. JVMのダウンロード
  4. SBTのダウンロード
  5. sbt compile stage」コマンドの実行
  6. キャッシュや中間ファイルの削除


実際にコンパイルを行っているのは「sbt compile stage」コマンドです。
stageというのはSBT Native Packagerというプラグインのコマンドで、それさえあればScalaアプリケーションを実行できるというファイルセットを作ってくれるものです。


Playframeworkにはこのプラグインが組み込まれているので、Playアプリケーションのルートで「sbt stage」を実行すると「target/universal/stage」以下に必要なファイルがすべてコピーされ、実行スクリプトも生成されていることが確認できます。

要するにこの下のファイル群だけHerokuに渡しちゃえば、Scalaアプリケーションは実行できるわけです。
コンパイルも不要なのでSBTをダウンロードする必要もありません。

つまり、この手法の場合先の手順からこれだけのステップを省略できます。

  1. Gitからコードを取得
  2. Buildpackのダウンロード
  3. JVMのダウンロード
  4. SBTのダウンロード
  5. 「sbt compile stage」コマンドの実行
  6. キャッシュや中間ファイルの削除


ほとんど何もしないので、間違いなく速いはずですよね。
また、SBTやコンパイル前のソースコード、画像ファイル等もSlugに含まれなくなるのでサイズ的にも有利です。



★ heroku-buildpack-scala-compiled

ということで作ったbuildpackがこれです。

https://github.com/shunjikonishi/heroku-buildpack-scala-compiled

Scalaのbuildpackをforkして、要らないところをザクザク削って、Procfileが無い場合に自動生成するパスを変更しただけ。(^^;

腰が重かった割には作り始めるとあっという間でしたね。


最初は標準ライブラリはbuildpack側で生成するようにしようとか、Gitに入れるならherokuブランチを作ってgh-pagesのようにそっくり中身を差し替えようとか、色々難しく考えてたんですが、よくよく考えるとHerokuへのdeployにしか使わないと割り切ってしまえば別にバージョン管理する必要がないんですよね。

なので、コード管理しているgitリポジトリとは別にまっさらのgitリポジトリを作成してそちらにstage以下のコードを全部突っ込むことにしました。

手元にPlayアプリケーションがあるなら以下の手順で、Herokuに新しいアプリケーションを作成できます。

 

sbt stage

mkdir heroku
cp -rp target/universal/stage heroku

cd heroku

git init
git add .
(※1)
git commit -m "Initial commit"

heroku create -b https://github.com/shunjikonishi/heroku-buildpack-scala-compiled
git push heroku master

 

※1 Windows環境の場合はデフォルトではスクリプトに実行権が付かないので、ここで

git update-index --chmod=+x stage/bin/[APPNAME]

 を実行する必要があります。


このリポジトリはGitHub等の外部リポジトリにホストする必要はありません。コードさえあれば同じものをいつでも作れますし、別のマシンにコピーを作りたい場合はHerokuのgitからcloneしちゃえば良いので。

初回のコミットは標準ライブラリ等が山ほど入るので、少し遅い(それでもscala-buildpackよりは全然速い)ですが、標準ライブラリは基本変更されることがないので2回目以降のコミットでは自前のjarとconfファイル程度しか対象とはならないのでデプロイにかかる時間はわずか数秒です。素晴らしい。。。(^^v

初回はともかく2回目以降の手順はGrunt等で簡単にスクリプト化できるので、それなりに使い勝手は良いんじゃないですかね。(^^;

欠点はDashboardのActivityページからDiffが見られなくなることとかですかね。(GitHub Syncを使えばリリース毎のDiffがGitHubのページで見られます。)

あとはチーム開発時にデプロイ用のgitまで各メンバで同期する運用の場合、ちょっと面倒かもしれません。むしろCI連携で使った方が便利かも。。。

作ってはみたものの本当に使うかどうかはまだわかりませんが、興味のある方は触ってみてくださいな。(^^;


明日は@ponkotuyさんのMyFleetGirlsの話です。

2014年12月 4日 (木)

Gruntからherokuコマンドを実行する

ども。 Salesforce World Tour Tokyo, DeveloperZoneからこんにちは。

Heroku Advent Calendar 2014 4日目。2日ぶり3度目の登板の小西です。(--
今日を乗り切れば明日からはしばらくは乗り切れるようなので雑に埋めておきます。

本日のネタはこちら

https://gist.github.com/shunjikonishi/b42decee4446c0652cdd

さらっと作ったpgbackups:restoreをGruntから実行するタスクです。

child_process.execでherokuコマンドを叩いているだけなので、Nodeを使ったことのある人にはなんの新規性も無いかと思いますが、Grunt使っている人でも自分でタスクを書いたことの無い人も多いと思うのでさらっとご紹介します。

このタスクが行っている処理内容は以下です。

  • heroku pgbackups:urlを実行してrestoreしたいバックアップのダウンロードURLを取得する
  • heroku pgbackups:restoreを実行してリストア

いじょ。

バックアップを取得したアプリケーションとリストアしたいアプリケーションが同じであれば、pgbackups:urlを実行せずともバックアップIDでいきなりpgbackups:restoreを実行してしまえば良いんですが、開発環境で作ったデータをテスト環境でリストアするケースも多いので、このようにしています。

Gruntfileでタスクを定義する際に渡せるパラメータは以下です。

  • app: リストアを実行するアプリケーション名
  • backupId: リストアするバックアップのID
  • backupApp: バックアップを生成したアプリケーション名。省略時はappと同じ

いじょ。


JavaScriptはちょっと書けるけどNodeは触ったことがないという人向けにさらっとポイントを説明すると以下のような感じです。

  • gruntタスクの定義にはgruntオブジェクトを使用する
  • タスク名と説明(registerMultiTaskの最初の2つの引数)以外は変える必要が無い
  • コマンド実行にはchild_process#execを使用する
  • 複数のコマンドを連続して実行する場合はコマンド実行は非同期なのでコマンド終了時にemitterでイベントを発行し、それを受けて次のコマンドを実行するようにする
  • この例ではpgbackups:urlの終了時に「url」イベントを発行し、それを受けてpgbackups:restoreを実行する
  • 全部のコマンドを実行したらthis.asyncで返ってくるdoneメソッドを実行することでタスクが完了する

いじょ。


こんだけわかっていれば後は見よう見まねで書けるんじゃないですかね。(^^;;;

ちなみにこのrestorePgbackupsタスクはテスト専用の環境でデータを初期化するために使用していてわりと重宝しています。

□□□□

SFハッカソンに参加するので、ここから先は本当にしばらく気配を消します。

14日以降まで繋がっていればまた復活するかもしれませんが。。。(^^;;;

がんばれ! Heroku Advent Calendar

2014年12月 2日 (火)

Heroku Postgresのロールバック

この記事はHeroku Advent Calendar 2014の2日目です。



先ごろCodeZineにHeroku Postgresの記事を書いたんですが、そこでさらっと触れたHeroku PostgresのRollback機能について、実際の使い方を紹介したいと思います。



ほとんどの場合Rollbackの必要に迫られる場面は突発的に訪れ、かつ時間の制約も厳しかったりするんですが、これさえあれば安心です!(多分)


★ Heroku PostgresのRollbackとは

Databaseを扱ったことのある技術者でRollbackという用語を知らない人はいないと思いますが、ここでいうRollbackは世間一般に浸透しているトランザクション制御のためのRollbackのことではありません。

名前が紛らわしいので正直、名前変えたほうが良いんじゃないかと思ったりもしますが。。。(^^;;;
自分の言葉で説明するならば、これは

時間を指定してその時点のスナップショットから新しいDBを作成する機能

です。
Forkを使ったことある人ならForkで時間指定ができるようになっただけ、と捉えても良いです。(ちなみにForkというのは既存DBのスキーマやデータをコピーして新しいDBを作成する機能です。)

Rollbackが使用できるのはStandard-0以上のプランによって指定できる時間の制限が異なります。

  • Standard-X. 現在時刻から1時間前まで
  • Premium-X. 現在時刻から7日前まで


ちなみに指定できる時間は分単位までで、秒単位での指定はできません。


★ コマンド

実際にRollbackデータベースを作成するためのコマンドは以下

 

heroku addons:add heroku-postgresql:standard-0 --rollback green --to '2014-12-02 12:00+00:00'

 



見ての通り、通常のAddon追加のコマンドにロールバックに必要なパラメータを追加しているだけです。

「--rollback」にはロールバックの対象となるDBの色名の部分のみを指定します。
「--to」にはロールバックする時間をタイムゾーンつきで指定します。

ちなみに「--to」の代わりに、「--by 3 days 7 hours 22 minutes」のように何時間何分前に戻る!という指定の方法もあるんですが、時間を計算したりコマンドを叩いたりしているうちに時間が経過したらローブバックする時間もずれるので、はっきり言ってこのオプションの存在意義がわかりませぬ。。。(--

コマンドの実行にはそれなりに時間がかかります。試したところそれほど多くのデータの入っていないDBを数分過去の状態に戻すだけでも10分程度かかりました。

元々PostgresのAddon追加自体が数分を要しますし、データ量や巻き戻す時間によっても所要時間は変わってくると思います。
なので、コマンド実行後はpg:waitでDBの作成完了を待ったほうが良いです。

ロールバックDBの作成が完了したら、DBを置き換えて元のDBを削除します。
全体としてのコマンドシーケンスは以下のような感じです。(元のDBがgreen、作成したロールバックDBがblueの場合)

 

heroku addons:add heroku-postgresql:standard-0 --rollback green --to '2014-12-02 12:00+00:00'
heroku pg:wait
heroku pg:promote blue
heroku addons:remove HEROKU_POSTGRESQL_GREEN

 




★ バックアップは計画的に

以上が、ロールバックの使い方でしたが意外と簡単だったかと思います。そして非常に強力です。

ただ、個人的には障害時の対応をこれだけに頼り切るのは危険だとも思っています。
もちろん、選択肢のひとつとしてはあっても良いんですが実際に使うかどうかはケースバイケースのような気がしています。どの時間まで戻すのが適切なのかわからないこともあるだろうし、このようなめったに使われることのない機能にはバグや想定外の何かがあってもおかしくないですしね。

pgbackupsを入れるのは当然として、障害対応はある程度あらかじめシュミレーションしておくことが重要です。


★おまけ。Heroku Postgresの識別名

Heroku Postgresを追加するとご存知の通りconfigには「HEROKU_POSTGRESQL_<色名>_URL」という環境変数が設定されるわけですが、いざこれをコマンドで指定しようとすると以下のようないくつかのパターンがあります。

  • HEROKU_POSTGRESQL_BLUE (「_URL」がない)
  • blue (「HEROKU_POSTGRESQL_」も省略されている。ついでにCaseInsensitive)


つねづねかねがね「何だ?この一貫性の無さは。。。」と思ってたんですが、今回一連の操作を試していてなんとなく枠組みが見えてきました。
おそらく、

・HEROKU_POSTGRESQL_<色名>
Addon名。Heroku Postgresは1アプリケーションに複数追加できるのでそれを識別するための名前。
Addonを操作するコマンドではこちらを使用する

・<色名>
pg:xxxxコマンドなど、文脈からHeroku Postgresを指定することがわかる箇所では色名のみの省略記法が使用できる


ということなんではないかなぁと。(^^;(全部を確認したわけではないですが)

Addonの中でHeroku Postgresのみが同一Addonを複数追加できることにも違和感があったんですが、もしかしたらサードパーティ製のAddonでも複数追加できるものを作れるのかもしれません。

□□□□

明日は@anoworlさんによる画像アップロードの話です。
あとはがんばってください。(^^)/



2014年12月 1日 (月)

GitHub Syncは多分イケてる

ども、この記事はまったく完走できそうな気がしないHeroku Advent Calendar 2014の一発目です。(^^;

いや~、どうなるんでしょうね、これ。5、6日なら頑張ろうかなという気もするけど、20日は無理っすよ。。。

中旬はSFハッカソンとかもあるし、終盤までバトンが繋がったらそこから先はちょっとがんばります。(かもしれません。)

さて、そんなこんなの一発目のネタですが、GitHub Syncです。

本当は別のネタも考えてたんですが、数日前にA氏のつぶやいていたこの新機能がなかなか興味深かったのでとりあげてみます。

 

★ GitHub Syncとは

その名の通りHerokuとGitHubを同期させる機能です。

HerokuがGitHubのOAuthクライアントとなってGitHubに対してあれやこれやの操作を行います。

 

★ 下準備

GitHub Syncはまだlabsのベータ機能なので、使用するためにはまず以下のコマンドをたたく必要があります。

 

heroku labs:enable github-sync

 

User Featureなのでアカウントで一度有効化すればすべてのアプリケーションで使用できるようになります。

 

★ Dashboard

GitHub Syncを有効にするとHeroku DashboardのCodeタブに以下のような設定画面が表示されるようになります。

 

 

画面を見るとできることはほとんど一目瞭然なんですが、設定したGitHubリポジトリに対して以下の操作が行えます。

 

1、 任意のブランチからの手動デブロイ

この画面から任意のGitHubリポジトリ上の任意のブランチを選択してデプロイすることができます。

といっても、これは全くメインのFeatureではないので多分使うことはないです。(^^;

 

2、自動デプロイ

指定のブランチに対してpushやmergeが行われた際に自動的にデプロイを行うように設定できます。

ちなみにHerokuへのgit pushのフックとは異なり、ここでのフックは非同期です。

git push自体は何も設定していない場合と同様にすぐに終了し、その後に非同期でデプロイが実行されます。Scalaアプリで試したところデプロイには10分程度かかりました。(Scalaのコンパイルが遅いせいですけど。。。)

デプロイの成否はDashboardのActivityタブで見ることができます。

OAuthでリポジトリにアクセスしているのでPrivateリポジトリも問題ないはずです。

 

3、PullRequest時に毎回新規アプリを作成

これ、試してみたところ実はまだ動いてないようなのですが。。。

PullRequestを作るたびに自動で新しいHerokuアプリケーションを作成して、そこにPullReuqestの内容をデプロイするというかなりとんでもない機能です。(^^;

作成するアプリケーションはapp.jsonを参照するので、そこに使用するAddonや環境変数の情報を書いておけばそれらも自動的に設定されます。

ただ、DB等を使用する場合を考えた場合、この場合のapp.jsonの設定では「親アプリの設定値を引き継ぐ」ということができないと実質的には使えない気がします。

app.jsonにはgeneratorという書式があるので、それを拡張すれば割と簡単にできるとは思うのですが。。。。

まぁ当面成り行きを見守りたいと思います。

 

4、リリースの差分をGitHub上のDiff画面で見られる

これはひょっとしたら前からできてたのかもしれませんが。。。

Activityページの各リリースの行に前回リリースとのDiffを表示するGitHub画面へのリンクが追加されます。(PullRequestでおなじみのコミットAとコミットBを比較するあの画面です。)

はっきり言って便利です。GitHubでコード管理しているプロジェクトであれば、全部自動で設定して欲しいと思うくらいのレベル(^^;

まだ出たばかりのベータ昨日なのでPullRequest Syncが動いてないなど、怪しい部分もありますが、こういうのは時間の問題で直ると思うのであんまり気にしなくて良いです。

labsだからと躊躇せずにHerokuとGitHubを使っている人は全員使った方が良いと思います。

 

□□□□

Advent Calendar、初日からバトンが途切れるのもあれなので、明日も小西が連投します。

2014年11月 7日 (金)

AngularJSのValidationで、maxlength, minlengthのサロゲートペア対応

ども。

最近は某案件に突っ込まれているのでわりとAngularJSを使っています。

Angular、便利は便利なんですがちょっと癖がありますね~。

しかし、これの思想を理解しておくことは(特に設計等を考える立場の人にとっては)大変有益だと思います。

一度はがっつり使ってみておくのも良いんじゃないでしょうか。(^^;

(↑ これは個人的にはあんまり積極的には使わないという意味でもあるんですが。。。)

 

 

それはさておき、Validationです。

Angularではinput要素にng-requiredとかng-maxlengthとかをつけておくとFormのモデルに自動的にエラー情報が付加されます。

非常に便利です。(^^v

。。。が、このng-maxlength。割と後半になってからサロゲートペア未対応であることが判明!

えーーー。。。。(--;;;;

 

 

まぁ、言うてもJavaScriptはもともとサロゲートペアはまともに扱えないので予測はできてもおかしくなかったんですが、こういうのは必要に迫られるまでは忘れてますよね。。。(--

もう2010年代も半ばなんだから、フレームワーク側でサロゲートペアもよしなに扱ってほしいとは思うんですが、既にいっぱい使っちゃってるng-maxlengthをどう対処していくべきか。。。

 

 

★ 対処法

あんまりブログに時間かけてる場合でもないんで、さっくり答えを書いちゃうと自前でdirectiveを定義することでほとんど改修コストをかけずに修正することができました。

 

https://gist.github.com/shunjikonishi/2dbe5e8eab1ebd08e434

 

ここではsp-maxlength、sp-minlengthという2つのdirectiveを定義していますが、エラー情報の設定名はそれぞれ「maxlength」、「minlength」としています。(ng-maxlength, ng-minlengthが使用している名前と同じです。)

このため、input要素での宣言だけを「sp-maxlength」に置き換えてやれば、エラー表示の制御等で使用しているであろう

 

form.inputName.$error.maxlength

 

の部分は変更不要です。

ちゅーことで、単純なGREPと置換で対処することができました。

ちなみに同時に行った対処としてPlayframeworkのValidationでmaxlength, minlengthのサロゲートペア対応というのもあるんだけど、こっちはソースをコピってきて一部書き変えただけだから割愛。

めでたしめでたし(なのか?)

2014年10月29日 (水)

HerokuのprebootがGA

ども、最近火事場案件に突っ込まれててあんまりブログ書けておりませぬ。。。(--

本当は別の記事を書きかけてるんですが、なんかHerokuからお知らせ来てたので先にそっちの話を。

なんと未来永劫labsから抜け出ることは無いんじゃないかと思っていた、prebootがGAになったようです。

https://devcenter.heroku.com/articles/preboot

結構びっくり!

ドキュメント見ると微妙にlabsの頃と挙動が違っているようなので、ざっくりとまとめておきます。


★ 使い方

新たに追加されたと思われる「heroku features」コマンドを使います。

 

heroku features:enable preboot
heroku features:disable preboot

 



これまでと同様にデフォルトでは有効になっていないので使用するためには明示的にコマンドで有効化する必要があります。

また、prebootはWeb Dynoが2台以上起動していないと動作しません
別な言い方をすれば課金しているアプリでなければ使用出来ないということです。



★ 挙動

僕の記憶によればいくつか動作に変更点があります(多分)。以下の赤字が以前とは異なる部分です。

  • Slugコンパイル完了後、既存のDynoがシャットダウンされるよりも前に新しいDynoが起動する
  • デプロイから約3分後、古いDynoと新しいDynoのRoutingが切り替わる
  • さらにその数分後、古いDynoが削除される
  • prebootはデプロイ以外の環境変数の変更や再起動時にも有効
  • prebootはWeb Dynoでのみ機能し、Worker Dynoはこれまで同様シャットダウン後に新しいDynoが起動される


新しいDynoが起動してから、切り替えまで数分のタイムラグがある点と、デプロイ以外の再起動時にも有効になったと書かれている点が以前とは違います。

デプロイ完了しても数分間は旧バージョンが動き続けるというのは結構注意が必要な点かも知れません。
ざっと見た感じRoutingがスイッチしたタイミングではログがでていない気がするので、どこで切り替わったかはわからない気がします。(これは要望出そうかと思ってます。)

また、ドキュメントのこの書き方だとデイリー再起動時にもprebootは有効なように読めますが、少なくとも昨日のデイリー再起動ではprebootが行われた形跡はありません


labsの頃は(少なくとも僕がドキュメントを精読した時には)デプロイ時以外の挙動については触れられていなかったんですが、実際には環境変数の変更やheroku restartでもprebootは効いていました。

が、デイリー再起動だけは対象外だったんですよね。。。。(--


以前にもかなりしつこくデイリー再起動時にもprebootしてくれとお願いしているので、有効になっていてくれると嬉しいんですけどね。。。


★ 注意点

ドキュメントには新Dynoのアイドル時間が増えたことによっていくつか注意点ができたことも記されています。

  • これまでと違いgit pushからリターンしてもすぐには新バージョンが動かない
  • preboot中はheroku psコマンドの見方に注意が必要。新旧バージョンの両方がheroku psのリストに載ることはないが、「starting」と表示されていても旧Dynoが仕事中だったりする
  • 一時的にではあるが通常の2倍のDynoが起動しているのでその間RDBやRedisなどのコネクションを余分に消費する。特に安いプランで接続数が制限されている場合は注意が必要
  • DBのスキーマ変更を伴う場合はprebootはうまく機能しない可能性が高い。(何故ならデプロイ後も数分旧バージョンが動くが、それが新スキーマでも変わらず動作するかどうかは不明なため)。この場合はprebootを一度無効化する必要がある


こ、これは結構微妙。。。(--
特にスキーマ変更の話は注意が必要です。

ちなみにコネクションを余計に消費する問題に対してはpgbouncer buildpackというのがお勧めらしいですが、これの話はまた今度。

個人的にはデイリー再起動で有効なのかどうかでかなり大きく評価が分かれます。

とりあえず、明日のデイリー再起動の結果を待ちたいと思います。


続報をお待ちください。(^^;

★ 追記

やっぱりデイリー再起動時にはpreboot適用されないようです。残念

ただ、デイリー再起動は24時間+αの時間で実行されるので、日本だけで使うようなサービスの場合は毎日深夜3時とかに自力でrestartをかけるのは有効かもしれません。

2014年9月29日 (月)

プロフェッショナルのための実践Heroku入門

ちょっと遅くなりましたがHerokuの相澤さんより「プロフェッショナルのための 実践Heroku入門」を頂いたので軽く感想を書いておきます。



ページ数は180ページと若干薄めです。
アドオンやアーキテクチャのあたりはもう少し分量あっても良かったかな、という印象。
わりとすぐに全部読めちゃいます。

一回通しで流し読みした後は逆引きで使えるのが良いです。
ドメインやSSLの設定とかはHeroku使っててもやったことがない人も多いだろうからとっかかりとしてはとても良いと思います。
(ただし、UIとかはわりと頻繁に変わるので概要理解したら一度はDev Centerのドキュメントも見た方が良いです。)

ちなみにHerokuチョット使える身としてはほとんど既知の内容だったんですが、一個だけはじめて知った機能はこれ。

 

$ heroku logs -r prod

 

git remoteに複数のHerokuアプリケーションが登録されている場合に「--remote」または「-r」にgit remoteのエイリアスを指定することでアプリを指定できる

おおっ!
これまでずっと「-a <アプリ名>」でやってたよ。。。
こっちの方が大分タイプ量が減るので便利。(^^v


個人的に一番面白かったのは「はじめに」のHerokuの歴史のところです。僕がはじめてHerokuに触ったのはJavaサポートが入った頃なので、それ以前の歴史は興味深かったです。


あと最後のThe Twelve Factor Appもお勧め。

The Twelve Factor Appはネット上にも日本語訳ありますが、これはWebアプリを開発する人は全員読んだ方が良いと思う位の良プラクティスです。
Heroku使わない場合でも有効なプラクティスなので、できるだけ多くの人に読んでもらいたい。(^^;



そして、これこそが僕がHerokuを好きな理由でもあります。

Herokuを使うと、これらのプラクティスが半ば強制的に適用されるようになっているんですが、何が凄いってそれでいてベンダーロックインにならないんですよね。
Herokuで作ったアプリは割と簡単にAWS等の別の環境に移すことができます。

これは本当に凄いことだと思います。
ベンダーはあの手この手でユーザを自社環境に縛りつけようとするものですが、そのための一番簡単な手段(=うちの環境使うとこんなに簡単にアプリ作れますよー、そのかわり他の環境では動かないけど)を放棄しているので。

逆から言うと、Heroku以外の環境を使う場合でもベンダー独自機能の誘惑に負けずTwelve Factorは適用すべきとも言えます。
それによってベンダーロックインから逃れることができるので。

大事なことなのでもう一回言いますが、Herokuを使うとTwelve Factorが半ば強制的に適用されます。読んでみて内容はわかるけどイマイチぴんとこない、という人は一度Herokuを使ってみると良いと思います。
最初は不便に感じるかもしれませんが、使っているうちに自然にTwelve Factorが身に付きます。

書籍の冒頭にも書いてありますが、Herokuの理念は「アプリケーション開発者の生産性を高めること」であり僕の関わったこの数年ではその理念はまったくぶれていないと感じます。
Herokuには是非ともこのままがんばってほしいものです。

本当にもうあとは日本に来てくれさえすれば何の文句もありません。

2014年9月12日 (金)

ScalaMatsuriに行ってきた話

先週末はScalaMatsuriでした。
非常に内容の濃い2日間でとても勉強になりました。

本当は2日目は途中で離脱する予定だったんですが、あまりにも面白かったので結局最後までいちゃいましたからね。(^^;

Scalaの懐はあまりにも深く、チョットカケルようになった位ではまったくその深淵には辿りつけないということを改めて実感しました。
それが面白いところでもあるんですけど。(^^;

セッション中も本編よりも端の方にさらっと書かれている知らないワードをググって芋づる式に新事実(俺が知らなかっただけ)に気付かされることも度々。

ちなみにそんな中で個人的な最大のヒットはこれです。

Iterator.continually()を使おう


こんなメソッドあるなんて全然知らなかった。。。
今までJavaのInputStreamを読む時はあきらめてvarを使ってましたが、これがあればvalだけでいけますね。(^^;
(場所によっては甘えだと怒られるようです(Scala怖い)。僕は絶対に使いたくない!と言うほどに否定的ではないですが極力使わない方が良いですね。)

セッションで面白かったのは

- 小田好先生のScalaの歴史、未来、哲学の話
- sbtのお話
- Node.js vs Play
- マクロの話
- RubyとScalaの話
- HaskellとScalaの話
- コードレビューの話
- GitBucket会議

などです。
初日のセッションは全部ニコ生で見られるようなので興味ある人は見てみると良いと思います。

http://live.nicovideo.jp/watch/lv191315006

なんか再生数が凄いことになってますが。。。(^^;;;
僕もいくつか裏番組気になってるものがあるので週末に見ます。


本当は終わり間際にツィートしてたHerokuでScalaのコンパイルをスキップする方法についてちょっとトライしたのでその顛末について書こうと思ってたんですが、ScalaMatsuriを振り返ってたら結構な時間を消費しちゃったのでまた今度にします。
(ちなみに結論はできることはわかったけど多分イマイチです。)



最後に今回のScalaMatsuriを企画・運営されたスタッフの皆様に心から感謝申し上げます。
ハッピ着たスタッフの人達20人以上いたんじゃないですかね。こんなにもScalaを盛り上げようとしている人がたくさんいるのかということに驚いたし嬉しくもなりました。
Scalaもっとメジャーになると良いですね。

ちょっと前までは入門者から初心者になるまでのハードルがものすごい高かったけど最近はそうでもないので、とりあえず皆触ってみると良いよ。(^^;

2014年8月25日 (月)

Herokuのkensaがおもしろい

ども。
最近Herokuの提供するkensaというツールをちょっと触ったんですが、これがなかなかユニークな代物だったんでちょっと紹介してみたいと思います。

★ kensaとは

HerokuのAddon Provider向けに提供されているAddonインターフェース作成の補助ツールです。
Ruby製のコンソールアプリなのでgem installでインストールすることが出来ます。
おそらく名前の由来は日本語の「検査」で、文字通りAddonインターフェースの実装が正しく行われているかどうかを検査してくれるものです。

Heroku Addonの多くは実体は独立したWebサービスです。
それをAddon化するためにはサービス側でいくつかのHerokuが規定するAPIを実装する必要があります。
例えば

  • heroku addons:add コマンド実行時に新しいユーザを作成しその情報を返す
  • heroku addons:update でプラン変更を行う
  • Heroku Dashboardからシングルサインオンで管理画面を表示する

などです。
これらはすべてWebAPIとして実装する必要があるわけですが、kensaはその実装URLに対して様々なテストを実行してくれます。

  • HTTPレスポンスが200 OKで返ってくるか?
  • Basic認証が正しく実装されているか?
  • レスポンスボディがJSONになっているか?
  • JSON内に必要な情報が含まれているか?

などなど。

これ、つまりテスト駆動開発で最初からテストが揃っている状態で開発できるということなんです。
もちろん、サービス側のブラックボックスである実際のユーザ登録などのバックエンド処理はkensaでテストすることはできないわけですが、まだ何も実装していない状態で、kensaのテストが404 Not Foundで落ちるのを確認するところからはじめて、すべてのテストをクリアするまで実装を進めていくというのはなかなか面白い経験でした。

実際にテスト駆動開発を行っている場合でも、先にテストだけが全部揃っているという状況はなかなか無いでしょうしね。(^^;


★ なんか色々応用出来そう

実際に試してみて思ったのは数あるテストをクリアしていくのはなんかゲームみたいで楽しいな、ということです。

個人的には新人研修の最後や入社試験なんかでこうした課題があると面白いんじゃないかと思いました。
他にもプログラミング教育系のサービスに取り込んでも面白いでしょう。
所用時間や実行回数を計測してランキング化するゲームにするのもアリです。

ていうか、むしろ自分で作りてーとちょっと思いました。(いやマジで)(^^;

ちなみにkensaの使い方と作るべき課題の説明はこちらです。

https://devcenter.heroku.com/articles/building-a-heroku-add-on

バックエンドの処理を実装せずにkensaに合格するだけのものを作るだけなら、速い人なら1時間くらいでクリアできると思います。(Herokuまったく使ったことが無いと実装すべきもののイメージがわからなくて辛いと思いますけど)

社内で新人の教育なんかにも関わる立場の人であれば一回触ってみると面白いかもしれませんよ(^^;

2014年8月19日 (火)

Heroku Postgresのメンテナンス時間が選べるらしい

今朝はHerokuからこんなサブジェクトのメール来てました。

Set the maintenance window for your database

どうやらHeroku Postgresにセキュリティパッチを充てるために停止を伴うメンテナンスが行われるらしい。

ここまでは過去にも数回あったことだしまたか、という感じなわけですが今回のメールがちょっと違うのは必要だったらメンテナンスの希望時間を設定しろ、という文章が続いてたこと。

$ heroku pg:maintenance window="Friday 18:15" pink -a myapp

というコマンドで希望時間を設定できるようです。(時刻はUTC。Fridayっていつのだよ?って思うけど普通に考えて次の金曜日のことでしょうね。)

詳細なドキュメントはこちら。

https://devcenter.heroku.com/articles/heroku-postgres-maintenance

これ見ると希望への対応はBest Effort(前後4時間)で、Standard/Premium-4より上のプランでのみ希望時間を設定できるようですね。

実際に作業を行う人達は多分サンフランシスコだからちょうど日本と昼夜逆転してて日本時間の深夜帯での希望は結構通りやすいんじゃないですかね。

また、heroku pg:info でメンテナンスの予定時刻も確認できるようです。(手元で試したら何故かnot requiredになってたけど。。。)

あれ?でも、このメールをうけた対象DBはRonin(Standard-2相当)なんだけど。。。。???

旧プランの扱いがなんかおかしいんだろうか。。。(--

pg:infoの件と言い、メンテナンス自体が手動で行われるものであるならメンテナンス時刻の設定も自動ではないと思うので、その辺若干怪しいにおいがしないでもない。。。

メンテナンス自体がちゃんと行われるのであればこうした周辺機能(サービスというべきか)が少々おかしくても文句はないですけどね。

ていうか、Postgresのプランをあげなければ。。。(--

採用情報

株式会社フレクトでは、事業拡大のため、
Salesforce/Force.comのアプリケーション
開発
HerokuやAWSなどのクラウドプラッ
トフォーム上でのWebアプリケーション開発

エンジニア、マネージャーを募集中です。

未経験でも、これからクラウドをやってみた
い方、是非ご応募下さい。

フレクト採用ページへ

会社紹介

株式会社フレクトは、
認定コンサルタント
認定上級デベロッパー
認定デベロッパー
が在籍している、
セールスフォースパートナーです。
heroku partnersにも登録されています。
herokuパートナー
株式会社フレクトのSalesforce/Force.com
導入支援サービス
弊社の認定プロフェッショナルが支援致します。
・Visualforce/Apexによるアプリ開発
・Salesforceと連携するWebアプリ開発
も承っております。
セールスフォースご検討の際は、
お気軽にお問合せください。
Powered by Six Apart