More Related Content Similar to 20160521 大規模映像配信サービスの Java8による全面リニューアルの裏側 (20) 20160521 大規模映像配信サービスの Java8による全面リニューアルの裏側2. Hello!
氏名 秋穂 賢(あきほ すぐる)
所属 株式会社U-NEXT システム開発部
リリース管理や開発用ミドルウェア管理
DBFlute & Java8でのAPI開発 など
見習いスクラムマスターとして精進中
仕事
このページ以降、U-NEXTは
サービス名称を表します
28. ◉ 迫り来る決まったリリース日
◉ 決まらない要求仕様
◉ この期間でサーバ構成を検討
◉ そして開発メンバーがDBFluteの習得
○ jfluteさんが勉強会をひらいてくれた
○ DBFluteハンズオン(チュートリアル)をしっかり実施
アニメ放題
http://dbflute.seasar.org/ja/tutorial/handson/
36. データストアとしてのRedis
◉ Logic / Facadeクラスは変わらず実装
◉ もう一歩発展
◉ jsonでスキーマ定義
◉ それを元に共通して使えるクラスについてテンプレート化
○ Velocityテンプレートを利用
○ DBFluteの自動生成の仕組みに乗せて、Redisにスキーマ定義を
もたせて自動生成!!
◉ IDEのコード補完の恩恵を存分に受けられるように
構造を意識したデータのCRUD
37. データストアとしてのRedis
EVALUATION: {
$comment : "評価点",
$type : "table",
PLATFORM_CODE : {
type: "varchar",
comment: "プラットフォームコード",
kvsKey: true ,
notNull: true },
SAKUHIN_CODE : {
type: "varchar",
comment: "作品コード",
kvsKey: true,
notNull: true },
EVALUATION_POINT : {
type: "varchar",
comment: "評価点",
notNull: true },
TTL : {
type: "java.time.LocalDateTime",
comment: "有効期限",
notNull: true
}
}
public class EvaluationMeta
implements KvsStoreMeta {
…(Meta data. name, column, ...)
}
public class BsEvaluation
implements KvsStoreEntity,
Serializable {
…(getter / setter / util methods)
}
public class Evaluation extends
BsEvaluation {
… (extends local methods)
}
自
動
生
成
42. SelectableDataSource
◉ Seasar2が提供しているMaster/Slaveを切り替える仕組
みを利用
// e.g. SelectableDataSource のベタな実装方法 @Java
protected MemberBhv memberBhv;
protected DataSourceFactory dataSourceFactory; // injected
public void fooAndBar() {
dataSourceFactory.setSelectableDataSourceName("master");
Member member = ...
...
memberBhv.update(member); // master の会員を更新
dataSourceFactory.setSelectableDataSourceName("slave");
MemberCB cb = ...
...
... = memberBhv.select(cb); // slave の会員を検索
}
http://dbflute.seasar.org/ja/manual/reference/diway/seasar/selectabledatasource.html
46. ◉ 更新系処理が開始した時点で初めてトランザクションを開始す
るように
◉ DBFluteでBehavior(SQL実行)の処理前後にHookができる
LazyTransaction?
protected BehaviorCommandHook createLazyTransactionHook() {
return new BehaviorCommandHook() {
public void hookBefore(BehaviorCommandMeta meta) {
if (!meta.isSelect() || meta.isProcedure()) {
LazyHookedUserTransaction.beginRealTransactionLazily();
}
}
public void hookFinally(BehaviorCommandMeta meta, RuntimeException
cause) {
}
@Override
public boolean inheritsExistingHook() {
return true;
}
};
}
SAFluteのリクエ
スト開始時点の
Hookへ登録
47. ◉ 課題1 Redisへのアクセス
○ キャッシュ / ストアとしての使い方
○ FacadeやLogicで処理をまとめたり、DBFluteの自動
生成機能に乗せて独自の自動生成機能を作った
◉ 課題2 Mroongaへの対応
○ DBFluteのSelectableDataSourceを使ってMaster
/ Slaveの切り替えを汎用的に実装
◉ 課題3 MySQLとAtlas
○ BehaviorCommandHookを使って全てのBehavior
の実行前にHookを入れることでLazyTransaction機
能を実現
アーキテクチャ課題への対応
57. 2. ReplaceSchema
1. テストデータの修正と出力
1. まず、MySQLへテストデータ
を追加
2. manage.shでload data
reverse実行!
3. DBに入っているテストデータ
がxlsやtsv形式で出力
4. git commit & push
http://dbflute.seasar.org/ja/manual/function/generator/task/doc/loaddatareverse.html
58. 2. ReplaceSchema
2. データ共有 & Load
1. git pull
2. sh manage.sh
3. 0
4. Enter!
http://dbflute.seasar.org/ja/manual/function/generator/task/doc/loaddatareverse.html
drop table
create table
insert into
59. 2. ReplaceSchema
2. データ共有 & Load
1. git pull
2. sh manage.sh
3. 0
4. Enter!
http://dbflute.seasar.org/ja/manual/function/generator/task/doc/loaddatareverse.html
drop table
create table
insert into
修正したデータをgit経由で簡単に共有
開発前にReplaceSchemaをしておけば
テストデータの共有漏れは起こらない
60. 3. AlterCheck (DB Migration)
ローカルと開発と本番のDBスキーマが違う!
なんてことが起こらないようにするための
DB Migrationツール
DBFluteの場合、こんな感じです
62. 3. AlterCheck (DB Migration)
差分を確認
alterSQLを定義
今回の場合は
create table hoge
再度AlterCheckで
Success!
後は各環境へ差分を
反映させるだけ
63. 3. AlterCheck (DB Migration)
差分を確認
alterSQLを定義
今回の場合は
create table hoge
再度AlterCheckで
Success!
AlterCheckを運用として実施していくことで
各環境でのDBスキーマで差分が出ないように
67. 5. 見やすいログ
Requestの開始と終了
http://dbflute.seasar.org/ja/manual/function/helper/saflute/friendlylogging.html
...-DEBUG (...#before():268) - * * * * * * * * * * {BEGIN}: /member/list/
Request class=org.seasar.framework.container.hotdeploy.HotdeployHttpSer...
, REQUEST_URI=/dockside/member/list/, SERVLET_PATH=/member/list/, Chara...
, ContentType=application/x-www-form-urlencoded, Locale=ja, Locales=ja,...
...
...
Response class=org.mortbay.jetty.Response, ContentType=text/html; chars...
, toString()=HTTP/1.1 200 Content-Type: text/html; charset=utf-8 Expir...
[session] javax.servlet.jsp.jstl.fmt.request.charset=UTF-8
[session] member_memberListForm=org.dbflute.maihama.app.web.member.
Memb...
[session] org.apache.struts.action.LOCALE=ja
[session] org.dbflute.maihama.domainfw.action.DocksideUserBean={userId=...
* * * * * * * * * * {END}: /member/list/ [00m00s247ms]
68. 5. 見やすいログ
SQLの実行時間と結果概要
http://dbflute.seasar.org/ja/manual/function/helper/saflute/friendlylogging.html
2016-05-20 17:28:22,346 [main]-DEBUG (XLog#log():43) -
SakuhinListActionTest.testname():131 -> ...
2016-05-20 17:28:22,693 [main]-DEBUG (QLog#log():43) -
select dfloc.SAKUHIN_ID as SAKUHIN_ID, dfloc.DISPLAY_NAME as
DISPLAY_NAME
from SAKUHIN dfloc
where dfloc.SAKUHIN_ID = 1
2016-05-20 17:28:22,694 [main]-DEBUG (XLog#log():43) - ===========/
[00m00s348ms (1) result={1, null, ほげ作品, null, null, null, null, null, null,
null, null, null, null, null, null, null, null, null}@729c021d]
71. 6. 書きやすいUT
ActionクラスのisHogeメソッドを実行してbooleanを
Assert
public void test_isHoge_hogeはhogeだったらtrue() throws Exception {
// ## Arrange ##
SakuhinListAction action = new SakuhinListAction();
inject(action);
// ## Act ##
boolean isHoge = action.isHoge("hoge");
// ## Assert ##
assertTrue("hogeはtrueだ", isHoge);
}
http://dbflute.seasar.org/ja/manual/function/helper/utflute/index.html
80. solrjをそのまま使うとタイプセーフではない...
MroongaからSolrへ
try (HttpSolrClient httpSolrClient = new HttpSolrClient(“http://localhost:
8983/solr/schema”)) {
httpSolrClient.setParser(new XMLResponseParser());
ModifiableSolrParams params = new ModifiableSolrParams();
params.add("q", "あの日");
params.add("defType", "dismax");
params.add("qf", "name kana^10");
QueryResponse response = httpSolrClient.query(params);
SolrDocumentList results = response.getResults();
}
…