Slide 1

Slide 1 text

Spring で実現する SmartNews のニュース配信基盤 井口 貝 (@kainoque) SmartNews, Inc. Spring Day 2016

Slide 2

Slide 2 text

はじめに 2

Slide 3

Slide 3 text

SmartNews におけるニュース配信基盤の紹介と、そこで利用されている Spring の技 術について紹介します。 セッションを通じて、Spring のメリットや知見などが共有できれば幸いです。 はじめに 3

Slide 4

Slide 4 text

SmartNews とは 4

Slide 5

Slide 5 text

SmartNews のご紹介 5

Slide 6

Slide 6 text

6

Slide 7

Slide 7 text

自己紹介 7

Slide 8

Slide 8 text

自己紹介 名前 井口 貝 (いのくち かい) @kainoque 担当   サーバサイドエンジニア @ SmartNews, Inc. ニュース配信基盤および管理コンソールの開発を担当 ref: SmartNews, Inc. | Team http://about.smartnews.com/ja/team/ 8

Slide 9

Slide 9 text

- SmartNews のニュース配信基盤のご紹介 - 記事収集 - 分析 - 検索 - 配信 - 監視 - ニュース配信基盤における Spring の活用 - サービスの分割と Spring の導入 - サービス間の連携 - バッチ処理 - 監視 - デプロイ / プロビジョニング - 生産性向上 アジェンダ 9

Slide 10

Slide 10 text

- SmartNews のニュース配信基盤のご紹介 - 記事収集 - 分析 - 検索 - 配信 - 監視 - ニュース配信基盤における Spring の活用 - サービスの分割と Spring の導入 - サービス間の連携 - バッチ処理 - 監視 - デプロイ / プロビジョニング - 生産性向上 アジェンダ 10

Slide 11

Slide 11 text

SmartNews のニュース配信基盤 11

Slide 12

Slide 12 text

ユーザにニュース記事を配信するための基盤 - 毎日、250 万人以上のユーザへ 5 万件以上の記事を配信 一日 4 回 (朝、昼、夕、夜) の定時 Push 通知 - Push 通知を許可していただいた全てのユーザに 通知を送信 - 重要なニュースがある場合は号外 Push 通知を送 信 SmartNews のニュース配信基盤 12

Slide 13

Slide 13 text

SmartNews のニュース配信基盤 監視 分析 収集 検索 配信 13

Slide 14

Slide 14 text

- バックエンド - 収集 各種クローラーお よび記事 inventory / index 生成 - 分析 記事分析 - オンライン - 検索 記事の検索エンジ ンおよびランキングシステ ム - 配信 自動スケールする フロントエンド向け API 分析 収集 検索 配信 SmartNews のニュース配信基盤 14

Slide 15

Slide 15 text

- SmartNews のニュース配信基盤のご紹介 - 収集 - 分析 - 検索 - 配信 - 監視 - ニュース配信基盤における Spring の活用 - サービスの分割と Spring の導入 - サービス間の連携 - バッチ処理 - 監視 - デプロイ / プロビジョニング - 生産性向上 アジェンダ 15

Slide 16

Slide 16 text

Crawler - 各ニュースソース (Web, SNS, SmartFormat endpoint) から記事を収集 - SmartFormat: SmartNews が策定している、RSS を拡張した、ニュース配信のための仕様 SmartNews のニュース配信基盤: 収集 16

Slide 17

Slide 17 text

Crawler - 収集した記事に加え、 Web/SNS 上のシグナルを用いて以下の情報を分析する - ポピュラリティ (注目度) 分析 - SNS のソーシャルグラフ、公開情報に基づいた 国籍 / 言語判定 - 一部の Crawler では Google Vision API を利用したクエリが可能 SmartNews のニュース配信基盤: 収集 17

Slide 18

Slide 18 text

Indexer - Crawler から受け取った記事から記事リスト (inventory) を生成 - 分散 KVS へ書き込み - 記事分析エンジンに Kinesis 経由で分析を依頼し、分析結果を各種メタ情報と merge して inventory に付与する SmartNews のニュース配信基盤: 収集 18

Slide 19

