More Related Content Similar to マイクロサービス時代の動画配信基Ruby×go=∞ (20) マイクロサービス時代の動画配信基Ruby×go=∞3. システム本部
デジタル配信開発部
グループ長 兼 チームリーダ
小嶋 聡史
2006年 ネットワークサービス事業者
2011年 ソーシャルゲーム事業者
2014年 ベンチャー企業
2015年 DMM.com ラボ
開発・運用・管理業務に携わり、2015年より DMM.com ラボへ参画していま
す。DMM.comラボで、システムのアーキテクトや組織運営に従事しています。
4. システム本部
デジタル配信開発部
システムエンジニア
江藤 慎吾
20YY年 WEB 広告
2009年 コミュニティサイト・ソーシャルゲーム
2011年 ECサイト
2013年 DMM.com ラボ
課金基盤のプラットフォーム開発と運用に携わり、半年前よりデジタル配信開
発に参画しています。
アルゴリズムとサービスを考えることが好きで、最近では動画やVR技術を活
かしたコンテンツの自動生成などに興味をもっています。
15. 動画配信技術#配信種別
動画配信には、VOD と LOD の2種類に分類できます。
今回は LOD について説明します。
VOD (Video On Demand)
あらかじめ録画しておいた動画コンテンツを、
視聴提供するサービス。
LOD (Live On Demand)
あらかじめ録画しておいたものではなく、撮った映像
を随時配信してリアルタイムに視聴提供するサービス。
36. DMM.com ラボ マイクロサービスTIPS
15分
サブシステム切り出し#PUB / SUB
Streaming Servers
Publisher
Wowza
Streaming Servers
Red5
Streaming Servers
Wowza
社内DC社外DC
Message
Queue
Subscriber
Capistrano
Subscriber
Capistrano
Enqueue
Denqueue
Cluster1から
動画配信
Subscriber
Capistrano
設定投入
37. RESTful API over HTTP(s) で設計します。
今回は Twitter REST API を参考にしました。
DMM.com ラボ マイクロサービスTIPS
15分
APIポリシー定義
詳細は
「Web API The Good Parts」
でお願いします。
39. ⑥ TraceID をつけてログ出力
④ URL + TraceID
① URL
③ なければ TraceID を生成
トレース ID をつけることでデバッグしやくすなります。
DMM.com ラボ マイクロサービスTIPS
15分
APIポリシー定義
System ‘A’
System ‘B’
System ‘C’
② X-DMM-
TRACEIDが
あるか
⑤ HTTP
ヘッダー を
参照
41. 評 価 軸 名 説 明
開 発 コ ス ト 実 装 に 必 要 な コ ー ド 量 。 ツ ール ( イ ンス ト ール ・ 環 境 構 築 ・
デバ ッ グ 等 ) が 充 実 して い る か な ど
環 境 適 応 ブ ラ ウ ザ の 互 換 性 な ど 、 ユ ー ザ 環 境 が 絞 ら れ な い か
機 能 何 が で き る か 。 ど こ の レ イ ヤ ー ま で 網 羅 して い る か
拡 張 性 他 の ラ イ ブ ラ リ や フ レ ームワ ー ク と の 親 和 性 。 一 部 、 ラ イ ブ
ラ リ を 変 え た と し た 時 の コ ス ト が 低 い か
将 来 性 メ ン テ ナ ンス さ れて い る か + 今 後 も さ れ る か 。 技 術 が 古 く な
い か 。 イ ン タ ー ネ ッ ト 上 で 話 題 に な って い る か 。 世 界 的 に 普
及 して い る か
学 習 コ ス ト 該 当 の 技 術 を 習 得 す る た め に 要 す る 時 間 ・ お 金 。 日 本 語 ド キ
ュ メ ン ト ・ 難 易 度 な ど
信 頼 性 リ リ ース か ら ど れ ほ ど た って い る か 。 脆 弱 性 が な い か 。 利 用
実 績
レス ポ ンス 速 度 全 体 の サ イ ズ 。 レン ダ リ ン グ ・ ブ ラ ウ ザ の 動 作 レス ポ ンス
ISO/IEC9126(JIS X 0129-1)ソフトウェア品質特性と副特性 から抜粋
DMM.com ラボ マイクロサービスTIPS
15分
技術選定
42. 評価軸名 言語1 言語2 言語3 言語4 言語5
開発コスト 3 4 4 4 4
環境適応 4 5 3 4 5
機能 5 3 4 3 3
拡張性 4 3 2 4 2
将来性 3 4 3 4 4
学習コスト 6 6 8 8 10
信頼性 4 4 4 4 3
レスポンス速度 4 3 5 4 4
33 32 33 35 35
例
DMM.com ラボ マイクロサービスTIPS
15分
技術選定
5点満点で、案件によっては評価軸のスコアを倍にし、その合計値で決定します。
将来性は、GoogleTrend や Qiitaトレンド、信頼性は ダウンロード数やメンテナンス
頻度で判断します。
43. 結果、Ruby + Go + AngularJS を採用しました。
DMM.com ラボ マイクロサービスTIPS
15分
技術選定
AngularJS
{wrap} bootstrap
Go
Ruby
+
+
RDOC
JSON
Hyper Schema
49. 技術選定 ∼ 管理系システム
Ruby / Node.js / PHP7 などが候補にあがりましたが
今まではPHP中心でした。
しかし、あるメンバーの Railsやりたい! という
高いモチベーションにより…
63. goimportsが自動的にimportの過不足を修正する。
Before
1 package main
2 import (
3 "fmt"
4 "reflect" // not used. error!!!!!
5 "strconv"
6 // "strings" // need!!!!!
7 )
8 func main() {
9 ary := strings.Split("0120-123-456", "-")
10 fmt.Println(ary)
11 for _, num := range ary {
12 n, err := strconv.Atoi(num)
13 fmt.Println(n + 1)
14 }
15 }
Go言語とは? ∼その独自の文化∼
64. goimportsが自動的にimportの過不足を修正する。
After
1 package main
2 import (
3 "fmt"
4 "strconv"
5 "strings" // added
6 // "strings" // need!!!!!!!
7 )
8 func main() {
9 ary := strings.Split("0120-123-456", "-")
10 fmt.Println(ary)
11 for _, num := range ary {
12 n, _ := strconv.Atoi(num)
13 fmt.Println(n + 1)
14 }
15 }
Go言語とは? ∼その独自の文化∼
76. Ruby vs Go!
イメージ的な違い
Ruby Go
富豪的プログラミング
動的スクリプト
おもてなし
オブジェクト指向
メソッドチェーン
豊富なライブラリ
大変なバージョン依存
環境構築でハマる
シンプルさを追求
静的コンパイル
郷に入っては郷に従え
並行プログラミング
C言語的
必要十分な標準ライブラリ
徹底した後方互換性
バイナリ一つ置くだけ
77. Ruby vs Go!
フレームワーク
Go
Rails or Sinatra
フレームワークのルールに従う
フレームワークとgemで賄う
言語仕様のルールに従う
いろいろ
(revel, gorilla, goji, gin,
gizmo, gocraft, go kit…)
必要なものを組み立てる
Ruby
78. Ruby vs Go!
開発方法の比較
(なし)
rails / runner / rake …
bundle / gems / gulp …
RSpec
便利だが覚えることが多い
RCover
Autodoc
peek / New Relicなど
go build
go run hoge.go
go get (バージョン管理不要)
go test
普通のプログラム(assertなし)
go test -cover
go doc
go test -pprof
ビルド
実行
依存設定
単体テスト
カバレッジ
ドキュメント
プロファイラ
79. Ruby vs Go! ∼ コードの比較
数字の文字配列を2倍にしてカンマ区切りの文字列を表示
Ruby
1 p ["1","2","3","4","5"].map {|n| n.to_i * 2}.join(‘,')
> "2,4,6,8,10"
80. Ruby vs Go! ∼ コードの比較
数字の文字配列を2倍にしてカンマ区切りの文字列を表示
Go
1 package main
2
3 import (
4 "fmt"
5 "strconv"
6 "strings"
7 )
8
9 func main() {
10 ary := [...]string{"1", "2", "3", "4", "5"}
11 nums := make([]string, len(ary))
12
13 for i, n := range ary {
14 if num, err := strconv.Atoi(n); err == nil {
15 nums[i] = strconv.Itoa(num * 2)
16 }
17 }
18
19 fmt.Printf("%+vn", strings.Join(nums, ","))
20 }
87. Goのツボ ∼ configリロード
config hotリロードの手順
1. 初期化時にconfigを読み込み失敗したらプロセスを終了
2. シグナルを待ち受けるgoroutineを作成
3. シグナルが来たらロックをかけてconfigをリロード
4. 読み込みに失敗したら元のデータをそのまま使う
88. Goのツボ ∼ configリロード1/2
1 func init() {
2 loadConfigs(true)
3
4 s := make(chan os.Signal, 1)
5 signal.Notify(s, syscall.SIGHUP)
6 go func() {
7 defer handleRuntimeError() // point!
8 for {
9 <-s
10 loadConfigs(false) // 3
11 }
12 }()
13 }
14
15 func handleRuntimeError() {
16 if r := recover(); r != nil {
17 log.Printf("Error : Recover from error! ", r)
18 }
19 }
←1. 初期化時にconfig読み込み
←2.SIGHUPを待ち受ける
←エラー対策
←3. configをリロード
←エラーはログを残して続行
89. Goのツボ ∼ configリロード2/2
1 func loadKVS(fail bool) {
2
3 temp = loadFile(fail, kvsFn)
4 if env.Env == env.Development {
5 tempHosts = temp.Development
6 }
7
8 client, err := as.Connection(nil, tempHosts...)
9 if err != nil {
10 if fail {
11 os.Exit(1)
12 }
13 return
14 }
15 kvsLock.Lock()
16 kvsHosts = tempHosts
27 kvsLock.Unlock()
18 }
←configファイル読み込み
←環境ごとに切り替え
←動作確認
←初期化時エラーなら終了
←リロード時エラーなら無視
←ロックして更新
92. Goのツボ ∼ 環境変数
定数が最適化されるか試してみました! (何もしないコード)
1 package main
2
3 import "log"
4
5 const flag = false
6
7 func emptyFunc(msg string) {
8 if flag { // is false
9 log.Println(msg)
10 }
11 }
12
13 func main() {
14 emptyFunc("hello world!") // do nothing
15 }
←このコードは消えて欲しい