20160521 大規模映像配信サービスの Java8による全面リニューアルの裏側

Post on 23-Jan-2018

3.025 views 0 download

Transcript of 20160521 大規模映像配信サービスの Java8による全面リニューアルの裏側

大規模映像配信サービスの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?最新情報はWebで http://video.unext.jp/introduction/fee

そもそも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]

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