Slide 19 text

Importer - Indexer から受け取った記事および meta 情報を transform / filter し index 情報を生成 - index 情報を検索エンジン (CloudSearch) へ書き込み - 200,000 articles / day を処理 SmartNews のニュース配信基盤: 収集 19

Slide 20

Slide 20 text

- SmartNews のニュース配信基盤のご紹介 - 記事収集 - 分析 - 検索 - 配信 - 監視 - ニュース配信基盤における Spring の活用 - サービスの分割と Spring の導入 - サービス間の連携 - バッチ処理 - 監視 - デプロイ / プロビジョニング - 生産性向上 アジェンダ 20

Slide 21

Slide 21 text

Analyzer - Indexer から受け取った記事を分析 - 機械学習による記事の カテゴリ判定 - スポーツ、エンタメ、政治、など - 固有表現抽出 - 人名、地名、組織名、日付、時間など - その他にも、画像の主題抽出、品質判定を行うサービスが別途存在 SmartNews のニュース配信基盤: 分析 21

Slide 22

Slide 22 text

- SmartNews のニュース配信基盤のご紹介 - 記事収集 - 分析 - 検索 - 配信 - 監視 - ニュース配信基盤における Spring の活用 - サービスの分割と Spring の導入 - サービス間の連携 - バッチ処理 - 監視 - デプロイ / プロビジョニング - 生産性向上 アジェンダ 22

Slide 23

Slide 23 text

Search - CloudSearch をベースとした検索エンジン - 配信側のリクエスト (チャンネルの指定) を、CloudSearch のクエリに変換し記事を検索する SmartNews のニュース配信基盤:検索 23

Slide 24

Slide 24 text

Search - ユーザの行動情報や記事の注目度をベースにしたアルゴリズムからランキングを生成 - スコアのもととなる情報は、ニア・リアルタイムで集計している SmartNews のニュース配信基盤:検索 24

Slide 25

Slide 25 text

SmartNews のニュース配信基盤:検索 Recommend - ある記事の内容に類似する他の記事を CloudSearch から検索する検索エンジン - 記事分析結果から得た meta 情報を用いてオンラインで類似度を判定する 25

Slide 26

Slide 26 text

- SmartNews のニュース配信基盤のご紹介 - 記事収集 - 分析 - 検索 - 配信 - 監視 - ニュース配信基盤における Spring の活用 - サービスの分割と Spring の導入 - サービス間の連携 - バッチ処理 - 監視 - デプロイ / プロビジョニング - 生産性向上 アジェンダ 26

Slide 27

Slide 27 text

Frontend - ユーザからのリクエストに対して、購読チャンネルごとに記事リストを配信する - チャンネルの記事リストを検索エンジンに問い合わせる - 分散キャッシュを用いた検索エンジンの負荷低減 SmartNews のニュース配信基盤: 配信 27

Slide 28

Slide 28 text

SmartNews のニュース配信基盤: 配信 Frontend - リクエスト状況によって台数をスケール - ピークタイムでスケール - 号外ニュースを配信前に検知し事前にスケール - ピークタイムでは、平時の 2 から 4 倍近くのアクセスがある 28

Slide 29

Slide 29 text

SmartNews のニュース配信基盤: 配信 Push - Push 配信候補の選定 - アルゴリズムにより決定 - ユーザごとに、記事購読状況により - 編成を自動的に変更 - Push 配信対象ユーザの選定 - Push 送信 - 定時で全てのユーザにほぼ遅延なく送信 - 定時通知, 号外通知時によるスケール 29

Slide 30

Slide 30 text

- SmartNews のニュース配信基盤のご紹介 - 記事収集 - 分析 - 検索 - 配信 - 監視 - ニュース配信基盤における Spring の活用 - サービスの分割と Spring の導入 - サービス間の連携 - バッチ処理 - 監視 - デプロイ / プロビジョニング - 生産性向上 アジェンダ 30

Slide 31

Slide 31 text

- Datadog - 各種 metrics の監視、可視化 - NewRelic - 各種 performance を監視する APM - Runscope - 各種 API の外形監視 / E2E - PagerDuty - Datadog / Runscope と連携した Alert 用 SaaS SmartNews のニュース配信基盤:監視 31

