Submit Search
Upload
JavaからAkkaハンズオン
•
3 likes
•
1,843 views
TIS Inc.
Follow
JJUG CCC Fall 2018 Akkaハンズオンの資料です。 Javaで小さなWebアプリケーションを作成します。
Read less
Read more
Technology
Report
Share
Report
Share
1 of 84
Download now
Download to read offline
Recommended
ジェネリクスの基礎とクラス設計への応用
ジェネリクスの基礎とクラス設計への応用
nagise
Swaggerでのapi開発よもやま話
Swaggerでのapi開発よもやま話
KEISUKE KONISHI
世界一わかりやすいClean Architecture
世界一わかりやすいClean Architecture
Atsushi Nakamura
NuxtでAPIサーバー立ててみた
NuxtでAPIサーバー立ててみた
ssuserbf0fbd
Junitを使ったjavaのテスト入門
Junitを使ったjavaのテスト入門
Satoshi Kubo
シングルサインオンの歴史とSAMLへの道のり
シングルサインオンの歴史とSAMLへの道のり
Shinichi Tomita
LeSSでつなぐビジネスとIT
LeSSでつなぐビジネスとIT
Takao Kimura
Fargate起動歴1日の男が語る運用の勘どころ
Fargate起動歴1日の男が語る運用の勘どころ
Yuto Komai
Recommended
ジェネリクスの基礎とクラス設計への応用
ジェネリクスの基礎とクラス設計への応用
nagise
Swaggerでのapi開発よもやま話
Swaggerでのapi開発よもやま話
KEISUKE KONISHI
世界一わかりやすいClean Architecture
世界一わかりやすいClean Architecture
Atsushi Nakamura
NuxtでAPIサーバー立ててみた
NuxtでAPIサーバー立ててみた
ssuserbf0fbd
Junitを使ったjavaのテスト入門
Junitを使ったjavaのテスト入門
Satoshi Kubo
シングルサインオンの歴史とSAMLへの道のり
シングルサインオンの歴史とSAMLへの道のり
Shinichi Tomita
LeSSでつなぐビジネスとIT
LeSSでつなぐビジネスとIT
Takao Kimura
Fargate起動歴1日の男が語る運用の勘どころ
Fargate起動歴1日の男が語る運用の勘どころ
Yuto Komai
【Unite Tokyo 2018】さては非同期だなオメー!async/await完全に理解しよう
【Unite Tokyo 2018】さては非同期だなオメー!async/await完全に理解しよう
Unity Technologies Japan K.K.
Twitterのsnowflakeについて
Twitterのsnowflakeについて
moai kids
AngularとSpring Bootで作るSPA + RESTful Web Serviceアプリケーション
AngularとSpring Bootで作るSPA + RESTful Web Serviceアプリケーション
ssuser070fa9
Demystifying Identities for Azure Kubernetes Service
Demystifying Identities for Azure Kubernetes Service
Toru Makabe
Amazon EKS によるスマホゲームのバックエンド運用事例
Amazon EKS によるスマホゲームのバックエンド運用事例
gree_tech
LogbackからLog4j 2への移行によるアプリケーションのスループット改善 ( JJUG CCC 2021 Fall )
LogbackからLog4j 2への移行によるアプリケーションのスループット改善 ( JJUG CCC 2021 Fall )
Hironobu Isoda
Spring 歴約1年初心者の Test 奮闘記
Spring 歴約1年初心者の Test 奮闘記
chishizu naito
これからSpringを使う開発者が知っておくべきこと
これからSpringを使う開発者が知っておくべきこと
土岐 孝平
JIRA / Confluence の必須プラグインはこれだ
JIRA / Confluence の必須プラグインはこれだ
Narichika Kajihara
とにかく分かりづらいTwelve-Factor Appの解説を試みる
とにかく分かりづらいTwelve-Factor Appの解説を試みる
Masatoshi Tada
DeNAのゲームを支えるプラットフォーム Sakasho #denatechcon
DeNAのゲームを支えるプラットフォーム Sakasho #denatechcon
DeNA
Keycloakの実際・翻訳プロジェクト紹介
Keycloakの実際・翻訳プロジェクト紹介
Hiroyuki Wada
大規模ソーシャルゲームを支える技術~PHP+MySQLを使った高負荷対策~
大規模ソーシャルゲームを支える技術~PHP+MySQLを使った高負荷対策~
infinite_loop
怖くないSpring Bootのオートコンフィグレーション
怖くないSpring Bootのオートコンフィグレーション
土岐 孝平
Ganglia のUIにGrafanaを追加する話
Ganglia のUIにGrafanaを追加する話
KLab Inc. / Tech
ソーシャルゲームのためのデータベース設計
ソーシャルゲームのためのデータベース設計
Yoshinori Matsunobu
Nuxt.jsとExpressでSPA×SSR×API Aggregationを実現した話
Nuxt.jsとExpressでSPA×SSR×API Aggregationを実現した話
Recruit Lifestyle Co., Ltd.
ゲームの仕様書を書こうまとめ
ゲームの仕様書を書こうまとめ
Sugimoto Chizuru
NTTデータ流Infrastructure as Code~ 大規模プロジェクトを通して考え抜いた基盤自動化の新たな姿~(NTTデータ テクノロジーカンフ...
NTTデータ流Infrastructure as Code~ 大規模プロジェクトを通して考え抜いた基盤自動化の新たな姿~(NTTデータ テクノロジーカンフ...
NTT DATA Technology & Innovation
PFNのオンプレ計算機クラスタの取り組み_第55回情報科学若手の会
PFNのオンプレ計算機クラスタの取り組み_第55回情報科学若手の会
Preferred Networks
LoRaWANとAzure IoT Hub接続ハンズオン
LoRaWANとAzure IoT Hub接続ハンズオン
Tomokazu Kizawa
React vtecx20171025
React vtecx20171025
Shinichiro Takezaki
More Related Content
What's hot
【Unite Tokyo 2018】さては非同期だなオメー!async/await完全に理解しよう
【Unite Tokyo 2018】さては非同期だなオメー!async/await完全に理解しよう
Unity Technologies Japan K.K.
Twitterのsnowflakeについて
Twitterのsnowflakeについて
moai kids
AngularとSpring Bootで作るSPA + RESTful Web Serviceアプリケーション
AngularとSpring Bootで作るSPA + RESTful Web Serviceアプリケーション
ssuser070fa9
Demystifying Identities for Azure Kubernetes Service
Demystifying Identities for Azure Kubernetes Service
Toru Makabe
Amazon EKS によるスマホゲームのバックエンド運用事例
Amazon EKS によるスマホゲームのバックエンド運用事例
gree_tech
LogbackからLog4j 2への移行によるアプリケーションのスループット改善 ( JJUG CCC 2021 Fall )
LogbackからLog4j 2への移行によるアプリケーションのスループット改善 ( JJUG CCC 2021 Fall )
Hironobu Isoda
Spring 歴約1年初心者の Test 奮闘記
Spring 歴約1年初心者の Test 奮闘記
chishizu naito
これからSpringを使う開発者が知っておくべきこと
これからSpringを使う開発者が知っておくべきこと
土岐 孝平
JIRA / Confluence の必須プラグインはこれだ
JIRA / Confluence の必須プラグインはこれだ
Narichika Kajihara
とにかく分かりづらいTwelve-Factor Appの解説を試みる
とにかく分かりづらいTwelve-Factor Appの解説を試みる
Masatoshi Tada
DeNAのゲームを支えるプラットフォーム Sakasho #denatechcon
DeNAのゲームを支えるプラットフォーム Sakasho #denatechcon
DeNA
Keycloakの実際・翻訳プロジェクト紹介
Keycloakの実際・翻訳プロジェクト紹介
Hiroyuki Wada
大規模ソーシャルゲームを支える技術~PHP+MySQLを使った高負荷対策~
大規模ソーシャルゲームを支える技術~PHP+MySQLを使った高負荷対策~
infinite_loop
怖くないSpring Bootのオートコンフィグレーション
怖くないSpring Bootのオートコンフィグレーション
土岐 孝平
Ganglia のUIにGrafanaを追加する話
Ganglia のUIにGrafanaを追加する話
KLab Inc. / Tech
ソーシャルゲームのためのデータベース設計
ソーシャルゲームのためのデータベース設計
Yoshinori Matsunobu
Nuxt.jsとExpressでSPA×SSR×API Aggregationを実現した話
Nuxt.jsとExpressでSPA×SSR×API Aggregationを実現した話
Recruit Lifestyle Co., Ltd.
ゲームの仕様書を書こうまとめ
ゲームの仕様書を書こうまとめ
Sugimoto Chizuru
NTTデータ流Infrastructure as Code~ 大規模プロジェクトを通して考え抜いた基盤自動化の新たな姿~(NTTデータ テクノロジーカンフ...
NTTデータ流Infrastructure as Code~ 大規模プロジェクトを通して考え抜いた基盤自動化の新たな姿~(NTTデータ テクノロジーカンフ...
NTT DATA Technology & Innovation
PFNのオンプレ計算機クラスタの取り組み_第55回情報科学若手の会
PFNのオンプレ計算機クラスタの取り組み_第55回情報科学若手の会
Preferred Networks
What's hot
(20)
【Unite Tokyo 2018】さては非同期だなオメー!async/await完全に理解しよう
【Unite Tokyo 2018】さては非同期だなオメー!async/await完全に理解しよう
Twitterのsnowflakeについて
Twitterのsnowflakeについて
AngularとSpring Bootで作るSPA + RESTful Web Serviceアプリケーション
AngularとSpring Bootで作るSPA + RESTful Web Serviceアプリケーション
Demystifying Identities for Azure Kubernetes Service
Demystifying Identities for Azure Kubernetes Service
Amazon EKS によるスマホゲームのバックエンド運用事例
Amazon EKS によるスマホゲームのバックエンド運用事例
LogbackからLog4j 2への移行によるアプリケーションのスループット改善 ( JJUG CCC 2021 Fall )
LogbackからLog4j 2への移行によるアプリケーションのスループット改善 ( JJUG CCC 2021 Fall )
Spring 歴約1年初心者の Test 奮闘記
Spring 歴約1年初心者の Test 奮闘記
これからSpringを使う開発者が知っておくべきこと
これからSpringを使う開発者が知っておくべきこと
JIRA / Confluence の必須プラグインはこれだ
JIRA / Confluence の必須プラグインはこれだ
とにかく分かりづらいTwelve-Factor Appの解説を試みる
とにかく分かりづらいTwelve-Factor Appの解説を試みる
DeNAのゲームを支えるプラットフォーム Sakasho #denatechcon
DeNAのゲームを支えるプラットフォーム Sakasho #denatechcon
Keycloakの実際・翻訳プロジェクト紹介
Keycloakの実際・翻訳プロジェクト紹介
大規模ソーシャルゲームを支える技術~PHP+MySQLを使った高負荷対策~
大規模ソーシャルゲームを支える技術~PHP+MySQLを使った高負荷対策~
怖くないSpring Bootのオートコンフィグレーション
怖くないSpring Bootのオートコンフィグレーション
Ganglia のUIにGrafanaを追加する話
Ganglia のUIにGrafanaを追加する話
ソーシャルゲームのためのデータベース設計
ソーシャルゲームのためのデータベース設計
Nuxt.jsとExpressでSPA×SSR×API Aggregationを実現した話
Nuxt.jsとExpressでSPA×SSR×API Aggregationを実現した話
ゲームの仕様書を書こうまとめ
ゲームの仕様書を書こうまとめ
NTTデータ流Infrastructure as Code~ 大規模プロジェクトを通して考え抜いた基盤自動化の新たな姿~(NTTデータ テクノロジーカンフ...
NTTデータ流Infrastructure as Code~ 大規模プロジェクトを通して考え抜いた基盤自動化の新たな姿~(NTTデータ テクノロジーカンフ...
PFNのオンプレ計算機クラスタの取り組み_第55回情報科学若手の会
PFNのオンプレ計算機クラスタの取り組み_第55回情報科学若手の会
Similar to JavaからAkkaハンズオン
LoRaWANとAzure IoT Hub接続ハンズオン
LoRaWANとAzure IoT Hub接続ハンズオン
Tomokazu Kizawa
React vtecx20171025
React vtecx20171025
Shinichiro Takezaki
Terraform with Bitbucket pipeline
Terraform with Bitbucket pipeline
Masatomo Ito
React vtecx20171129
React vtecx20171129
Shinichiro Takezaki
YJTC18 A-1 大規模サーバの戦略
YJTC18 A-1 大規模サーバの戦略
Yahoo!デベロッパーネットワーク
第5回 デジタルガジェット祭り! スマートスピーカー特集(4)
第5回 デジタルガジェット祭り! スマートスピーカー特集(4)
aitc_jp
DLモデル開発中の雑務が嫌で支援プラットフォームを作った話
DLモデル開発中の雑務が嫌で支援プラットフォームを作った話
Kamonohashi
テレビ版GYAO!アプリへのOAuth2.0 Device Flowの実装
テレビ版GYAO!アプリへのOAuth2.0 Device Flowの実装
Hiromitsu Homma
【初心者向け】API を使ってクラウドの管理を自動化しよう
【初心者向け】API を使ってクラウドの管理を自動化しよう
富士通クラウドテクノロジーズ株式会社
Spring I/O 2018 報告会
Spring I/O 2018 報告会
NTT Software Innovation Center
Spring I/O 2018 報告 RESTDocs RAML, Cloud Contract
Spring I/O 2018 報告 RESTDocs RAML, Cloud Contract
Takuya Iwatsuka
Spring Boot × Vue.jsでSPAを作る
Spring Boot × Vue.jsでSPAを作る
Go Miyasaka
JSUG 2018 BTC
JSUG 2018 BTC
kazukiotomori
React vtecx20170822
React vtecx20170822
Shinichiro Takezaki
Jazug-8th: Azure AKS & FIWARE & Robot
Jazug-8th: Azure AKS & FIWARE & Robot
Nobuyuki Matsui
Go + Pulsar WebSocket APIの利用事例 #pulsarjp
Go + Pulsar WebSocket APIの利用事例 #pulsarjp
Yahoo!デベロッパーネットワーク
AITCオープンラボ 2018年5月度(2)
AITCオープンラボ 2018年5月度(2)
aitc_jp
ソフトウェアジャパン2018 ITフォーラムセッション(3)
ソフトウェアジャパン2018 ITフォーラムセッション(3)
aitc_jp
JTF2018 FIWARE x robot x IoT
JTF2018 FIWARE x robot x IoT
Nobuyuki Matsui
技術選択とアーキテクトの役割
技術選択とアーキテクトの役割
Toru Yamaguchi
Similar to JavaからAkkaハンズオン
(20)
LoRaWANとAzure IoT Hub接続ハンズオン
LoRaWANとAzure IoT Hub接続ハンズオン
React vtecx20171025
React vtecx20171025
Terraform with Bitbucket pipeline
Terraform with Bitbucket pipeline
React vtecx20171129
React vtecx20171129
YJTC18 A-1 大規模サーバの戦略
YJTC18 A-1 大規模サーバの戦略
第5回 デジタルガジェット祭り! スマートスピーカー特集(4)
第5回 デジタルガジェット祭り! スマートスピーカー特集(4)
DLモデル開発中の雑務が嫌で支援プラットフォームを作った話
DLモデル開発中の雑務が嫌で支援プラットフォームを作った話
テレビ版GYAO!アプリへのOAuth2.0 Device Flowの実装
テレビ版GYAO!アプリへのOAuth2.0 Device Flowの実装
【初心者向け】API を使ってクラウドの管理を自動化しよう
【初心者向け】API を使ってクラウドの管理を自動化しよう
Spring I/O 2018 報告会
Spring I/O 2018 報告会
Spring I/O 2018 報告 RESTDocs RAML, Cloud Contract
Spring I/O 2018 報告 RESTDocs RAML, Cloud Contract
Spring Boot × Vue.jsでSPAを作る
Spring Boot × Vue.jsでSPAを作る
JSUG 2018 BTC
JSUG 2018 BTC
React vtecx20170822
React vtecx20170822
Jazug-8th: Azure AKS & FIWARE & Robot
Jazug-8th: Azure AKS & FIWARE & Robot
Go + Pulsar WebSocket APIの利用事例 #pulsarjp
Go + Pulsar WebSocket APIの利用事例 #pulsarjp
AITCオープンラボ 2018年5月度(2)
AITCオープンラボ 2018年5月度(2)
ソフトウェアジャパン2018 ITフォーラムセッション(3)
ソフトウェアジャパン2018 ITフォーラムセッション(3)
JTF2018 FIWARE x robot x IoT
JTF2018 FIWARE x robot x IoT
技術選択とアーキテクトの役割
技術選択とアーキテクトの役割
More from TIS Inc.
AWSマネージドサービスとOSSによるミッションクリティカルなシステムの実現
AWSマネージドサービスとOSSによるミッションクリティカルなシステムの実現
TIS Inc.
Reactive Systems that focus on High Availability with Lerna
Reactive Systems that focus on High Availability with Lerna
TIS Inc.
Starting Reactive Systems with Lerna #reactive_shinjuku
Starting Reactive Systems with Lerna #reactive_shinjuku
TIS Inc.
可用性を突き詰めたリアクティブシステム
可用性を突き詰めたリアクティブシステム
TIS Inc.
EventStormingワークショップ 〜かつてない図書館をモデリングしてみよう〜
EventStormingワークショップ 〜かつてない図書館をモデリングしてみよう〜
TIS Inc.
Akkaの並行性
Akkaの並行性
TIS Inc.
リアクティブシステムとAkka
リアクティブシステムとAkka
TIS Inc.
Akka in Action workshop #ScalaMatsuri 2018
Akka in Action workshop #ScalaMatsuri 2018
TIS Inc.
Preparing for distributed system failures using akka #ScalaMatsuri
Preparing for distributed system failures using akka #ScalaMatsuri
TIS Inc.
Akkaで実現するステートフルでスケーラブルなアーキテクチャ
Akkaで実現するステートフルでスケーラブルなアーキテクチャ
TIS Inc.
akka-doc-ja
akka-doc-ja
TIS Inc.
10分で分かるリアクティブシステム
10分で分かるリアクティブシステム
TIS Inc.
Typesafe Reactive Platformで作るReactive System入門
Typesafe Reactive Platformで作るReactive System入門
TIS Inc.
Typesafe Reactive Platformで作るReactive System
Typesafe Reactive Platformで作るReactive System
TIS Inc.
Effective Akka読書会2
Effective Akka読書会2
TIS Inc.
再帰で脱Javaライク
再帰で脱Javaライク
TIS Inc.
Scalable Generator: Using Scala in SIer Business (ScalaMatsuri)
Scalable Generator: Using Scala in SIer Business (ScalaMatsuri)
TIS Inc.
甲賀流Jenkins活用術
甲賀流Jenkins活用術
TIS Inc.
More from TIS Inc.
(18)
AWSマネージドサービスとOSSによるミッションクリティカルなシステムの実現
AWSマネージドサービスとOSSによるミッションクリティカルなシステムの実現
Reactive Systems that focus on High Availability with Lerna
Reactive Systems that focus on High Availability with Lerna
Starting Reactive Systems with Lerna #reactive_shinjuku
Starting Reactive Systems with Lerna #reactive_shinjuku
可用性を突き詰めたリアクティブシステム
可用性を突き詰めたリアクティブシステム
EventStormingワークショップ 〜かつてない図書館をモデリングしてみよう〜
EventStormingワークショップ 〜かつてない図書館をモデリングしてみよう〜
Akkaの並行性
Akkaの並行性
リアクティブシステムとAkka
リアクティブシステムとAkka
Akka in Action workshop #ScalaMatsuri 2018
Akka in Action workshop #ScalaMatsuri 2018
Preparing for distributed system failures using akka #ScalaMatsuri
Preparing for distributed system failures using akka #ScalaMatsuri
Akkaで実現するステートフルでスケーラブルなアーキテクチャ
Akkaで実現するステートフルでスケーラブルなアーキテクチャ
akka-doc-ja
akka-doc-ja
10分で分かるリアクティブシステム
10分で分かるリアクティブシステム
Typesafe Reactive Platformで作るReactive System入門
Typesafe Reactive Platformで作るReactive System入門
Typesafe Reactive Platformで作るReactive System
Typesafe Reactive Platformで作るReactive System
Effective Akka読書会2
Effective Akka読書会2
再帰で脱Javaライク
再帰で脱Javaライク
Scalable Generator: Using Scala in SIer Business (ScalaMatsuri)
Scalable Generator: Using Scala in SIer Business (ScalaMatsuri)
甲賀流Jenkins活用術
甲賀流Jenkins活用術
Recently uploaded
論文紹介:Semantic segmentation using Vision Transformers: A survey
論文紹介:Semantic segmentation using Vision Transformers: A survey
Toru Tamaki
SOPを理解する 2024/04/19 の勉強会で発表されたものです
SOPを理解する 2024/04/19 の勉強会で発表されたものです
iPride Co., Ltd.
Postman LT Fukuoka_Quick Prototype_By Daniel
Postman LT Fukuoka_Quick Prototype_By Daniel
danielhu54
論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...
論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...
Toru Tamaki
スマートフォンを用いた新生児あやし動作の教示システム
スマートフォンを用いた新生児あやし動作の教示システム
sugiuralab
Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介
Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介
Yuma Ohgami
TSAL operation mechanism and circuit diagram.pdf
TSAL operation mechanism and circuit diagram.pdf
taisei2219
論文紹介:Automated Classification of Model Errors on ImageNet
論文紹介:Automated Classification of Model Errors on ImageNet
Toru Tamaki
[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略
[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略
Ryo Sasaki
Recently uploaded
(9)
論文紹介:Semantic segmentation using Vision Transformers: A survey
論文紹介:Semantic segmentation using Vision Transformers: A survey
SOPを理解する 2024/04/19 の勉強会で発表されたものです
SOPを理解する 2024/04/19 の勉強会で発表されたものです
Postman LT Fukuoka_Quick Prototype_By Daniel
Postman LT Fukuoka_Quick Prototype_By Daniel
論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...
論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...
スマートフォンを用いた新生児あやし動作の教示システム
スマートフォンを用いた新生児あやし動作の教示システム
Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介
Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介
TSAL operation mechanism and circuit diagram.pdf
TSAL operation mechanism and circuit diagram.pdf
論文紹介:Automated Classification of Model Errors on ImageNet
論文紹介:Automated Classification of Model Errors on ImageNet
[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略
[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略
JavaからAkkaハンズオン
1.
Copyright © 2018
TIS Inc. All rights reserved. JavaからAkkaハンズオン JJUG Fall 2018 前出祐吾 @yugolf JavaからAkkaハンズオンの準備⼿順 https://qiita.com/yugolf/items/701ba01ef283c868119a
2.
Copyright © 2018
TIS Inc. All rights reserved. TIS株式会社 前出 祐吾 @yugolf 最近の研究テーマ オープン環境で⾼可⽤システムどうやって構築する? 翻訳した本 連載 ThinkIT:メニーコア時代のパラダイム リアクティブシステムを知ろう 2 ⾃⼰紹介 エンジニア積極採⽤中
3.
Copyright © 2018
TIS Inc. All rights reserved. 3 本⽇のアジェンダ 1.Akkaとは 2.Akkaで実装してみる ‣ゴール Akkaを使った実装の取っ掛かりを掴む • Akkaでどう実装するのか? • その後どう学んでいけばよいか?
4.
Copyright © 2018
TIS Inc. All rights reserved. 4 教材 ✦here
5.
Copyright © 2018
TIS Inc. All rights reserved. 5 ⽬次 https://www.shoeisha.co.jp/book/detail/9784798153278 第1章 Akkaの紹介 第2章 最⼩のAkkaアプリケーション 第3章 アクターによるテスト駆動開発 第4章 耐障害性 第5章 Future 第6章 Akkaによるはじめての分散アプリケーション 第7章 設定とロギングとデプロイ 第8章 アクターの構造パターン 第9章 メッセージのルーティング 第10章 メッセージチャネル 第11章 有限状態マシンとエージェント 第12章 ストリーミング 第13章 システム統合 第14章 クラスタリング 第15章 アクターの永続化 第16章 パフォーマンスTips 第17章 Akkaのこれから 付録 AkkaをJavaから使う TODAY • 第2章 最⼩のAkkaアプリケーション • クローンとビルドとインターフェイスのテスト • アプリケーションでのActorの探求 • クラウドへ
6.
Copyright © 2018
TIS Inc. All rights reserved. Akkaとは 6 第1章 Akkaの紹介
7.
Copyright © 2018
TIS Inc. All rights reserved. 7 Akkaとは 並⾏・分散システムを構築するためのツールキット • スケールアップ(並⾏)やスケールアウ ト(分散)の実現によるアプリケーショ ンの複雑化を抑⽌ • JavaとScalaのAPIを提供
8.
Copyright © 2018
TIS Inc. All rights reserved. 8 単⼀のプログラミングモデルでスケールアップ・スケールアウト アクターモデルはメッセージの送受信を抽象化することにより、 実装とスレッドの数やサーバーの台数に対する結合度を下げる シングルスレッドで実⾏ 複数サーバーで実⾏ 逐次処理 並⾏処理 分散処理 アクターモデル マルチコアで実⾏ 位置透過性
9.
Copyright © 2018
TIS Inc. All rights reserved. アクターモデル 9 第2章 最⼩のAkkaアプリケーション
10.
Copyright © 2018
TIS Inc. All rights reserved. 10 アクターモデルとは 並⾏的に受信するメッセージに対する以下のふるまいを備える • アクターを作る • アクターにメッセージを送信する • メッセージを受信したときの動作を指定する トラディショナルモデルとの違い トラディショナルモデル アクターモデル 逐次実⾏が基本で部分的に並⾏処理を実装 本質的に並⾏
11.
Copyright © 2018
TIS Inc. All rights reserved. 11 本質的に並⾏? お客さん チケット販売員 Buy Buy Buy メールボックス Akkaを使うことでアクターのプログラミングに集中できる • コンポーネント間のやり取りはメッセージで⾏う • 関数の応答を待つ必要はなく並⾏に処理される • アクターはメールボックスを持ち到着順に処理する
12.
Copyright © 2018
TIS Inc. All rights reserved. 12 もしあなたがErlangの世界のアクターだった場合 あなたは孤独な⼈間で、窓もない暗い部屋に座っていて、メール ボックスにメッセージが届くのを待っている状態です。 そしてメッセージを受け取ると、それに対して特定の⽅法で反応し ます:メッセージを受け取るときにお⾦を払い、誕⽣⽇カードには 「ありがとう(“Thank you”)」という⽂字で返事をし、理解出来な い⽂字は無視するという具合です。 「すごいErlangゆかいに学ぼう!」より https://www.ymotongpoo.com/works/lyse-ja/ja/01_introduction.html
13.
Copyright © 2018
TIS Inc. All rights reserved. Akkaのアクター 13 第2章 最⼩のAkkaアプリケーション
14.
Copyright © 2018
TIS Inc. All rights reserved. 14 トラディショナルスタイルとAkkaを4つのケースで⽐較 Akkaとは/概要/従来型との違い/アクターのプログ ラミングモデル/Akkaのアクター 1)データを保存して耐久性のあるものにしたい 2)インタラクティブな機能を実装したい 3)サービスを分離して疎結合にしたい 4)システム全体の障害を避けたい
15.
Copyright © 2018
TIS Inc. All rights reserved. 15 1) データを耐久性のあるものにしたい インメモリーに状態を持ち、ロック制御なしに書き換える 1万円引落し 1万円引落し 残⾼ 1万円 ATM モバイル 1万円引落し 1万円引落し ロック ATM モバイル ⼝座 残⾼ 1万円 トラディショナル Akka ボトルネック
16.
Copyright © 2018
TIS Inc. All rights reserved. 16 1) データを耐久性のあるものにしたい 状態をイベントとして永続化しておき(Akka Persistence)、 これらを再⽣することで状態を復元できる • 1万円引落 • 1万円引落 • 3万円預⼊ 「スケールアウトしやすいようステートレスに」、 から「ステートフルでスケーラブルに」 イベントの永続化 イベントの再⽣ 1万円引落し 1万円引落し ATM モバイル ⼝座 残⾼ 1万円 イベントソーシング
17.
Copyright © 2018
TIS Inc. All rights reserved. 17 2) インタラクティブな機能を作りたい メッセージパッシングなので基本プッシュ ポーリング @Bob “こんにちは!” Alice Bob プッシュ Alice Bob チャットサーバー トラディショナル Akka
18.
Copyright © 2018
TIS Inc. All rights reserved. チャットサーバー メンションサーバー - 時間的疎結合:メッセージの応答を待たない - 機能的疎結合:送信後どうなったか知らない - 位置的疎結合:別サーバーにいてもいい 18 3) サービスを分離して疎結合にしたい メッセージパッシングなので元々⾮同期で疎結合 • 密結合は複雑度をあげる • 変更容易=技術的負債になりづらい、ほどよい疎結合 「メンション」がメッセー ジを受信したときのふる まいを定義するだけ 「メンション」のふるまい が変わっても「会話」は影 響を受けない チャット エンキュー デキュー 会話 メンションMeメンション トラディショナル Akka
19.
Copyright © 2018
TIS Inc. All rights reserved. 19 4) システム全体の障害を避けたい アクターでエラーが発⽣したらスーパーバイザーへ コーヒ1本 故障!! システムをダウンさせないよう、 すべての障害を想定しCatch ⾃販機でコーヒーを買う try { vendingMachine.buy() } catch () { // ⾃販機の故障など // 障害が発⽣したときの処理 } 障害制御はスーパーバイザーに任せる Dave ⾃販機 スーパーバイザー トラディショナル Akka - 障害制御においても疎結合 (⾃動販売機の故障はコーヒーを買った⼈では なく⾃動販売機の管理者が対処)
20.
Copyright © 2018
TIS Inc. All rights reserved. 20 スーパーバイザーヒエラルキー https://doc.akka.io/docs/akka/2.5/general/supervision.html Akkaは適切な単位で障害制御を⾏うため、スーパーバイザーヒエラルキーを持つ
21.
Copyright © 2018
TIS Inc. All rights reserved. 21 1)データを耐久性のあるものにしたい DB インメモリーで状態を持ちイベントを永続化 2)インタラクティブな機能を実装したい ポーリング メッセージパッシング 3)サービスを分離して疎結合にしたい キュー アクター間は疎結合 4)システム全体の障害を避けたい 全障害シナリオをキャッチ コンポーネント間で影響なし トラディショナルスタイルとAkkaを4つのケースで⽐較してみた
22.
Copyright © 2018
TIS Inc. All rights reserved. 最小のAkkaアプリケーション 22 •クローンとビルドとインターフェイスのテスト •アプリケーションでのActorの探求 •クラウドへ
23.
Copyright © 2018
TIS Inc. All rights reserved. 23 クローンとビルド • github.com からサンプルプロジェクトをクローン $git clone https://github.com/yugolf/akka-in-action-java.git $cd akka-in-action-java/chapter-up-and-running/ $mvn compile exec:exec https://github.com/yugolf/akka-in-action-java/tree/master/chapter-up-and-running • ビルドとアプリケーションの起動 Slf4jLogger: Slf4jLogger started Main: start actor system: go-ticks Main: Server online at http://0.0.0.0:5000 Main: Press RETURN to stop... ※Mavenがインストールされていない場合はmvnwを使⽤してください。 例) ./mvnw compile exec:exec https://github.com/takari/maven-wrapper ※事前準備でクローン済の⼈はgit pull で最新を取得してください。
24.
Copyright © 2018
TIS Inc. All rights reserved. 24 プロジェクトの構成 プロジェクトの構造 リソース ソースコード テストコード ビルド成果物 Mavenのビルドファイル https://www.jetbrains.com/idea/download/
25.
Copyright © 2018
TIS Inc. All rights reserved. 25 構築するアプリケーション • イベント⼀覧の参照 • チケットの購⼊ • イベントの作成 • イベントのキャンセル チケット販売サービス GoTicks.com イベント管理者 お客さん
26.
Copyright © 2018
TIS Inc. All rights reserved. 26 Web API確認のための準備 まずは、動かしてみましょう! HTTPリクエストのツールをインストールしてアプリを起動 • HTTPリクエスト送信ツールのインストール • HTTPie または Advanced REST client - CLI: HTTPie (https://httpie.org/) - GUI: Advanced REST client(Chrome Extensions) https://chrome.google.com/webstore/detail/advanced-rest- client/hgmloofddffdnphfgcellkdfbfbjeloo $brew install httpie
27.
Copyright © 2018
TIS Inc. All rights reserved. 27 HTTPieでリクエスト送信 • CLI: HTTPie $http POST localhost:5000/events/JJUG/ tickets:=3 HTTP/1.1 201 Created Content-Length: 27 Content-Type: application/json Date: Sun, 02 Dec 2018 06:42:52 GMT Server: GoTicks.com REST API { "name": "JJUG", "tickets": 3 }
28.
Copyright © 2018
TIS Inc. All rights reserved. 28 REST clientでリクエスト送信 • GUI: Advanced REST client(Chrome Extensions) (1) (2) (3) (4) (8) http://localhost:5000/events/JJUG (5) (6) (7) {"tickets":3}
29.
Copyright © 2018
TIS Inc. All rights reserved. 29 APIのエンドポイント HTTPieコマンド • イベント作成 • チケット購⼊ • イベント⼀覧取得 • イベント取得 • イベントキャンセル $http POST localhost:5000/events/JJUG/ tickets:=3 $http GET localhost:5000/events $http POST localhost:5000/events/JJUG/tickets tickets:=2 $http DELETE localhost:5000/events/JJUG/ 機能 HTTPメソッド パス JSON イベント作成 POST /events/<イベント名>/ {"tickets":<枚数>} チケット購⼊ POST /events/<イベント名>/tickets/ {"tickets":<枚数>} イベント⼀覧 GET /events/ イベント取得 GET /events/<イベント名>/ イベントキャンセル DELETE /events/<イベント名>/ $http GET localhost:5000/events/JJUG/
30.
Copyright © 2018
TIS Inc. All rights reserved. 30 >イベント⼀覧の取得 >「JJUG」を2枚購⼊ >イベント⼀覧の取得 >「JJUG」を8枚購⼊ >「JJUG」を2枚購⼊ >チケット10枚の「JJUG」イベントを作成 >チケット20枚の「ScalaMatsuri」イベントを作成 >「ScalaMatsuri」をキャンセル >イベント⼀覧の取得 チケット販売サービスを使ってみる イベント管理者 お客さん
31.
Copyright © 2018
TIS Inc. All rights reserved. 最小のAkkaアプリケーション 31 •クローンとビルドとインターフェイスのテスト •アプリケーションでのActorの探求 •クラウドへ
32.
Copyright © 2018
TIS Inc. All rights reserved. 32 ハンズオン⽤のブランチを取得 ワークショップ⽤ブランチの取得 $ git checkout handson
33.
Copyright © 2018
TIS Inc. All rights reserved. ActorSystem “go-ticks” 33 クラス構成 Main HTTP Server run new create create create Actor BoxOffice Actor TicketSeller HTTP Route RestApi
34.
Copyright © 2018
TIS Inc. All rights reserved. Interface ITicketSeller Interface IBoxOffice 34 アクターの関係 JJUG Scala Matsuri boxOffice create Add/Buy/Cancel/… Actor BoxOffice Actor TicketSeller
35.
Copyright © 2018
TIS Inc. All rights reserved. Exercise 0. アクターシステムの生成 35 演習0.アクターシステムの⽣成
36.
Copyright © 2018
TIS Inc. All rights reserved. ActorSystem “go-ticks” 36 アクターシステムの⽣成 アクターシステムの⽣成 Main HTTP Server HTTP Route RestApi Actor BoxOffice Actor TicketSeller run new create create create
37.
Copyright © 2018
TIS Inc. All rights reserved. 37 「go-ticks」 ActorSystemを⽣成する 0.0.[Main] ActorSystemの⽣成 アプリケーションの実⾏ final ActorSystem system = ActorSystem.create("go-ticks"); $ mvn compile exec:exec ... Slf4jLogger: Slf4jLogger started Main: start actor system: go-ticks Main: Server online at http://0.0.0.0:5000 Main: Press RETURN to stop... ※Mavenがインストールされていない場合はmvnwを使⽤してください。 例) ./mvnw compile exec:exec https://github.com/takari/maven-wrapper
38.
Copyright © 2018
TIS Inc. All rights reserved. Exercise 1. イベントの作成 38 演習1.イベントの作成
39.
Copyright © 2018
TIS Inc. All rights reserved. 39 HTTP Route RestApi Actor BoxOffice Actor TicketSeller CreateEvent create EventCreated EventExists POST /events/JJUG Created 201 BadRequest 400 Add イベント作成時のメッセージの流れ
40.
Copyright © 2018
TIS Inc. All rights reserved. 40 イベント作成時のメッセージの流れ:実装箇所 実装するところ Actorの⽣成とメッセージ送信(Add/ EventCreated) HTTP Route RestApi Actor BoxOffice Actor TicketSeller CreateEvent create AddEventCreated EventExists POST /events/JJUG Created 201 BadRequest 400
41.
Copyright © 2018
TIS Inc. All rights reserved. 41 実装: アクターの⽣成・定義とメッセージ送信 演習1:TicketSellerアクターの⽣成、Addメッセージ の送信、EventCreatedメッセージの返信 • TicketSellerアクターの⽣成 1.1.[TicketSeller] アクターのファクトリーメソッドを定義 1.2.[BoxOffice ] TicketSellerアクターの⽣成 • BoxOfficeアクターからTicketSellerアクターへAddメッセージを送信 1.3.[TicketSeller] メッセージプロトコルの定義 1.4.[TicketSeller] メッセージ受信時のふるまい定義 1.5.[BoxOffice ] Addメッセージの送信 • BoxOfficeからRestApiへEventCreatedメッセージを返信 1.6.[BoxOffice ] EventCreatedメッセージの返信
42.
Copyright © 2018
TIS Inc. All rights reserved. 42 テストによる実⾏結果の確認 RestApiTest#testCreateEventの実⾏ $mvn test -Dtest=RestApiTest#testCreateEvent ... ------------------------------------------------------- T E S T S ------------------------------------------------------- Running com.goticks.RestApiTest Slf4jLogger: Slf4jLogger started Slf4jLogger: Slf4jLogger started RestApi: ---------- POST /events/RHCP/ {"tickets":3} ---------- BoxOffice: 📩 IBoxOffice.CreateEvent[name=RHCP,tickets=3] TicketSeller: 📩 ITicketSeller.Add[tickets=[ITicketSeller.Ticket[id=1], ITicketSeller.Ticket[id=2], ITicketSeller.Ticket[id=3]]] RestApi: 📩 IBoxOffice.EventCreated[event=IBoxOffice.Event[name=RHCP,tickets=3]] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 5.634 sec Results : Tests run: 1, Failures: 0, Errors: 0, Skipped: 0 ... ※Windowsだと「📩 」が「?」で表⽰されます。
43.
Copyright © 2018
TIS Inc. All rights reserved. 43 実装1/3 TicketSellerアクターの⽣成 1.1.[TicketSeller] アクターのファクトリーメソッドを定義 1.2.[BoxOffice ] TicketSellerアクターの⽣成 public static Props props(String event) { return Props.create(TicketSeller.class, () -> new TicketSeller(event)); } public class BoxOffice extends AbstractActor { ... private ActorRef createTicketSeller(String name) { return getContext().actorOf(TicketSeller.props(name), name); } BoxOffice TicketSeller create
44.
Copyright © 2018
TIS Inc. All rights reserved. 44 実装2/3 BoxOfficeからTicketSellerにAddメッセージを送信 1.3.[TicketSeller] メッセージプロトコルの定義 1.4.[TicketSeller] メッセージ受信時のふるまい定義 interface ITicketSeller { class Add extends AbstractMessage { private final List<Ticket> tickets; public Add(List<Ticket> tickets) { this.tickets = Collections.unmodifiableList(new ArrayList<>(tickets)); } public List<Ticket> getTickets() { return tickets; } } private final List<Ticket> tickets = new ArrayList<>(); private void add(Add add) { log.debug(msg, add); tickets.addAll(add.getTickets()); } @Override public Receive createReceive() { return receiveBuilder() .match(Add.class, this::add) .build(); } BoxOffice TicketSeller Add
45.
Copyright © 2018
TIS Inc. All rights reserved. 45 実装3/3 BoxOfficeからTicketSellerにAddメッセージを送信 1.5.[BoxOffice ] Addメッセージの送信 1.6.[BoxOffice ] EventCreatedメッセージの返信 private void createEvent(CreateEvent createEvent) { log.debug(msg, createEvent); Optional<ActorRef> child = getContext().findChild(createEvent.getName()); if (child.isPresent()) { getContext().sender().tell(new EventExists(), self()); } else { ActorRef ticketSeller = createTicketSeller(createEvent.getName()); List<TicketSeller.Ticket> newTickets = IntStream.rangeClosed(1, createEvent.getTickets()) .mapToObj(ticketId -> (new TicketSeller.Ticket(ticketId))) .collect(Collectors.toList()); ticketSeller.tell(new TicketSeller.Add(newTickets), getSelf()); getContext().sender().tell(new EventCreated(new Event(createEvent.getName(), createEvent.getTickets())), getSelf()); } } BoxOffice TicketSeller Add RestApi BoxOffice EventCreated
46.
Copyright © 2018
TIS Inc. All rights reserved. 46 Exercise1のポイント • Actorの⽣成 • メッセージの送信 • メッセージ受信時のふるまい • メッセージプロトコルの定義 getContext().actorOf(TicketSeller.props(name), name); eventTickets.tell(new TicketSeller.Add(newTickets), getSelf()); public static class Add{ private final List<Ticket> tickets; public Add(List<Ticket> tickets) { this.tickets = Collections.unmodifiableList(new ArrayList<>(tickets)); } public List<Ticket> getTickets() { return tickets; } } @Override public Receive createReceive() { return receiveBuilder() .match(Add.class, this::add) .build(); public static Props props(String event) { return Props.create(TicketSeller.class, () -> new TicketSeller(event)); }
47.
Copyright © 2018
TIS Inc. All rights reserved. Exercise 2. チケットの購入 演習2.チケットの購⼊
48.
Copyright © 2018
TIS Inc. All rights reserved. 48 チケット購⼊時のメッセージの流れ チケットを購⼊するフロー GetTicketsPOST /events/JJUG/tickets Created 201 NotFound 404 HTTP Route RestApi Actor BoxOffice Actor TicketSeller Buy Tickets
49.
Copyright © 2018
TIS Inc. All rights reserved. 49 GetTickets Buy Tickets POST /events/JJUG/tickets Created 201 NotFound 404 HTTP Route RestApi Actor BoxOffice Actor TicketSeller 実装するところ メッセージ送信(Buy/ Tickets) チケット購⼊時のメッセージの流れ:実装箇所
50.
Copyright © 2018
TIS Inc. All rights reserved. 50 実装: Buyメッセージの送信とTicketsメッセージの返信 • BoxOfficeからTicketSellerへBuyメッセージを送信 2.1.[TicketSeller] メッセージプロトコルの定義 2.2.[TicketSeller] メッセージ受信時のふるまい - 送信元へTicketsメッセージの返信 2.3.[BoxOffice ] Buyメッセージの転送 ※TicketSellerからのメッセージの返信先を⾃⾝(BoxOffice)ではなく、 RestApi(TicketSellerいメッセージを送った⼈)にしたい 2.4.[BoxOffice ] 空のTicketsメッセージを返信
51.
Copyright © 2018
TIS Inc. All rights reserved. 51 チケット購⼊の動作確認 $mvn test -Dtest=RestApiTest#testBuy ... ------------------------------------------------------- T E S T S ------------------------------------------------------- Running com.goticks.RestApiTest Slf4jLogger: Slf4jLogger started Slf4jLogger: Slf4jLogger started RestApi: ---------- POST /events/RHCP/ {"tickets":3} ---------- BoxOffice: 📩 IBoxOffice.CreateEvent[name=RHCP,tickets=3] TicketSeller: 📩 ITicketSeller.Add[tickets=[ITicketSeller.Ticket[id=1], ITicketSeller.Ticket[id=2], ITicketSeller.Ticket[id=3]]] RestApi: 📩 IBoxOffice.EventCreated[event=IBoxOffice.Event[name=RHCP,tickets=3]] RestApi: ---------- POST /events/RHCP/tickets/ {"tickets":2} ---------- BoxOffice: 📩 IBoxOffice.GetTickets[event=RHCP,tickets=2] TicketSeller: 📩 ITicketSeller.Buy[tickets=2] RestApi: 📩 ITicketSeller.Tickets[event=RHCP,entries=[ITicketSeller.Ticket[id=1], ITicketSeller.Ticket[id=2]]] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 5.577 sec Results : Tests run: 1, Failures: 0, Errors: 0, Skipped: 0 ... テストによる実⾏結果の確認 RestApiTest#testBuyの実⾏
52.
Copyright © 2018
TIS Inc. All rights reserved. 52 実装1/2 BoxOfficeからTicketSellerへBuyメッセージを送信 2.1.[TicketSeller] メッセージプロトコルの定義 2.2.[TicketSeller] メッセージ受信時のふるまい - 送信元へTicketsメッセージの返信 interface ITicketSeller { class Buy extends AbstractMessage { private final int tickets; public Buy(int tickets) { this.tickets = tickets; } public int getTickets() { return tickets; } } @Override public Receive createReceive() { return receiveBuilder() .match(Buy.class, this::buy) .build(); BoxOffice TicketSeller Buy BoxOffice Tickets private final List<Ticket> tickets = new ArrayList<>(); private void buy(Buy buy){ log.debug(msg, buy); if (tickets.size() >= buy.getTickets()) { List<Ticket> entries = tickets.subList(0, buy.getTickets()); getContext().sender().tell(new Tickets(event, entries), getSelf()); entries.clear(); } else { getContext().sender().tell(new Tickets(event), getSelf()); } }
53.
Copyright © 2018
TIS Inc. All rights reserved. 53 実装2/2 BoxOfficeからTicketSellerへBuyメッセージを送信 2.3.[BoxOffice ] Buyメッセージの転送 2.4.[BoxOffice ] 空のTicketsメッセージを返信 if (child.isPresent()) child.get().forward(new TicketSeller.Buy(getTickets.getTickets()), getContext()); else getContext().sender().tell(new TicketSeller.Tickets(getTickets.getEvent()), getSelf()); BoxOffice TicketSeller Buy BoxOffice Tickets
54.
Copyright © 2018
TIS Inc. All rights reserved. 54 Exercise2のポイント • メッセージの転送 child.get().forward(new TicketSeller.Buy(getTickets.getTickets()), getContext()); ※⾃⾝ではなく、⾃⾝へメッセージを送ってきた⼈に直接返信してほしいときは forwardを使う
55.
Copyright © 2018
TIS Inc. All rights reserved. Exercise 3. イベント一覧の取得 55 演習3.イベント⼀覧の取得
56.
Copyright © 2018
TIS Inc. All rights reserved. 56 イベント取得時のメッセージの流れ イベント⼀覧を取得するフロー GetEventGET /events/JJUG OK 200 Events HTTP Route RestApi Actor BoxOffice Actor TicketSeller empty GetEvent Event
57.
Copyright © 2018
TIS Inc. All rights reserved. 57 イベント⼀覧取得時のメッセージの流れ イベント⼀覧を取得するフロー GetEventsGET /events/ OK 200 Events HTTP Route RestApi Actor BoxOffice Actor TicketSeller GetEvent empty GetEvent Event Events
58.
Copyright © 2018
TIS Inc. All rights reserved. 58 GetEvents GetEvent Event GET /events/ OK 200 Events GetEvent empty Events HTTP Route RestApi Actor BoxOffice Actor TicketSeller イベント⼀覧取得時のメッセージの流れ:実装箇所
59.
Copyright © 2018
TIS Inc. All rights reserved. 59 実装: GetEventメッセージの送信とEventsメッセージの返信 • TicketSellerにGetEventメッセージを送信する(準備) 3.1.[TicketSeller] メッセージプロトコルの定義 3.2.[TicketSeller] メッセージ受信時のふるまい - Eventメッセージの返信 • BoxOfficeから⾃⾝にGetEventメッセージを送信 3.3.[BoxOffice ] ⾃分宛てにGetEventメッセージを送信 • BoxOfficeにGetEventメッセージ受信時のふるまいを定義 3.4.[BoxOffice ] ⼦アクターが存在する場合: - ⼦アクター(TicketSeller)へGetEventメッセージを転送 3.5.[BoxOffice ] ⼦アクターが存在しない場合: - Optional.empty()メッセージを返信 • BoxOfficeからEventsメッセージの返信 3.6.[BoxOffice ] Eventsメッセージを送信元へ返信
60.
Copyright © 2018
TIS Inc. All rights reserved. 60 テストによる実⾏結果の確認 チケット⼀覧取得の動作確認 $mvn test -Dtest=RestApiTest#testGetEvents ... ------------------------------------------------------- T E S T S ------------------------------------------------------- Running com.goticks.RestApiTest Slf4jLogger: Slf4jLogger started Slf4jLogger: Slf4jLogger started RestApi: ---------- POST /events/RHCP/ {"tickets":3} ---------- BoxOffice: 📩 IBoxOffice.CreateEvent[name=RHCP,tickets=3] TicketSeller: 📩 ITicketSeller.Add[tickets=[ITicketSeller.Ticket[id=1], ITicketSeller.Ticket[id=2], ITicketSeller.Ticket[id=3]]] RestApi: 📩 IBoxOffice.EventCreated[event=IBoxOffice.Event[name=RHCP,tickets=3]] RestApi: ---------- GET /events/ ---------- BoxOffice: 📩 IBoxOffice.GetEvents[] BoxOffice: 📩 IBoxOffice.GetEvent[name=RHCP] TicketSeller: 📩 ITicketSeller.GetEvent[] RestApi: 📩 IBoxOffice.Events[events=[IBoxOffice.Event[name=RHCP,tickets=3]]] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 5.186 sec Results : Tests run: 1, Failures: 0, Errors: 0, Skipped: 0 RestApiTest#testGetEventsの実⾏
61.
Copyright © 2018
TIS Inc. All rights reserved. 61 実装1/4 TicketSellerにGetEventメッセージを送信する(準備) 3.1.[TicketSeller] メッセージプロトコルの定義 3.2.[TicketSeller] メッセージ受信時のふるまい - Eventメッセージの返信 @Override public Receive createReceive() { return receiveBuilder() .match(GetEvent.class, this::getEvent) .build(); } class GetEvent extends AbstractMessage { } BoxOffice TicketSeller Event private void getEvent(GetEvent getEvent) { log.debug(msg, getEvent); sender().tell(Optional.of(new BoxOffice.Event(event, tickets.size())), self()); } GetEvent
62.
Copyright © 2018
TIS Inc. All rights reserved. 62 実装2/4 BoxOfficeから⾃⾝にGetEventメッセージを送信 GetEventメッセージを⾃⾝(self)に送信する 3.3.[BoxOffice ] GetEventメッセージを⾃分宛てに送信 // 子アクター(TicketSeller)に ask した結果のリストを作成 List<CompletableFuture<Optional<Event>>> children = new ArrayList<>(); getContext().getChildren().forEach(child -> children.add(ask(getSelf(), new GetEvent(child.path().name()), timeout) .thenApply(event -> (Optional<Event>) event) .toCompletableFuture())); BoxOffice GetEvent
63.
Copyright © 2018
TIS Inc. All rights reserved. 63 実装3/4 BoxOfficeにGetEventメッセージ受信時のふるまいを定義 3.4.[BoxOffice ] ⼦アクターが存在する: - ⼦アクターへGetEventメッセージを転送 3.5.[BoxOffice ] ⼦アクターが存在しない: - Optional.empty()を返信 private void getEvent(GetEvent getEvent) { log.debug(msg, getEvent); Optional<ActorRef> child = getContext().findChild(getEvent.getName()); if (child.isPresent()) child.get().forward(new TicketSeller.GetEvent(), getContext()); else getContext().sender().tell(Optional.empty(), getSelf()); } BoxOffice TicketSeller GetEvent Optional.empty()
64.
Copyright © 2018
TIS Inc. All rights reserved. 64 実装4/4 BoxOfficeからEventsメッセージを返信 pipeを使って、処理完了時にFuture内の値(Events) を送信元に返信する 3.6.[BoxOffice ] Eventsメッセージを送信元へ返信 private void getEvents(GetEvents getEvents) { // 子アクター(TicketSeller)に ask した結果のリストを作成 List<CompletableFuture<Optional<Event>>> children = new ArrayList<>(); getContext().getChildren().forEach(child -> children.add(ask(getSelf(), new GetEvent(child.path().name()), timeout) .thenApply(event -> (Optional<Event>) event) .toCompletableFuture())); // List<CompletableFuture<Optional<Event>>> の children を // CompletionStage<Events> に変換 // Events は List<Event> を持つ CompletionStage<Events> futureEvents = CompletableFuture .allOf(children.toArray(new CompletableFuture[0])) .thenApply(ignored -> { List<Event> events = children.stream() .map(CompletableFuture::join) .filter(Optional::isPresent) .map(Optional::get) .collect(Collectors.toList()); return new Events(events); }); pipe(futureEvents, getContext().dispatcher()).to(sender()); } RestApi BoxOffice Events
65.
Copyright © 2018
TIS Inc. All rights reserved. 65 Exercise3のポイント 応答が必要なメッセージ、⾃⾝へのメッセージ送信 レスポンスが必要な場合のメッセージ送信 ⾃分宛てのメッセージ送信 ask(getSelf(), new GetEvent(child.path().name()), timeout) .thenApply(event -> (Optional<Event>) event); pipe(futureEvents, getContext().dispatcher()).to(sender()); ask(getSelf(), new GetEvent(child.path().name()), timeout) ※レスポンスがほしいときはaskを使う(使いすぎ注意) ※pipeでCompletableFuture完了時結果を返す
66.
Copyright © 2018
TIS Inc. All rights reserved. Exercise 4. イベントのキャンセル 66 演習4.イベントのキャンセル
67.
Copyright © 2018
TIS Inc. All rights reserved. 67 イベントキャンセルのメッセージの流れ イベントをキャンセルするフロー CancelEvent Cancel Event DELETE /events/JJUG OK 200 NotFound 404 empty PoisonPill HTTP Route RestApi Actor BoxOffice Actor TicketSeller
68.
Copyright © 2018
TIS Inc. All rights reserved. 68 CancelEvent Cancel Event DELETE /events/JJUG empty PoisonPill HTTP Route RestApi Actor BoxOffice Actor TicketSeller イベントキャンセルのメッセージの流れ:実装箇所 実装するところ メッセージ送信(Cancel/ Event)、アクターの停⽌ OK 200 NotFound 404
69.
Copyright © 2018
TIS Inc. All rights reserved. 69 実装: Cancelメッセージの送信とTicketSellerアクターの停⽌ 演習4:Cancelメッセージの送信とTicketSellerアク ターの停⽌ BoxOfficeからTicketSellerへCancelメッセージを送信 4.1.[TicketSeller] メッセージプロトコルの定義 4.2.[TicketSeller] メッセージ受信時のふるまい Eventメッセージの返信 ⾃分宛てにPoisonPillメッセージの送信 ※毒薬を飲んで⾃殺 4.3.[BoxOffice ] ⼦アクターが存在する場合: - ⼦アクター(TicketSeller)へCancelメッセージを転送 4.4.[BoxOffice ] ⼦アクターが存在しない場合: - Optional.empty()メッセージを返信
70.
Copyright © 2018
TIS Inc. All rights reserved. 70 テストによる実⾏結果の確認 $mvn test -Dtest=RestApiTest#testCancel ... ------------------------------------------------------- T E S T S ------------------------------------------------------- Running com.goticks.RestApiTest Slf4jLogger: Slf4jLogger started Slf4jLogger: Slf4jLogger started RestApi: ---------- POST /events/RHCP/ {"tickets":3} ---------- BoxOffice: 📩 IBoxOffice.CreateEvent[name=RHCP,tickets=3] TicketSeller: 📩 ITicketSeller.Add[tickets=[ITicketSeller.Ticket[id=1], ITicketSeller.Ticket[id=2], ITicketSeller.Ticket[id=3]]] RestApi: 📩 IBoxOffice.EventCreated[event=IBoxOffice.Event[name=RHCP,tickets=3]] RestApi: ---------- DELETE /events/RHCP/ ---------- BoxOffice: 📩 IBoxOffice.CancelEvent[name=RHCP] TicketSeller: 📩 ITicketSeller.Cancel[] RestApi: 📩 Optional[IBoxOffice.Event[name=RHCP,tickets=3]] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 5.679 sec Results : Tests run: 1, Failures: 0, Errors: 0, Skipped: 0 RestApiTest#testCancelの実⾏
71.
Copyright © 2018
TIS Inc. All rights reserved. 71 実装1/2 BoxOfficeからTicketSellerへCancelメッセージの送信 4.1.[TicketSeller] メッセージプロトコルの定義 4.2.[TicketSeller] メッセージ受信時のふるまい - Eventメッセージの返信 - ⾃⾝にPoisonPillメッセージを送信する(PoisonPillを受信するとアクターは停⽌する) class Cancel extends AbstractMessage { } @Override public Receive createReceive() { return receiveBuilder() .match(Cancel.class, this::cancel) .build(); } private void cancel(Cancel cancel){ log.debug(msg, cancel); sender().tell(Optional.of(new BoxOffice.Event(event, tickets.size())), self()); self().tell(PoisonPill.getInstance(), self()); } BoxOffice TicketSeller Event Cancel PoisonPill
72.
Copyright © 2018
TIS Inc. All rights reserved. 72 実装2/2 BoxOfficeからTicketSellerへCancelメッセージの送信 4.3.[BoxOffice ] ⼦アクターが存在する場合: - ⼦アクター(TicketSeller)へCancelメッセージを転送 4.4.[BoxOffice ] ⼦アクターが存在しない場合: - Optional.empty()メッセージを返信 private void cancelEvent(CancelEvent cancelEvent) { log.debug(msg, cancelEvent); Optional<ActorRef> child = getContext().findChild(cancelEvent.getName()); if (child.isPresent()) child.get().forward(new TicketSeller.Cancel(), getContext()); else getContext().sender().tell(Optional.empty(), getSelf()); } BoxOffice TicketSeller Cancel Optional.empty()
73.
Copyright © 2018
TIS Inc. All rights reserved. 73 Exercise4のポイント 応答が必要なメッセージ、⾃⾝へのメッセージ送信 アクターはPoisonPillメッセージを受信すると停⽌する self().tell(PoisonPill.getInstance(), self()); ※PoisonPillはActorを殺すための毒薬
74.
Copyright © 2018
TIS Inc. All rights reserved. Exercise 5. APIに仕立てる(解説) 74
75.
Copyright © 2018
TIS Inc. All rights reserved. 75 APIのエンドポイント(再掲) HTTPieコマンド • イベント作成 • チケット購⼊ • イベント⼀覧取得 • イベント取得 • イベントキャンセル $http POST localhost:5000/events/JJUG/ tickets:=3 $http GET localhost:5000/events $http POST localhost:5000/events/JJUG/tickets tickets:=2 $http DELETE localhost:5000/events/JJUG/ 機能 HTTPメソッド パス JSON イベント作成 POST /events/<イベント名>/ {"tickets":<枚数>} チケット購⼊ POST /events/<イベント名>/tickets/ {"tickets":<枚数>} イベント⼀覧 GET /events/ イベント取得 GET /events/<イベント名>/ イベントキャンセル DELETE /events/<イベント名>/ $http GET localhost:5000/events/JJUG/
76.
Copyright © 2018
TIS Inc. All rights reserved. 76 エンドポイントの作成(Akka HTTP) RestAPI#createRoute import akka.http.javadsl.server.Route; public Route createRoute() { return route( pathPrefix("events", () -> route( getEvents(), pathPrefix(segment(), (String name) -> route( getEvent(name), createEvent(name), cancelEvent(name) )), pathPrefix(segment().slash(segment("tickets")), (String event) -> route( requestTickets(event) )) )) ); } • AkkaHTTPが提供するDSLを使ってHTTPリクエストの制御⽅法を定義
77.
Copyright © 2018
TIS Inc. All rights reserved. 77 RestApi#getEvents private Route getEvents() { // [Get all events] GET /events/ return get(() -> pathEndOrSingleSlash(() -> { log.debug("---------- GET /events/ ----------"); CompletionStage<Events> events = ask(boxOfficeActor, new GetEvents(), timeout) .thenApply((Events.class::cast)); return onSuccess(() -> events, maybeEvent -> { log.debug(msg, maybeEvent); return completeOK(maybeEvent, Jackson.marshaller()); }); }) ); } エンドポイントの作成(Akka HTTP)
78.
Copyright © 2018
TIS Inc. All rights reserved. 最小のAkkaアプリケーション 78 •クローンとビルドとインターフェイスのテスト •アプリケーションでのActorの探求 •クラウドへ
79.
Copyright © 2018
TIS Inc. All rights reserved. 79 クラウドへ1/2 Heroku上にアプリケーションを乗せる • Mainクラスに標準⼊⼒を待ち受けサーバーをダウンさせる実装があるため Heroku上で動かすにはこの部分を削除 $cd .. $heroku login $heroku create go-ticks Creating ⬢ go-ticks... done https://go-ticks.herokuapp.com/ | https://git.heroku.com/go-ticks.git Heroku CLIのインストール $brew install heroku System.in.read(); log.info("presses return..."); binding .thenCompose(ServerBinding::unbind) .thenAccept(unbound -> system.terminate());
80.
Copyright © 2018
TIS Inc. All rights reserved. 80 クラウドへ2/2 Herokuにソースコードをプッシュ $git subtree push --prefix chapter-up-and-running heroku master .... remote: -----> Compressing... remote: Done: 73M remote: -----> Launching... remote: Released v3 remote: https://go-ticks.herokuapp.com/ deployed to Heroku remote: remote: Verifying deploy... done. To https://git.heroku.com/go-ticks.git * [new branch] 0f4dac16e9abbdbb694502f21d314281c6affd66 -> master $ http POST go-ticks.herokuapp.com/events/JJUG tickets:=250 $ http POST go-ticks.herokuapp.com/events/JJUG/tickets tickets:=4 Heroku上のアプリケーションにアクセス ※chapter-up-and-running配下のプロジェクトをプッシュする
81.
Copyright © 2018
TIS Inc. All rights reserved. さいごに 81
82.
Copyright © 2018
TIS Inc. All rights reserved. 82 さいごに やったこと • Akkaを使って⼩さなWebサービスを構築 残された課題 • アプリケーションを再起動するとデータは消える • スケールアップもスケールアウトもしない • テストを実装していない • 1台のサーバーがダウンするとシステム全体がダウンする Akkaのエコシステムで解決できるのでぜひチャレンジしてください。 https://akka.io/docs/ Akka Actors Akka Http Akka Cluster Cluster Sharing Distributed Data Akka Persistence Alpakka
83.
Copyright © 2018
TIS Inc. All rights reserved. チャレンジのお供に 83 • メニーコア時代のパラダイム リアクティブシステムを知ろう(ThinkIT) サンプルコードはScalaで書かれ いますが、付録でJavaのAPIも 紹介しています 本⽇のサンプルアプリケーションのScala版はこちら https://github.com/akka-ja/akka-in-action/tree/master/chapter-up-and-running
84.
THANK YOU We are
hiring!! いっしょにチャレンジしませんか?
Download now