73
Play2.0+Javaサービスを本番 稼働させた話 @i2key ※以後の発表内容は会社は関係なく 私の個人的な見解・思考・思想に基づくものになります。

Play2.0+Javaでサービスを本番稼働させた話 #play_ja

Embed Size (px)

DESCRIPTION

http://attacca.fm/ でPlay2.0+Javaを採用した経緯について等について発表しました。http://attacca.fm/posts/song/v1/0e3cf1c612075954c429dd69bdda6843

Citation preview

Page 1: Play2.0+Javaでサービスを本番稼働させた話 #play_ja

Play2.0+Javaで  サービスを本番稼働させた話  

@i2key    

※以後の発表内容は会社は関係なく  私の個人的な見解・思考・思想に基づくものになります。  

Page 2: Play2.0+Javaでサービスを本番稼働させた話 #play_ja

@i2key  元SIer  Java屋  最近ObjC

Page 3: Play2.0+Javaでサービスを本番稼働させた話 #play_ja

皆様  

Page 4: Play2.0+Javaでサービスを本番稼働させた話 #play_ja

音楽は好きですか?  

Page 5: Play2.0+Javaでサービスを本番稼働させた話 #play_ja

普段どんな曲を  聴いていますか?  

Page 6: Play2.0+Javaでサービスを本番稼働させた話 #play_ja

あなたのプレイリストは懐メロばかりになっちゃあいませんか?

Page 7: Play2.0+Javaでサービスを本番稼働させた話 #play_ja

学生の頃に比べると明らかに、新しい音楽へ出会う機会が減っている。

Page 8: Play2.0+Javaでサービスを本番稼働させた話 #play_ja

毎日が忙しく、音楽に出会う場

(クラブ、フェス、ライブハウス、カラオケ等)

にいかなくなった。

h)p://jigokuno.img.jugem.jp/20090624_1292358.gif

Page 9: Play2.0+Javaでサービスを本番稼働させた話 #play_ja

毎日が忙しく、音楽に出会う番組

(ドラマ、音楽番組、CM等)

を見なくなった。

h)p://jigokuno.img.jugem.jp/20090922_1475978.gif

Page 10: Play2.0+Javaでサービスを本番稼働させた話 #play_ja

•  時間がないので音楽を探すのはオンラインばかり。

– しかし、オンラインは思いのほか能動的に動かないと探せない。(TVやラジオの反対)

– 音楽番組を見てたころは、いつの間にか流行の音楽が耳に入っていたなぁ。

Page 11: Play2.0+Javaでサービスを本番稼働させた話 #play_ja

音楽のランキング番組を見てたように、受動的に音楽聴きたいなー。

Page 12: Play2.0+Javaでサービスを本番稼働させた話 #play_ja

どうせ聴くなら、友達が聴いてる曲を知りたい。  

Page 13: Play2.0+Javaでサービスを本番稼働させた話 #play_ja

そんな思いを解決してくれます。  そう、この「A8acca」ならね。

h8p://a8acca.fm

Page 14: Play2.0+Javaでサービスを本番稼働させた話 #play_ja

h)p://www.google.co.jp/imgres?num=10&um=1&hl=ja&biw=1623&bih=832&tbm=isch&tbnid=aaEe9GiNRXBbqM:&imgrefurl=h)p://seiga.nicovideo.jp/seiga/im1343303&docid=pxtVREKFNTjFM&imgurl=h)p://lohas.nicoseiga.jp/thumb/1343303i&w=450&h=600&ei=-­‐WD-­‐T8GwPOfEmQWCn52OBQ&zoom=1&iact=hc&vpx=445&vpy=130&dur=1282&hovh=259&hovw=194&tx=88&ty=102&sig=102960426298510789252&sqi=2&page=1&tbnh=  160&tbnw=119&start=0&ndsp=33&ved=1t:429,r:2,s:0,i:73

Page 15: Play2.0+Javaでサービスを本番稼働させた話 #play_ja

h)p://livedoor.blogimg.jp/coodoo/imgs/5/a/5ae655d9.jpg

Page 16: Play2.0+Javaでサービスを本番稼働させた話 #play_ja

h)p://jigokuno.img.jugem.jp/20090119_824857.gif