Slide 32

Slide 32 text

Datadog SmartNews のニュース配信基盤:監視 32

Slide 33

Slide 33 text

Datadog SmartNews のニュース配信基盤:監視 33

Slide 34

Slide 34 text

Datadog SmartNews のニュース配信基盤:監視 34

Slide 35

Slide 35 text

Datadog SmartNews のニュース配信基盤:監視 35

Slide 36

Slide 36 text

Datadog SmartNews のニュース配信基盤:監視 36

Slide 37

Slide 37 text

NewRelic フロントエンドの Web サーバだけでなく engine 側のオフラインバッチ処理も Non-Web transaction として trace する SmartNews のニュース配信基盤:監視 37

Slide 38

Slide 38 text

Runscope SmartNews のニュース配信基盤:監視 38

Slide 39

Slide 39 text

Runscope SmartNews のニュース配信基盤:監視 39

Slide 40

Slide 40 text

PagerDuty SmartNews のニュース配信基盤:監視 40

Slide 41

Slide 41 text

PagerDuty SmartNews のニュース配信基盤:監視 41

Slide 42

Slide 42 text

SmartNews のニュース配信基盤 - バックエンドによる記事収集、分析と、オンラインによる検索・配信を担う - ユーザからのリクエストによりスケールし、安定した記事配信を実現する - 各種監視 SaaS により、システムの状態を監視している 42

Slide 43

Slide 43 text

- SmartNews のニュース配信基盤のご紹介 - 記事収集 - 分析 - 検索 - 配信 - 監視 - ニュース配信基盤における Spring の活用 - サービスの分割と Spring の導入 - サービス間の連携 - バッチ処理 - 監視 - デプロイ / プロビジョニング - 生産性向上 アジェンダ 43

Slide 44

Slide 44 text

ニュース配信基盤における Spring の活用 44

Slide 45

Slide 45 text

- SmartNews のニュース配信基盤のご紹介 - 記事収集 - 分析 - 検索 - 配信 - 監視 - ニュース配信基盤における Spring の活用 - サービスの分割と Spring の導入 - サービス間の連携 - バッチ処理 - 監視 - デプロイ / プロビジョニング - 生産性向上 アジェンダ 45

Slide 46

Slide 46 text

ニュース配信基盤の前身として Seasar2 による旧基盤が存在 Frontend Indexer Analyzer Search Crawler サービスの分割と Spring の導入 46

Slide 47

Slide 47 text

旧基盤の役割 - 記事の収集基盤 - 各種 Cralwer - 記事の分析基盤 - Crawler が収集した記事を分析 - オンメモリの記事データベース - 分散ノードごとに、記事とそのメタ情報をオンメモリで保持 - RMI によるノード間の協調動作 - 記事検索エンジン API - オンメモリのデータベースから記事を検索 現在のニュース配信基盤の各サービスが、 一つのサービスとして 開発・運用されていた サービスの分割と Spring の導入 47

Slide 48

Slide 48 text

旧基盤の問題点 - 機能追加、修正が非常に行いづらい - index を一つ追加するのにも一苦労 - 柔軟な検索が実現できない - 多様なユーザ体験を実現できない - トラブルシューティングが職人芸化 - スケールさせずらい - 開発者がビジネスロジックのみに集中できない - 非サーバサイドエンジニアの開発効率が向上しない ユーザに価値を届け続けるため、これらを解決する必要があった 徐々に分割は進んでいったが、根本的な基盤はモノリシックなままだった サービスの分割と Spring の導入 48

Slide 49

Slide 49 text

サービスの分割と Spring (Spring Boot) の導入 (2015/05 ~) - サービスを分割することで、個々に集中が出来る - Spring Boot を導入することで以下が実現できると考えた - 高い開発効率 - シンプルなインフラ・ミドルウェア構成 - 高度な周辺エコシステムの恩恵 開発者が本質的な開発作業に集中でき、結果としてサービスの価値をより高めることが できるという判断で導入 サービスの分割と Spring の導入 49

Slide 50

