View
3.025
Download
0
Category
Preview:
Citation preview
大規模映像配信サービスのJava8による全面リニューアルの裏側
Hello!氏名 秋穂 賢(あきほ すぐる)
所属 株式会社U-NEXT システム開発部
リリース管理や開発用ミドルウェア管理DBFlute & Java8でのAPI開発 など見習いスクラムマスターとして精進中
仕事
このページ以降、U-NEXTはサービス名称を表します
そもそもU-NEXT?最新情報はWebで http://video.unext.jp/introduction
2015/10/8全面リニューアルを実施!
◉ 12万本以上の映像コンテ
ンツ
◉ 20万冊以上の電子書籍
そもそもU-NEXT?最新情報はWebで http://video.unext.jp/introduction/device
そもそもU-NEXT?最新情報はWebで http://video.unext.jp/introduction/family
そもそもU-NEXT?
2015年2月〜
2015年10月〜
そもそもU-NEXT?
◉ 動画配信サービスを軸として、書籍・音楽コンテンツのサービスも
提供
◉ 多種多様なデバイス・複数アカウント
◉ 見放題・ポイント
◉ 各社とアライアンスを提携
◉ FHD配信・アダプティブストリーミング配信
◉ コンテンツホルダーに応じた最高ビットレートのフレキシブルな制御
◉ などなど....
細やかな制御
第1章リニューアルの背景
U-NEXTの歴史
Pay per View開始
GyaONEXTサービス開始
マルチデバイス
2007年6月
1デバイス1顧客デバイス認証見放題のみ
2008年11月
都度課金の仕組み
コンテンツDB
顧客・課金DB
2010年6月
TVデバイス対応オンライン認証
の仕組み
新顧客課金DB
新顧客課金DB
PlayStation VitaU-NEXT
TV
PCスマホ
タブレット
2012年 2014年
増える対応デバイス
● 様々な環境と異なるバージョンで動いていたPHP● 様々なPHPアプリケーションから直接リクエストされる
DB● 各テーブルが触るな危険状態に
● 新しいサービスを開始する際には同じようなテーブル
が次々と拡張されていく
2007年から拡張し続けた複雑怪奇なシステム
アニメ放題サービス提携の決定
これ以上の拡張は不可能
アニメ放題の先を見据えて
既存システムを捨て
U-NEXTサービスサイトの
リニューアルを決断
U-NEXT大幅
リニューアル
2015年10月
アニメ放題サービス開始
2015年2月
リニューアルで目指す姿
性能にこだわるシステム
よりよいユーザ体験の為に性能にこだわる
アプリケーションだけでなく
システムアーキテクチャとして高い性能を出せるような設計に
メンテナンス性の高いシステム
DBの集中管理
● どのDBがどのアプリケーションからアクセスされているか、管理したい
● DB毎に管理するAPIを実装する方針に
アーキテクチャの最適化を測った結果
自然とマイクロサービスアーキテクチャ
よりの思想に
(実際はミディアムサービスくらい)
FW選定
FW選定で重視したポイント
● 強力なORM○ 生のSQLは書かなくてもよいように
■ 人によって書くSQLが違うとか...
○ DB Migration機能
● 静的型付け言語
○ 規模の大きな開発
○ IDEによるサポート
○ コンパイルによるエラー検知
● PlayFramework
● (NodeJS + TypeScript)
● DBFlute
いくつかの選択肢があった
縁があってDBFluteメインコミッターのjfluteさんにDBFluteを紹介してもらえることに
● DBFluteの強力なORM● DB Migrationツール
● コードとドキュメント自動生成
● Javaによる静的型付けとコンパイル
● IDEのサポート
● 豊富な公式ドキュメント
● (24時間戦えるjfluteさんが開発してる)
DBFluteとの出会い
何より
DBFlute / SAFluteはサービス開発のためのFW
サービス開発で便利な機能が豊富
(詳細は後ほど)
DBFluteとの出会い
これらのメリットからORMはDBFluteに決定
WebFWは一緒に紹介してもらったDBFluteとの親和性が高いSAFluteに
DBFluteとの出会い
Java8+
DBFlute / SAFlute
第2章アニメ放題サービスの開始
◉ 迫り来る決まったリリース日
◉ 決まらない要求仕様
◉ この期間でサーバ構成を検討
◉ そして開発メンバーがDBFluteの習得○ jfluteさんが勉強会をひらいてくれた
○ DBFluteハンズオン(チュートリアル)をしっかり実施
アニメ放題
http://dbflute.seasar.org/ja/tutorial/handson/
DBFluteハンズオン?
DBFluteハンズオン = DBFluteのチュートリアル
セクション1 〜 セクション11で構成されている
DBFluteハンズオンで修行する
=
業務で出てくる技術の習得
http://dbflute.seasar.org/ja/tutorial/handson/
DBFlute Live DemoそんなDBFluteを生で見てもらいます
サーバ構成
クライアントむけのAPI永続層は持たない
リバースプロキシのキャッシュ
コンテンツDBを管理するAPI
コンテンツDBSlaveに全文検索エンジンのMroonga
MySQL Atlas中国企業のOSS
SB認証基盤
コンテンツと紐付いたユーザ情報のDB
アーキテクチャ課題
クライアントむけのAPI永続層は持たない
リバースプロキシのキャッシュ
コンテンツDBを管理するAPI
コンテンツDBSlaveに全文検索エンジンのMroonga
MySQL Atlas中国企業のOSS
SB認証基盤
コンテンツと紐付いたユーザ情報のDB
① ②
③
課題1 Redisへのアクセス
大きく2種類の使い方
◉ データキャッシュとしてのRedis○ マスタデータはDBに格納
○ キャッシュとしてRedis上にも保存
○ ユーザDBのデータはキャッシュへ
◉ データストアとしてのRedis○ マスタデータをRedisに格納
キャッシュを意識しないデータのCRUD
構造を意識したデータのCRUD
キャッシュとしてのRedis
◉ 対象テーブル毎にCRUDのI/Fを持ったLogicクラスを実装
○ キャッシュを意識したくないテーブルを作るタイミングでLogicクラ
スも一緒に実装
◉ RedisへのアクセスはFacadeを使って統一で使い回し○ insert or update時には内部でキャッシュを削除
○ delete時は一緒にキャッシュを削除
○ select時はキャッシュがあればキャッシュから、なければDBから
のデータをキャッシュに
◉ 内部ではJedisを利用
キャッシュを意識しないデータのCRUD
キャッシュとしてのRedis
@Resourceprotected ViewingHistoryCacheLogic viewingHistoryCacheLogic;…UsrViewingHistory viewingHistory = new UsrViewingHistory();viewingHistory.setUserId(userId);…viewingHistoryCacheLogic.insertOrUpdate(viewingHistory);
ViewingHistoryParam param = new ViewingHistoryParam();param.setUserId(userId);param.addOrderByList(ViewingHistoryDbm.getInstance().columnUpdateDatetime());… return viewingHistoryCacheLogic.getList(param);
データストアとしてのRedis
◉ Logic / Facadeクラスは変わらず実装
◉ もう一歩発展
◉ jsonでスキーマ定義
◉ それを元に共通して使えるクラスについてテンプレート化○ Velocityテンプレートを利用
○ DBFluteの自動生成の仕組みに乗せて、Redisにスキーマ定義を
もたせて自動生成!!
◉ IDEのコード補完の恩恵を存分に受けられるように
構造を意識したデータのCRUD
データストアとしての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)}
自動生成
◉ 本当は専用の検索エンジン(Solr/Elasticsearch)を使いたかっ
た
◉ 時間の都合上、手軽に全文検索ができるMroongaを選択
◉ 一部Slaveの全文検索したいテーブルだけのEngineをMroongaにして利用○ 初めて利用するため、何かあった場合の影響を最小限に
課題2 Mroongaへの対応
Mroonga?Groongaをベースとした全文検索エンジン。MySQLのストレージエンジンの1つとしてMySQLに全文検索機能を提供
課題2 Mroongaへの対応
Mroongaを使うとSQLで手軽に全文検索が出来る
DBFluteはmatch構文をサポート
mysql> SELECT * FROM diaries WHERE MATCH(content) AGAINST("fine");+----+-----------------------------------------+| id | content |+----+-----------------------------------------+| 1 | It'll be fine tomorrow. |+----+-----------------------------------------+1 row in set (0.00 sec)
課題2 Mroongaへの対応
EngineInnodb
EngineInnodb
EngineInnodbMroonga
Mroongaへの検索かどうかで向け先を変える
課題2 Mroongaへの対応
EngineInnodb
EngineInnodb
EngineInnodbMroonga
Mroongaへの検索かどうかで向け先を変える
SelectableDataSource
SelectableDataSource◉ Seasar2が提供しているMaster/Slaveを切り替える仕組
みを利用
// e.g. SelectableDataSource のベタな実装方法 @Javaprotected 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
SelectableDataSource
◉ SAFluteの機能を使ってSelectableDataSourceをベースに汎用性を持たせて使いやすいようにして利用
PagingResultBean<Sakuhin> sakuhinPage = slaveDBAccessor.accessIfNeeds(() -> {
return sakuhinBhv.selectPage(cb -> { cb.specify().... cb.query().... });}, isNotEmpty(searchWord));
http://dbflute.seasar.org/ja/manual/reference/diway/seasar/selectabledatasource.html
検索ワードがあれば強制的にSlaveへSlaveのhost設定をMroongaなMySQLへ向くように設定
◉ MySQL Atlasはトランザクションを更新処理とみなしてmasterへ
◉ SAFlute(SAStruts)はリクエストでトランザクション
◉ 各API毎に自前でトランザクションをかけるのはつらい
課題3 MySQLとAtlas
ここのLBはMySQL Atlasにお任せ
LazyTransaction
◉ 更新系処理が開始した時点で初めてトランザクションを開始するように
◉ 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へ登録
◉ 課題1 Redisへのアクセス○ キャッシュ / ストアとしての使い方○ FacadeやLogicで処理をまとめたり、DBFluteの自動
生成機能に乗せて独自の自動生成機能を作った
◉ 課題2 Mroongaへの対応○ DBFluteのSelectableDataSourceを使ってMaster
/ Slaveの切り替えを汎用的に実装
◉ 課題3 MySQLとAtlas○ BehaviorCommandHookを使って全てのBehavior
の実行前にHookを入れることでLazyTransaction機能を実現
アーキテクチャ課題への対応
Special Thanks
アーキテクチャ周りはDBFluteコアユーザの
@p1us2er0 さん
に多大なるご協力を頂きました
その他
日々のサービス開発で
便利なこと
工夫してること
などなど
一挙にご紹介!!6連発
DB変更を行うとき、どのようにしていますか?
DBFluteの場合、こんな感じです
1. ERDドリブン開発
1. ERDドリブン開発
1. EclipseプラグインのERMasterでER図を変更
1. ERDドリブン開発
2. ERMasterからDDLを出力
1. ERDドリブン開発
3. manage.shのrenewalを実行
renewalはDB定義から
Javaのエンティティクラスな
どを自動生成する機能
1. ERDドリブン開発
4. DB変更した内容のJavaが自動生成
1. ERDドリブン開発
4. DB変更した内容のJavaが自動生成
DB変更完了!
U-NEXTではDBFluteの流儀に沿って
DB変更する場合はまずERDを修正する
というフローで実施
ER図と実態が一致しない、はありえない
2. ReplaceSchema
テストデータを追加
開発メンバーと共有 & 最新化
みなさんどのようにやってますか?
DBFluteの場合、こんな感じです
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
2. ReplaceSchema
2. データ共有 & Load
1. git pull2. sh manage.sh3. 04. Enter!
http://dbflute.seasar.org/ja/manual/function/generator/task/doc/loaddatareverse.html
drop table
create table
insert into
2. ReplaceSchema
2. データ共有 & Load
1. git pull2. sh manage.sh3. 04. Enter!
http://dbflute.seasar.org/ja/manual/function/generator/task/doc/loaddatareverse.html
drop table
create table
insert into
修正したデータをgit経由で簡単に共有
開発前にReplaceSchemaをしておけば
テストデータの共有漏れは起こらない
3. AlterCheck (DB Migration)
ローカルと開発と本番のDBスキーマが違う!
なんてことが起こらないようにするための
DB Migrationツール
DBFluteの場合、こんな感じです
DB変更後にmanage.shの8
◉ 前回のDBの状態で
ReplaceSchema◉ 最新のDBの状態で
ReplaceSchema◉ 前回と今回の差分を提示し
てFailure
3. AlterCheck (DB Migration)
3. AlterCheck (DB Migration)
差分を確認
alterSQLを定義
今回の場合は
create table hoge
再度AlterCheckでSuccess!
後は各環境へ差分を反映させるだけ
3. AlterCheck (DB Migration)
差分を確認
alterSQLを定義
今回の場合は
create table hoge
再度AlterCheckでSuccess!
AlterCheckを運用として実施していくことで
各環境でのDBスキーマで差分が出ないように
4. Schemaドキュメント
ER図だけでなく、DBFluteはHTML形式のドキュメントも自動生成してくれる
4. Schemaドキュメント
ER図だけでなく、DBFluteはHTML形式のドキュメントも自動生成してくれる
U-NEXTでは
人によってER図とSchema.htmlを
使い分けて開発作業を行っている
5. 見やすいログ
開発やテスト時は何度もデバッグを行うため、ログが見やすいことは重要
今回は一部のログをご紹介
http://dbflute.seasar.org/ja/manual/function/helper/saflute/friendlylogging.html
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]
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 = 12016-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]
5. 見やすいログ
その他、色々とログが見やすく工夫されています
詳細は公式ページで!
http://dbflute.seasar.org/ja/manual/function/helper/saflute/friendlylogging.html
6. 書きやすいUT
みなさん、テストは書いていますか?
UTFluteを使えば楽々テスト
UTFluteはDBFluteファミリーのJUnit拡張ライブラリ
UTFlute は、自分で new したものにDIできる JUnit 拡張 です。
http://dbflute.seasar.org/ja/manual/function/helper/utflute/index.html
6. 書きやすいUTActionクラスの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
6. 書きやすいUThttp://dbflute.seasar.org/ja/manual/function/helper/utflute/index.html
UTFluteのおかげで単体テストの自動化は結構している
◉ JenkinsでのCIも実施○ エラーが出たらHipChatに通知
◉ UTで事前に不具合を検知できた
コード品質が向上!
その他、UTFluteでの便利機能が提供されています
詳細は公式ページで!
http://dbflute.seasar.org/ja/manual/function/helper/utflute/index.html
6. 書きやすいUT
アニメ放題
無事に予定通りリリース!!
振り返ってみると
◉ 最初にDBFluteハンズオンをみっちりと実施した効果は
大○ 業務アプリ実装時に役立つTipsがたくさん
◉ 困った時の拡張ポイントがしっかりしてる○ アーキテクチャ課題は無事にクリア
◉ その他諸々サービス開発で役立つ機能○ 細かいけどあったらとても役立つ機能がたくさん
第3章U-NEXTサービスサイト
リニューアル
◉ アニメ放題と比較すると遥かに複雑な業務○ アニメ放題はアニメのみ、U-NEXTは洋画・邦画・ドラマなど、ジャン
ルの多さ
○ アニメ放題はiOS/Android/PC、U-NEXTはTV、ゲーム機、STBなど、対応デバイスの多さ
○ アニメ放題は見放題のみ、U-NEXTは見放題と単品でのレンタル作品も
○ U-NEXTはユーザへの見せ方がよりきめ細やか
◉ 複雑な業務 = 開発が大変◉ 複雑な業務 = 複雑なDB
U-NEXTリニューアルでの難関
API数 10倍程度のAPIテーブル数 125テーブル から253テーブルに (区分値除く 29 => 89)
激しいDB変更の嵐
DBFlute採用から約1年半、DB変更の回数は 186 回
=> 単純計算すると 約 3 日に 1 回はDB変更してる
毎日のようにER図を変更して
AlterCheckして
本番へDDL実行!をしていた日々もあった
怒涛のDB変更ラッシュもDBFluteで乗り越えた
検索のインクリメンタルサーチを目指していた
=> Mroongaでは性能で不利
ElasticsearchとSolrが候補に
「検索」の実績から Solr を選択
Demo:http://video.unext.jp
詳細:http://www.slideshare.net/SuguruAkiho/20151028-17-solr-unext
MroongaからSolrへ
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(); }…
Schema.xmlから各種クラスを自動生成
全文検索システムFessで使っていたSolr用CBを拡張
MroongaからSolrへ
SolrPagingResultBean<General> list = generalBhv.selectPage(cb -> { cb.query().dismax("あの日", queryField -> { queryField.put(GeneralMeta.Name, null); queryField.put(GeneralMeta.Kana, 10); queryField.put(GeneralMeta.NameGeneral, 20); queryField.put(GeneralMeta.Synonym, null); }); cb.specify().fieldUid(); cb.paging(10, 2); }); LOG.debug("list={}", list);
DBFluteの機能でページング検索が出来る
dismax検索出来る対象のフィールドがタイプセーフに指定可能
specifyでflをタイプセーフに指定可能
MroongaからSolrへとある1日のフリーワード検索の平均レスポンス:39ms
2016年9月26日、Seasar2のサポートが終了
SAFluteはSAStrutsの拡張FW
リニューアルが終わってないのにFW移行の危機...
そんな時、jfluteさん
「Seasar2フォークしてJava8で書き換えてLastaFlute作っちゃった」
SAFluteからLastaFluteへ
2016年9月26日、Seasar2のサポートが終了
SAFluteはSAStrutsの拡張FW
リニューアルが終わってないのにFW移行の危機...
そんな時、jfluteさん
「Seasar2フォークしてJava8で書き換えてLastaFlute作っちゃった」
SAFluteからLastaFluteへ
使うしかないでしょう
LastaFluteのいいところ
◉ 起動が圧倒的に早い○ SAFluteは7〜8秒程度、Lastaは2〜3秒程度
◉ ログが見やすい○ DBFluteイズムで見やすいログ
◉ よりシンプルに書けるコード
○ formが引数, formで型定義、Hibernate Validatorが使え
る、などなど
APIドキュメント自動生成
API開発をしている場合、クライアントへI/F定義を提示する必要がある
=> 自動生成
2015年 6月U-NEXTリニューアルリリース予定
リニューアルに向けて開発..開発..開発..
膨大な開発
2015年 6月U-NEXTリニューアルリリース予定
リニューアルに向けて開発..開発..開発..
2015年 8月へ延期
開発..開発..開発..開発..開発..開発..
膨大な開発
2015年 6月U-NEXTリニューアルリリース予定
リニューアルに向けて開発..開発..開発..
2015年 8月へ延期
開発..開発..開発..開発..開発..開発..
2015年 9月へ延期
開発..開発..開発..開発..開発..開発..開発..開発..開発..
膨大な開発
膨大な開発
2015年 6月U-NEXTリニューアルリリース予定
リニューアルに向けて開発..開発..開発..
2015年 8月へ延期
開発..開発..開発..開発..開発..開発..
2015年 9月へ延期
開発..開発..開発..開発..開発..開発..開発..開発..開発..
2015年 10月9日へ延期
開発..開発..開発.. リリース!!
ボリューム満点の開発
SAFlute / LastaFlute / DBFluteの軽快さ
実装 => リリース => 修正 => リリース => …
のサイクルをとても軽快に回すことが出来る
リニューアルを乗り越えられたのは
この軽快さのおかげ
膨大な開発
第4章更なる高みへ
リニューアルで全力疾走を続けた結果
◉ 個々のソロプレーを足しあわせて何とかなっていた○ チーム力・組織力が全くない状況
◉ ソースコードがちぐはぐ○ とにかく動くコードを早くリリースするのが正義
○ その結果、ちぐはぐなコードが生まれる
○ それでもテストコードは書いてCIはしていたし、DBFlute部分の
コードは問題なし
■ これはDBFluteハンズオンのおかげ
約1年半の開発である程度の技術的負債が生まれた
スクラム開発
◉ 今まで
○ 複数人のディレクターやQAからの要望を各分野に精通している人
が個々の判断で優先度を決定し、開発
◉ これから○ スクラム開発を導入
○ 優先度はプロダクトオーナーが決定
○ 開発タスクは開発チームで決定
○ 2週間のスプリント
○ スプリント計画ミーティングで実装タスクを決定
○ デイリースクラムで日々の状況や問題点を洗い出し
○ スプリントレビューで成果物の検査
○ スプリント振り返りでよりよいやり方に改善
○ ビジネス開発:アーキテクチャ改善・リファクタリング=7:3
より働きやすい環境
◉ ハイスペックな開発マシン
○ メモリ32GB、250GB SSD、インテル® Core™i7-5930k
◉ 高級なイス(予定)○ 候補:アーロンチェアなど
◉ 自由に買える書籍○ 申請して5分後に電子書籍が届くとか
◉ 定期的に開催される勉強会○ スクラム読書会
○ 機械学習の勉強会
○ データベースの勉強会 etc...
コードの品質
◉ これまで
○ コードを書いた人以外の目に触れずに本番へリリースされる
コードがたくさん
◉ これから○ コーディングガイドラインを整備
■ 規約は文章化せず、自動で判別できるものに
○ プルリクベースでのコードレビューを導入
○ 対面でのコードレビュー会を導入
チーム内でよりよいコードを書くという意識が芽生え始める
より良いアーキテクチャへ
◉ 当初目指していたDB単位のAPI○ これは実現出来た
○ DB変更は比較的簡単に出来る
◉ リポジトリはそれなりにでかい○ 分割出来るプロジェクトが同じリポジトリに存在している
■ 時間の都合上
◉ もっと最適に分割出来る
マイクロサービスアーキテクチャの思想でアーキテクチャをリファクタリグ
(やりすぎないようにミニマムサービスくらいを目指して)
◉ まだまだたくさんある開発案件○ これからはチームでよりよいものをより楽しく開発出来るように
○ そして競合に負けないように
◉ 個々の技術力
○ コードレビュー・勉強会などを通じてメンバーそれぞれがお互いを
高め合える環境・そして文化に
◉ より最適なアーキテクチャに○ 既存の技術的負債を放置せず、少しずつ返却していく
○ 2年後、3年後も楽しく開発出来るように
今後
U-NEXTでは人材を募集しています
映画やアニメが好きなひとエンターテイメントが好きなひと
配信プラットフォームに興味のあるひと技術的なことが好きなひと
一緒に仕事をしましょう
http://unext.co.jp/recruit/
Thank you for your attention
Recommended