Page 17: Play2.0+Javaでサービスを本番稼働させた話 #play_ja

デモンストレーション

Page 18: Play2.0+Javaでサービスを本番稼働させた話 #play_ja

Play導入の経緯

Page 19: Play2.0+Javaでサービスを本番稼働させた話 #play_ja

System  Integrator  

元SIer  Architect

Page 20: Play2.0+Javaでサービスを本番稼働させた話 #play_ja

官公庁系システム

Page 21: Play2.0+Javaでサービスを本番稼働させた話 #play_ja

数百億円規模

Page 22: Play2.0+Javaでサービスを本番稼働させた話 #play_ja

エクセル駆動開発

推進

\エクセル方眼紙バンザーイ/    

エクセル方眼紙から  どーんとJavaソースを自動生成して  

ばーん

Page 23: Play2.0+Javaでサービスを本番稼働させた話 #play_ja

人 海 戦 術

Page 24: Play2.0+Javaでサービスを本番稼働させた話 #play_ja

いろいろな病気を  こじらせたまま転職  

Page 25: Play2.0+Javaでサービスを本番稼働させた話 #play_ja

モジュール

RP1029Logic.javaへのコ

ミットログが多すぎるから、このモジュール作成者の品質に不安がある(キリッ  この開発者の作成したモジュールの横並び確認をしなければ!!  

Page 26: Play2.0+Javaでサービスを本番稼働させた話 #play_ja

サイクロマチック複雑度は??サイクロマチック複雑度と分岐網羅(C1)のテストケース数は大体近似できるから、それ以下だったら試験不足です。  はい、やりなおしー。  

Page 27: Play2.0+Javaでサービスを本番稼働させた話 #play_ja

凝集性がぁ〜。  

Page 28: Play2.0+Javaでサービスを本番稼働させた話 #play_ja

モジュール間結合度が〜。  

Page 29: Play2.0+Javaでサービスを本番稼働させた話 #play_ja

バグ密度は??    件/kstepで出してください。  試験密度も添えてね。  

Page 30: Play2.0+Javaでサービスを本番稼働させた話 #play_ja

え?当然、  カバレッジ100%でしょ?  

Page 31: Play2.0+Javaでサービスを本番稼働させた話 #play_ja

バグ改修はエクセル(方眼紙)を修正して、そこからソースコードを再生成してくださいネ。  

Page 32: Play2.0+Javaでサービスを本番稼働させた話 #play_ja

h)p://to-­‐a.ru/6CN9s2/img1

Page 33: Play2.0+Javaでサービスを本番稼働させた話 #play_ja

大規模開発のためのパラダイムで  小規模開発の現場に入ってしまったため、  前職と同等のアーキテクチャで  サービス開発をはじめてしまった。  

Page 34: Play2.0+Javaでサービスを本番稼働させた話 #play_ja

非機能要件からのアーキテクチャ設計  from  非機能要求グレード(IPA)抜粋

•  可用性  – 継続性(稼働率)、耐障害性、災害対策、回復性  

•  性能・拡張性  –  TX処理量、性能目標、リソース拡張性、性能品質保証  

•  運用・保守性  – 通常運用(運用時間・バックアップ・運用監視)  – 保守運用、障害時運用、運用環境、サポート体制  

•  セキュリティ  – 前提条件・制約条件、セキュリティリスク、アクセス利用

制限(認証、利用制限)、データ暗号化、不正追跡・監視、ネットワーク、Web対策  

Page 35: Play2.0+Javaでサービスを本番稼働させた話 #play_ja

Tomcat DIコンテナ

O/R  Mapper 制

制御

API  KEY認証

JVM Apache  

JSON  

XML  JSONP  

エラー処理

controller

facade

dao

APNS

C2DM

Pooling

Amazon  Linux  (MTL  Amazon  Image)

SSL  

Port

変換  

Twi)er

dao

facade

h)ps

RDS

HTML  

ビジネスロジック  (機能毎に実装)

ミドルウェア OS FW FW独自拡張

初代Architecture

Page 36: Play2.0+Javaでサービスを本番稼働させた話 #play_ja

Tomcat DIコンテナ

O/R  Mapper 制

制御