Slide 50 text

高い開発効率 - Spring Boot による Java-based Configuration で XML 地獄からの脱却 - Spring MVC で RESTFul API endpoint を手軽に作成可能 - SpringFox/Swagger による API 仕様の周知、可視化 サービスの分割と Spring の導入 50

Slide 51

Slide 51 text

シンプルなインフラ・ミドルウェア構成 - executable fat jar によるサービス起動 - war とは異なり、別途サーブレットコンテナを用意する必要が無い - リバースプロキシと Java プロセスのみのシンプルな構成が実現可能 - コンテナ化とも相性が良い サービスの分割と Spring の導入 51

Slide 52

Slide 52 text

高度な周辺エコシステム - Spring Cloud Config - Spring Cloud Consul - Reactor (Spring 5) サービスの分割と Spring の導入 ref: SpringOne Platform 2016 報告会「A Lite Rx API for the JVM」/ 井口 貝 http://www.slideshare.net/smartnews/springone-platform-2016-a-lite-rx-api-for-t he-jvm-smartnews-inc 52

Slide 53

Slide 53 text

サービスの分割と Spring の導入 Frontend Indexer Analyzer Search Crawler 53

Slide 54

Slide 54 text

サービスの分割と Spring の導入 Analyzer Crawler Search Frontend Indexer Importer 54

Slide 55

Slide 55 text

- サービスの分割と Spring の導入 - サービス間の連携 - バッチ処理 - 監視 - デプロイ / プロビジョニング ニュース配信基盤における Spring の活用 55

Slide 56

Slide 56 text

サービス間の連携 - オンラインのサービスは Spring MVC による RESTful API を利用して通信 - バックエンドのサービスは基本的に Kinesis を介して連携するが、管理用に Web API が存在 - spring-boot-starter-web を依存に追加することで Annotation ベースで簡単に API を追加可能 56

Slide 57

Slide 57 text

Swagger による仕様の可視化 - API 仕様を自動的に読み込み、可視化・構造化するツール群 - Spring-Boot では、SpringFox とともに利用する - springfox-swagger2 - springfox-swagger-ui - これらを用いると、Swagger に対応したサービス以下が有効になる - 自動生成された API 一覧 - それらのパラメタおよびレスポンス形式の可視化 - その場でリクエスト・レスポンスを試せる UI サービス間の連携 ref: Swagger http://swagger.io/ 57

Slide 58

Slide 58 text

サービス間の連携 58

Slide 59

Slide 59 text

- Swagger の API 仕様から、それらのサービスの Client Library の自動生成を実 現 - 各サービス間でクライアントを自作する必要がない - 現行仕様に正しく追従するクライアントライブラリ - swagger-codegen を fork し、自動生成プログラムを利用 サービス間の連携 ref: swagger-codegen https://github.com/swagger-api/swagger-cod egen 59

Slide 60

Slide 60 text

- サービスの分割と Spring の導入 - サービス間の連携 - バッチ処理 - 監視 - デプロイ / プロビジョニング ニュース配信基盤における Spring の活用 60

Slide 61

Slide 61 text

バッチ処理 Push や Crawler の一部にも Spring Boot を利用 - 定時起動やタスク間の依存関係などを解決するため @Scheduled / Spring Batch を利用 - Web API と同一フレームワークなので開発効率が良い - バッチプログラムの管理画面も、Spring Boot で手軽に作成している 61

Slide 62

Slide 62 text

- サービスの分割と Spring の導入 - サービス間の連携 - バッチ処理 - 監視 - デプロイ / プロビジョニング ニュース配信基盤における Spring の活用 62

Slide 63

Slide 63 text

監視 Spring Boot Admin を利用したお手軽な Service Discovery - 紐付いた Spring Boot サービスの一 覧、メトリクスの確認、設定変更が可 能 - オンラインで設定変更 (KV の注入、ログ レベルの変更) などができる - spring-boot-admin-starter-client を依存に追加し、application.yml で Admin の endpoint を設定 63

Slide 64

Slide 64 text

Spring Boot Admin の metrics 出力例 監視 64

Slide 65

Slide 65 text

