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

Post on 25-Dec-2014

16.819 views 2 download

description

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

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

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

@i2key    

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

@i2key  元SIer  Java屋  最近ObjC

皆様  

音楽は好きですか?  

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

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

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

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

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

にいかなくなった。

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

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

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

を見なくなった。

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

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

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

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

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

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

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

h8p://a8acca.fm

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

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

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

デモンストレーション

Play導入の経緯

System  Integrator  

元SIer  Architect

官公庁系システム

数百億円規模

エクセル駆動開発

推進

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

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

ばーん

人 海 戦 術

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

モジュール

RP1029Logic.javaへのコ

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

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

凝集性がぁ〜。  

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

から    

2人で2ヶ月で作る世界  

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

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

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

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

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

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

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

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

大規模  高品質

小規模  フットワーク  

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

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

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

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

     

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

     

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的な  ことがしたい

     

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);    }              :  

}

     

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);                  }  }

     

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

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

     

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("/");    }  

}

     

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したい

     

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));

     

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          ↑  入力チェックしたい

     

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));                  }}

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

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

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

@vulcaniz @i2key

iOS

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

Play  Controller(実装)  

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

もろもろ Model

渡す

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

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

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

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

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

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

Thrown(  akka.pa8ern.AskTimeoutExcepTon:  Timed  out)  

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

完全に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      

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!!

以上!!