API  KEY認証

JVM Apache  

JSON  

XML  JSONP  

エラー処理

controller

facade

dao

APNS

C2DM

Pooling

Amazon  Linux  (MTL  Amazon  Image)

SSL  

Port

変換  

Twi)er

dao

facade

h)ps

RDS

HTML  

ビジネスロジック  (機能毎に実装)

ミドルウェア OS FW FW独自拡張 非機能要件をカバー

非機能要件  

非機能要件  

機能要件  

MTL  Java  Server  Architecture

Page 37: Play2.0+Javaでサービスを本番稼働させた話 #play_ja

Tomcat DIコンテナ

O/R  Mapper 制

制御

API  KEY認証

JVM Apache  

JSON  

XML  JSONP  

エラー処理

controller

facade

dao

APNS

C2DM

Pooling

Amazon  Linux  (MTL  Amazon  Image)

SSL  

Port

変換  

Twi)er

dao

facade

h)ps

RDS

HTML  

ビジネスロジック  (機能毎に実装)

ミドルウェア OS FW FW独自拡張 非機能要件をカバー

非機能要件  

非機能要件  

MTL  Java  Server  Architecture

Page 38: Play2.0+Javaでサービスを本番稼働させた話 #play_ja

反省点 •  大規模開発の設計思想を取り入れすぎたことによ

り、フットワークの低下が発生。  –  インタフェースドリブンにし過ぎ  •  大規模開発では関係が疎になったモジュー

ル設計のほうが、責務の所在が明確化し、品質が安定するが、開発者が少ない開発ではオーバーヘッドでしかない。  

– スピード感・イライラ感  •  確認にTomcat起動はキツい・・・  

–  前工程での仕様フィックスを前提とした実装  •  テーブル定義の動的な変更に弱い  – Railsのマイグレーションとかうらやましい  

Page 39: Play2.0+Javaでサービスを本番稼働させた話 #play_ja

300人で2年かけて作っていた世界    

から    

2人で2ヶ月で作る世界  

Page 40: Play2.0+Javaでサービスを本番稼働させた話 #play_ja

h)p://www.town.kaminokawa.tochigi.jp/f_sangyousinkou/P2_ph_2.jpg

300人で2年間で受託開発  開発モデル   ウォーターフォール(工程毎に品質評価会議)  開発方法論   契約による設計(高凝集性で低結合度)    ロールの過度な分割(業務SE、業務プログラマ、方式エンジニア)    インタフェースドリブンな実装(複数社がモジュール開発・結合)    疎結合による責務の所在の明確化     テスタビリティの向上によるモジュール品質の担保   全社的に統一したフレームワークで品質・生産性の平準化    ゴール感   リリースがゴール  価値観   お客様に納品するためにはバグは許されない。   品質が大事で、   納期も大事で、コストも大事で   要件を全部満たすことも大事  

Page 41: Play2.0+Javaでサービスを本番稼働させた話 #play_ja

h)p://image.space.rakuten.co.jp/lg01/83/0000069883/72/imgcd88f518zikbzj.jpeg

2人で2ヶ月で  自社サービス開発  開発モデル   ウォーターフォールではなく  アジャイルでもない何か    開発方法論   アジャイルのプラクティスもろもろ   要件の変更が多く   仕様フィックスはリリース直前    ゴール感   リリースははじまり  ゴールは、サービスのヒット、マネタイズ    価値観   リリース遅延=機会損失   ユーザに使ってもらってFBを即反映   バグってたら、急いで直してリリース  

Page 42: Play2.0+Javaでサービスを本番稼働させた話 #play_ja

つまり、自社サービスは  よく変更が入�るし、  よくリリースするし、  速く開発したい  品質は少しぐらい悪くても  すぐ直せればいいよ

Page 43: Play2.0+Javaでサービスを本番稼働させた話 #play_ja

Javaなんてやってないで、  Railsやろうぜ!  Rubyをキメルと気もちいぜ!  

h)p://naglly.com/funny_japanese_t_thirt_13.jpg

Page 44: Play2.0+Javaでサービスを本番稼働させた話 #play_ja
Page 45: Play2.0+Javaでサービスを本番稼働させた話 #play_ja
Page 46: Play2.0+Javaでサービスを本番稼働させた話 #play_ja