監視 - spring-boot-actuator の充実した機能を利用し、Datadog と連携 - システム状態、VM 状態、API endpoint 毎のリクエスト数、データコネクションなどの監視 - カスタムな metrics の生成が可能 - - JMX での metrics も存在しているが、Spring の機能を利用して、自動・汎用的な 監視が実現 65

Slide 66

Slide 66 text

- spring-boot-actuator の metrics 出力例 監視 66

Slide 67

Slide 67 text

- SmartNews のニュース配信基盤のご紹介 - 記事収集 - 分析 - 検索 - 配信 - 監視 - ニュース配信基盤における Spring の活用 - サービスの分割と Spring の導入 - サービス間の連携 - バッチ処理 - 監視 - デプロイ / プロビジョニング - 生産性向上 アジェンダ 67

Slide 68

Slide 68 text

デプロイ / プロビジョニング - executable fat jar 構成を採用し java -jar でサービスを起動 - シンプルなプロビジョニング - nginx + java -jar (with supervisord) - シンプルなデプロイ - Deploy は CI でビルドした jar をダウンロードして起動 - GitHub で push 後に CircleCI/Jenkins + CodeDeploy で自動テスト、自動デプロイ 68

Slide 69

Slide 69 text

- SmartNews のニュース配信基盤のご紹介 - 記事収集 - 分析 - 検索 - 配信 - 監視 - ニュース配信基盤における Spring の活用 - サービスの分割と Spring の導入 - サービス間の連携 - バッチ処理 - 監視 - デプロイ / プロビジョニング - 生産性向上 アジェンダ 69

Slide 70

Slide 70 text

生産性向上 Controller レイヤの単体テスト - Runscope での E2E テスト / 外形監視に加えて、一部の endpoint では MockMvc による 単体テストを行っている 70

Slide 71

Slide 71 text

71

Slide 72

Slide 72 text

共通処理の intercepter (AOP) - 例: あるサービスのメソッドを引数単位でキャッシュする Interceptor - org.aopalliance.intercept.MethodInterceptor を継承したクラスで invoke を実装 生産性向上 72

Slide 73

Slide 73 text

73

Slide 74

Slide 74 text

共通処理の intercepter (AOP) - 例: あるサービスのメソッドを引数単位でキャッシュする Interceptor - Spring の Bean 生成時に、Interceptor を織り込んだ、キャッシュ対象のサービスの Proxy を生成して返 す - これらがすべてコードで書ける 生産性向上 74

Slide 75

Slide 75 text

生産性向上 Spring の DI コンテナを活用した柔軟なクエリ設定変更 - Spring Framework 上に、薄い検索 Framework を構築 - Search における CloudSearch への各種問い合わせロジックを DI コンテナに登録 - 外部からのパラメタで振る舞いを変更可能 - A/B テストやアドホックな記事取得に利用 75

Slide 76

Slide 76 text

Spring Boot with Kotlin - Crawler 一部のなどは Java でなく Kotlin で書かれている - 近年注目を集めている JetBrains 社が開発する JVM 言語 - Android での利用が注目されているが SmartNews では一部 Spring Boot アプリの開発で Kotlin を使っている - kotlin-stdlib を依存に追加 生産性向上 76

Slide 77

Slide 77 text

77

Slide 78

Slide 78 text

おわりに 78

Slide 79

Slide 79 text

SmartNews におけるニュース配信基盤をご紹介しました - 250 万人以上のユーザへ 5 万件以上の記事を配信 - 記事の収集、分析、検索、配信を実現 - バックエンド、オンラインの構成で、各処理がサービスに分かれている サービスが進化する過程でニュース配信基盤の大部分が Spring (Spring Boot) に移 行していきました - サービス間の連携やバッチ処理に役立っています - 運用・監視にも恩恵がありました - 生産性、開発速度が向上し、ユーザにより価値を届けられるようになりました - 技術的な挑戦もしやすい環境を整えられました おわりに 79

Slide 80

Slide 80 text

http://about.smartnews.com/ja/careers/ We’re hiring!! Web Application / iOS / Android / SRE / Ad-tech / Machine-learning / NLP