2.0 いずれ開発言語をJavaからScalaに移行したい

Page 47: Play2.0+Javaでサービスを本番稼働させた話 #play_ja

大規模  高品質

小規模  フットワーク  

Page 48: Play2.0+Javaでサービスを本番稼働させた話 #play_ja

REST  APIサーバとして  Play!2.0を採用  

やることは、リクエストを受け取って、JSONを返すだけ

Page 49: Play2.0+Javaでサービスを本番稼働させた話 #play_ja

いいか?  リファレンス以上の内容は  出てこないぞ?  

h)p://naglly.com/funny_japanese_t_thirt_13.jpg

Page 50: Play2.0+Javaでサービスを本番稼働させた話 #play_ja

     

Dynamo  DB  

AWS  SDK

Playframework  2.0

制御

制御

API  KEY認証

JVM Apache  

JSON  

エラー処理

controller

Manager APNS

C2DM

Amazon  Linux  (MTL  Amazon  Image)

SSL  

Port

変換  

Twi)er

Model

h)ps

Dynamo HTML  

ビジネスロジック  (機能毎に実装)

ミドルウェア OS FW FW独自拡張

A8acca  Architecture

Manager

Model

Page 51: Play2.0+Javaでサービスを本番稼働させた話 #play_ja

     

Dynamo  DB  

AWS  SDK

Playframework  2.0

制御

制御

API  KEY認証

JVM Apache  

JSON  

エラー処理

controller

Manager APNS

C2DM

Amazon  Linux  (MTL  Amazon  Image)

SSL  

Port

変換  

Twi)er

Model

h)ps

Dynamo HTML  

ビジネスロジック  (機能毎に実装)

ミドルウェア OS FW FW独自拡張

A8acca  Architecture

Manager

Model

←AOP的な  ことがしたい

Page 52: Play2.0+Javaでサービスを本番稼働させた話 #play_ja

     

Dynamo  DB  

AWS  SDK

Playframework  2.0

制御

制御

API  KEY認証

JVM Apache  

JSON  

エラー処理

controller

Manager APNS

C2DM

Amazon  Linux  (MTL  Amazon  Image)

SSL  

Port

変換  

Twi)er

Model

h)ps

Dynamo HTML  

ビジネスロジック  (機能毎に実装)

ミドルウェア OS FW FW独自拡張

A8acca  Architecture

Manager

Model

public  class  Global  extends  GlobalSeQngs  {    @Override    public  void  onStart(ApplicaTon  app)  {                  Logger.info("A)acca  is  ready!!");              //  Init  DynamoDB.              AmazonDynamoDBClientFactory.init();    }    @Override    public  AcTon  onRequest  

                                   (Request  request,  Method  acTonMethod)  {                            //リクエスト実行時に処理を織り込める  

               return  super.onRequest(request,  acTonMethod);    }              :  

}

Page 53: Play2.0+Javaでサービスを本番稼働させた話 #play_ja

     

Dynamo  DB  

AWS  SDK

Playframework  2.0

制御

制御

API  KEY認証

JVM Apache  

JSON  

エラー処理

controller

Manager APNS

C2DM

Amazon  Linux  (MTL  Amazon  Image)

SSL  

Port

変換  

Twi)er

Model

h)ps

Dynamo HTML  

ビジネスロジック  (機能毎に実装)

ミドルウェア OS FW FW独自拡張

A8acca  Architecture

Manager

Model

   //メソッド単位にもインターセプターを設定可能  @With(VerboseAcTon.class)          public  staTc  Result  index()  {                  CommonResult  result  =  new  CommonResult();                  result.setStatus("OK");                  return  ok(Json.toJson(result));                            }      /**    *  インターセプト用のAcpon例.    */  public  class  VerboseAcpon  extends  Acpon.Simple  {                    public  Result  call(H)p.Context  ctx)  throws  Throwable  {                                  //  必要に応じて前処理を実装 //  ラップしているAcponを呼び出し return  delegate.call(ctx);                  }  }

Page 54: Play2.0+Javaでサービスを本番稼働させた話 #play_ja

     

Dynamo  DB  

AWS  SDK

Playframework  2.0

制御

制御

API  KEY認証

JVM Apache  

JSON  

エラー処理

controller

Manager APNS

C2DM

Amazon  Linux  (MTL  Amazon  Image)

SSL  

Port

変換  

Twi)er

Model

h)ps

Dynamo HTML  

ビジネスロジック  (機能毎に実装)

ミドルウェア OS FW FW独自拡張

A8acca  Architecture

Manager

Model

←エラーハン  ドリングしたい

Page 55: Play2.0+Javaでサービスを本番稼働させた話 #play_ja

     

Dynamo  DB  

AWS  SDK

Playframework  2.0

制御

制御

API  KEY認証

JVM Apache  

JSON  

エラー処理

controller

Manager APNS

C2DM

Amazon  Linux  (MTL  Amazon  Image)

SSL  

Port

変換  

Twi)er

Model

h)ps

Dynamo HTML  

ビジネスロジック  (機能毎に実装)

ミドルウェア OS FW FW独自拡張

A8acca  Architecture

Manager

Model

public  class  Global  extends  GlobalSeQngs  {            :  

 @Override    public  Result  onError(Throwable  paramThrowable)  {      //エラー処理記述//      return  Results.ok(Json.toJson(result));    }  

   @Override    public  Result  onHandlerNotFound(String  paramString)  {      Logger.warn(“404  ERROR");      return  Results.redirect("/");    }        @Override    public  Result  onBadRequest  

                                   (String  paramString1,  String  paramString2)  {      Logger.warn(”404  ERROR");      return  Results.redirect("/");    }  

}

Page 56: Play2.0+Javaでサービスを本番稼働させた話 #play_ja

     

Dynamo  DB  

AWS  SDK

Playframework  2.0

制御

制御

API  KEY認証

JVM Apache  

JSON  

エラー処理

controller

Manager APNS

C2DM

Amazon  Linux  (MTL  Amazon  Image)

SSL  

Port

変換  

Twi)er

Model

h)ps

Dynamo HTML  

ビジネスロジック  (機能毎に実装)

ミドルウェア OS FW FW独自拡張

A8acca  Architecture

Manager

Model ←Object  –  JSON  Mappingしたい

Page 57: Play2.0+Javaでサービスを本番稼働させた話 #play_ja

     

Dynamo  DB  

AWS  SDK

Playframework  2.0

制御

制御

API  KEY認証

JVM Apache  

JSON  

エラー処理

controller

Manager APNS

C2DM

Amazon  Linux  (MTL  Amazon  Image)

SSL  

Port

変換  

Twi)er

Model

h)ps

Dynamo HTML  

ビジネスロジック  (機能毎に実装)

ミドルウェア OS FW FW独自拡張

A8acca  Architecture

Manager

Model

return  ok(Json.toJson(result));

Page 58: Play2.0+Javaでサービスを本番稼働させた話 #play_ja

     

Dynamo  DB  

AWS  SDK

Playframework  2.0

制御

制御

API  KEY認証

JVM Apache  

JSON  

エラー処理

controller

Manager APNS

C2DM

Amazon  Linux  (MTL  Amazon  Image)

SSL  

Port

変換  

Twi)er

Model

h)ps

Dynamo HTML  

ビジネスロジック  (機能毎に実装)

ミドルウェア OS FW FW独自拡張

A8acca  Architecture

Manager

Model          ↑  入力チェックしたい

Page 59: Play2.0+Javaでサービスを本番稼働させた話 #play_ja

     

Dynamo  DB  

AWS  SDK

Playframework  2.0

制御

制御

API  KEY認証

JVM Apache  

JSON  

エラー処理

controller

Manager APNS

C2DM

Amazon  Linux  (MTL  Amazon  Image)

SSL  

Port

変換  

Twi)er

Model

h)ps

Dynamo HTML  

ビジネスロジック  (機能毎に実装)

ミドルウェア OS FW FW独自拡張

A8acca  Architecture

Manager

Model

public  stapc  class  Hello  {                  @Required  public  String  name;                  @Required  @Min(1)  @Max(100)  public  Integer  repeat;                  public  String  color;  }    public  stapc  Result  sayHello()  {                  Form<Hello>  form  =  form(Hello.class).bindFromRequest();                  if(form.hasErrors())  {                          return  badRequest();                  }  else  {                          Hello  data  =  form.get();  

       return  ok(Json.toJson(data));                  }}

Page 60: Play2.0+Javaでサービスを本番稼働させた話 #play_ja

Play!で  iOS開発が  こんなに便利!!(ステマ)  

h)p://img5.blogs.yahoo.co.jp/ybi/1/83/95/dreamjapan04/folder/1564969/img_1564969_39575309_0?1201531988

Page 61: Play2.0+Javaでサービスを本番稼働させた話 #play_ja

iPhone  –  Server間  のI/F仕様の  ドキュメントレス化  (ソースが設計書)  

Page 62: Play2.0+Javaでサービスを本番稼働させた話 #play_ja

@vulcaniz @i2key

iOS

Playでスタブ  Controller(空)  Model(属性)

Play  Controller(実装)  

Model(属性+Validate)  DynamoDB(永続化)  

もろもろ Model

渡す

Page 63: Play2.0+Javaでサービスを本番稼働させた話 #play_ja

テストが楽  動かしながら実装できるのは楽  Managerからやって積み上げる感じ  その後コントローラー    Junit準備がいらないからいきなり試験かけて楽      DynamoのNoSQLがらく(SQLかくのだるい)  

Page 64: Play2.0+Javaでサービスを本番稼働させた話 #play_ja

TIPS  h)p://gigazine.jp/img/2007/09/29/potechi_gomamayo/potechi_gomamayo03.jpg

Page 65: Play2.0+Javaでサービスを本番稼働させた話 #play_ja

Amazon  EC2  microでPlay!2.0が起動しない。    java  -­‐Xms512M  -­‐Xmx1536M  でPlay!2.0はデフォルト起動される  

Page 66: Play2.0+Javaでサービスを本番稼働させた話 #play_ja

conf/routesの定義を変更しても反映されない。     つ $  clean  

Page 67: Play2.0+Javaでサービスを本番稼働させた話 #play_ja

ステージングモードでの  バックグラウンド実行がCTRL  -­‐  Dが必要になっていて、スクリプトで自動化できない。    $  play  start  &      ではなく  $  play  clean  compile  stage  $  target/start  &  

Page 68: Play2.0+Javaでサービスを本番稼働させた話 #play_ja

負荷試験でエラーでまくった  

Page 69: Play2.0+Javaでサービスを本番稼働させた話 #play_ja

Thrown(  akka.pa8ern.AskTimeoutExcepTon:  Timed  out)  

Page 70: Play2.0+Javaでサービスを本番稼働させた話 #play_ja

h)p://t3.gstapc.com/images?q=tbn:ANd9GcRanRMXzrPAKMq1JheavSmik2E5pYk3pK69vCisdXBXfiSKaCuKpLWRnd3v

Page 71: Play2.0+Javaでサービスを本番稼働させた話 #play_ja

完全にTomcat脳というかJ2EE脳だったので、Play(Ne)y+Akka)の仕組みを理解していなかった。    Hozumiさんの日記  Ne)yの基本 h)p://d.hatena.ne.jp/fatrow/20110208/ne)y    解決策は以下  h)p://www.playframework.org/documentapon/2.0.1/AkkaCore      

Page 72: Play2.0+Javaでサービスを本番稼働させた話 #play_ja

play  {          akka  {                  event-­‐handlers  =  ["akka.event.slf4j.Slf4jEventHandler"]                  loglevel  =  WARNING                                    actor  {                              deployment  {                                  /acpons  {                                          router  =  round-­‐robin                                          nr-­‐of-­‐instances  =  512                                  }                                    /promises  {                                          router  =  round-­‐robin                                          nr-­‐of-­‐instances  =  24                                  }                          }                          retrieveBodyParserTimeout  =  3  second                          acpons-­‐dispatcher  =  {                                  fork-­‐join-­‐executor  {                                          parallelism-­‐factor  =  256.0                                          parallelism-­‐max  =  512                                  }                          }

AcTon  Invoker  Actors  Booooooooost!!

Page 73: Play2.0+Javaでサービスを本番稼働させた話 #play_ja

以上!!