SlideShare ist ein Scribd-Unternehmen logo
1 von 48
Downloaden Sie, um offline zu lesen
Real World Android Akka
Who am I?
麻植泰輔 / Taisuke Oe
Twitter: @OE_uia
GitHub: taisukeoe
会社
- BONX INC. でAndroidアプリ書いたりスノー
ボードするお仕事
- ScalaMatsuri座長 / Japan Scala
Association, Inc.常務理事
個人
- Scalaを教える仕事しています
スポンサー募集
CFP
スタッフ募集
OPEN!!
What’s the topic?
本日のお話
本日のお話
Android
+
Scala
+
Akka
⇓
VoIPクライアント
本日のお話
◉ Akka
○ メッセージ駆動
○ Actorの実行モデル
○ Actorのヒエラルキー
◉ BONX
○ BONXとは?
○ BONX VoIPクライアントの要求仕様
◉ Android Akkaの注意点
○ Dispatcher, Mailboxの実装など
◉ Scala Androidってどうなの?
Akka?
Akka
◉ メッセージ駆動で並行/分散処理するtoolkit
◉ Lightbend CTO Jonas Bonér氏が作者
◉ 名前の由来はスイスの先住民の神様
◉ スイスのLaponiaという山がAkka神のシンボル
Message Driven?
メッセージ駆動?
メッセージ駆動
Actorがメッセージを送り合い協調動作することで、システムを構成
あとはたのむ
メッセージ駆動
あとはたのむ
次に手が空いてから
やるわ
Actorが受け取ったメッセージは、そのActorに紐付いたMailboxに入る
メッセージ駆動
あとはたのむ
次に手が空いてから
やるわ
Actorはメッセージ一つ一つを逐次処理する
=> (特にスレッドセーフではない)状態管理を伴う並行プログラミングに有用
メッセージ駆動
あとはたのむ 今からやるお
Actorは他のActorについては、メッセージの送信先と受け取れるメッセージ
の種類についてのみ知っておけばよいため、Actor同士を疎結合にしやす
い
Akka Dispatcher
Actorの実行モデル
Actorの実行モデル
Thread
Thread
Dispatcher
DispatcherがActorの実行基盤。内部にThreadPoolを保持。
Actorの実行モデル
Thread
Thread
Dispatcher
1つのActorは、同時に一つのスレッドにだけ割り振られる
Actorの実行モデル
Thread
Thread
Dispatcher
Threadが空いたら、次のActorが割り振られる
Actorの実行モデル
Dispatcher
Actorは、Mailboxにメッセージが有り、なおかつThreadが割り
当てられてるときにメッセージを処理する
Actorプログラミングのアンチパターン
Thread
Thread
Dispatcher
Actorが長時間Threadをブロックすると、同じdispatcherを使用
しているActorシステム全体の処理が進みにくくなる
進捗ダメです
Akka Actor Hierarchy
Actorのヒエラルキー
Actorの階層構造
Dispatcher
Actorには親子関係が作れる
ワシが育てた
Actorの階層構造
Dispatcher
子ActorでThrowableが投げられると、親Actorの
supervisorStrategy関数が呼ばれる
_人人人人人人人人人_
> 突然のThrowable <
 ̄Y^Y^Y^Y^Y^Y^Y^Y ̄
Actorの階層構造
Dispatcher
supervisorStrategyの実装により、その後の子Actorの処遇が
決定される
Restart
Akkaについて - まとめ
◉ Actorがメッセージを送り合うことでシステムを構成
◉ 1つのActorは同時に1メッセージを1スレッドで逐次処
理するため、状態管理が楽
◉ 実行モデル
○ Dispatcher … Thread(pool)の保持と、ActorへのThread貸
出
○ Mailbox … Actorに送られたメッセージ置き場
◉ ActorのヒエラルキーとSupervisorStrategyの実装を
適切に設定することで、障害からの回復力をもつ
The Way We Talk
BONX
BONXとは?
野外の激しい運動中でも
複数の仲間とスムーズに
コミュニケーションとれるVoIPサービス
VoIP = Voice over Internet Protocol
Requirement specification in BONX VoIP client
BONX VoIPクライアントの要求仕様
BONX VoIPクライアントの要求仕様
◉ 状態管理を伴う並行プログラミング
◉ (それなりに)低遅延
◉ 障害からの回復力
VoIPは音声ストリーム処理
ソケット通信録音 音量調整 発話検知 エンコード
デコード再生
音声ストリーム処理: 並行プログラミング
◉ 1フレームの処理が終わる前に、次のフレームの音声デー
タが送られてくる
◉ 必然的に並行プログラミングすることになる
◉ しかしエンコーダー・デコーダーなどのモジュールは、多く
の場合Threadセーフではない
Actorモデル向き
低遅延
◉ 合計の遅延:大きくなりすぎると、(特に顔が見えていると
き)通話中に違和感
◉ 個々の遅延:フレーム間の遅延が大きくなりすぎると、「ブ
ツッ」という音の途切れの原因
Dispatcher, Mailboxのカスタマイズ性は必要十分
障害からの回復力
◉ クライアントアプリとしては長時間(~8時間)の連続使用を想
定
◉ 使用中、録音/再生のハードウェア I/Oなど一部のモ
ジュールに問題が発生するケースがある
◉ 何かの状態がおかしい場合は、関連するモジュール含め
て、自動で再初期化が必要
AkkaのActorヒエラルキーを適切に設定しておくと、モジュール
群を自動で再初期化することで障害から回復できる
Pitfalls in Android Akka
Android Akkaの注意点
Android Akkaの注意点
◉ Akka version
◉ Proguard設定
◉ Dispatcherの罠
◉ Mailboxのサイズ
Akka version
◉ AndroidはJava6/7相当の環境
◉ Akka 2.14系はJava8要求
=> Akka 2.13系を使う
Proguard
● Akkaはapplication.confやPropsを基に、リフレクションで
Actorなどをインスタンス化
● Proguardは使用されていないクラス、メソッドをバイトコード
から抜くpost-processingツール
● Proguardはリフレクションを理解しない
● Android ScalaにおけるNoSuchMethodErrorの発生原因
の殆どはProguard起因
=> proguard.cfgに随時指定
参考: Macroid | Akka Integration
Dispatcherの罠
application.confのparallerism-factorは、(min~maxの範囲
で)availableProcessorsに乗じた数のThreadPoolを作る
akka.dispatch.ThreadPoolConfig
object ThreadPoolConfig {
/* … */
def scaledPoolSize(floor: Int, multiplier: Double, ceiling: Int): Int =
math.min(math.max((Runtime.getRuntime.availableProcessors * multiplier).ceil.toInt, floor), ceiling)
/* … */
}
AndroidのavailableProcessors
Androidの場合、電力消費を抑えるため、高クロックと低クロックのコア
から構成されているヘテロCPUが主流。そのため、一度に全てのCPUコ
アがonlineにならない端末が多い。
しかしRuntime#availableProcessorsは常に全合計コア数を返す。この
数字をそのまま使うと、Thread数がコア数に対して多くなりすぎてパ
フォーマンスが低下することがある
/sys/devices/system/cpu/online では 1-5,6 のようにオンライン状態の
CPUのindexをチェックできる (参考:Linux kernel related to hotplug a
CPU)
カスタムDispatcher
akka.dispatcher.ExecutorServiceConfiguratorを継承
したクラスのFQCN(フル修飾名)をapplication.confに指定
可能
my-dispatcher {
type = Dispatcher
executor = "com.taisukeoe.MyExecutorConfigurator"
fork-join-executor {
parallerism-min = 8
parallerism-factor = 2
parallerism-max = 16
}
}
カスタム
ExecutorServiceConfigurator
class MyExecutorConfigurator(config: Config, prerequisites: DispatcherPrerequisites) extends
ExecutorServiceConfigurator(config, prerequisites) {
final def createExecutorServiceFactory(id: String, threadFactory: ThreadFactory): ExecutorServiceFactory = {
val c = config.getConfig("fork-join-executor")
new ForkJoinExecutorServiceFactory(
threadFactory.asInstanceOf[ForkJoinPool.ForkJoinWorkerThreadFactory],
CPUConfig.scaledPoolSize(
c.getInt("parallelism-min"),
c.getDouble("parallelism-factor"),
c.getInt("parallelism-max")),
true)
}
}
OnlineのCPUコア数を取得
object CPUConfig {
private lazy val rangeRegex = "([0-9]+)-([0-9]+)".r
def onlineProcessors: Option[Int] = Try {
val reader = new BufferedReader(new FileReader("/sys/devices/system/cpu/online"))
val num = Iterator.continually(reader.readLine()).takeWhile(_ != null).toSeq.headOption map { cpu:String =>
cpu.split(",").map {
case rangeRegex(from, to) => to.toInt - from.toInt + 1
case num => 1
}.sum
reader.close()
num
}}.toOption.flatten
def scaledPoolSize(floor: Int, multiplier: Double, ceiling: Int): Int =
math.min(math.max(onlineProcessors.getOrElse(Runtime.getRuntime.availableProcessors) * multiplier).ceil.toInt,
floor), ceiling)
}
Mailboxのサイズ
◉ Androidは(増えてきたとはいえ)基本的には低メモリ環境
◉ 1 VM ~ 数百MB RAM
◉ サイズ制限のないMessageBoxだとOutOfMemoryErrorのおそれ
◉ できるだけ有限サイズのMailbox (BoundedMailbox) を使う方が
良い
◉ それで必要要件をみたさないときは、カスタムMailboxを作るべき
参考: Mailboxes -- Akka
my-mailbox {
mailbox-type = "com.taisukeoe.MyMailBox"
}
Android Scala Pros & Cons
ScalaでAndroidってどうなの?
ScalaでAndroidってどうなの?
◉ ScalaとAndroid両方に詳しい人がチームに1人いたら選択肢として
アリ。チーム2人目以降は、どちらかについて詳しければ、教育可能
◉ sbt-androidが(クセはあるけど)とても優秀。組み合わせると便利な
sbt pluginも色々
◉ 今回のケースではScala + Akka + Androidのメリットが存分に活き
た
○ 常時1~2人分の工数の少人数チームで新規機能開発&メンテ
○ 必要な低遅延/スループットなどのパフォーマンスを達成しつ
つ、モジュールの疎結合化、コードの抽象化に(それなりに)成
ScalaでAndroidってどうなの?
◉ 万人にオススメはしない
◉ ScalaとAndroid両方の知識がそれなりに必要
◉ ビルドが長い (Proguardのせい)
◉ Googleのサポート外
○ Scala2.12 & Java8対応?
■ Jack & JillがJava8対象
○ Jack & Jill対応?
■ sbt-androidにPullReqは一応....
まとめ
◉ Akkaはメッセージ駆動で並行/分散処理を便利に行える
toolkit
◉ Androidでも幾つかのポイントに注意すれば、Akkaは十分
実用的である。
◉ VoIPアプリの音声ストリーム処理など、AndroidでもActor
モデルが非常に有用となるケースがある
We’re hiring!
◉ VoIPクライアントアプリに興味がある人
◉ Android Scalaを触ってみたい人
◉ Akkaのチューニングをゴリゴリしたい人
◉ スノボ、サイクリング 等々が好きな人
お気軽に @OE_uia までメッセください

Weitere ähnliche Inhalte

Was ist angesagt?

ScalaでAndroidアプリ開発
ScalaでAndroidアプリ開発ScalaでAndroidアプリ開発
ScalaでAndroidアプリ開発
papamitra
 

Was ist angesagt? (20)

Akkaの翻訳みんなでやろう Let's translate akka doc
Akkaの翻訳みんなでやろう Let's translate akka docAkkaの翻訳みんなでやろう Let's translate akka doc
Akkaの翻訳みんなでやろう Let's translate akka doc
 
Akka meetup 2014_sep
Akka meetup 2014_sepAkka meetup 2014_sep
Akka meetup 2014_sep
 
Akka-Streams in Production
Akka-Streams in ProductionAkka-Streams in Production
Akka-Streams in Production
 
ScalaでAndroidアプリ開発
ScalaでAndroidアプリ開発ScalaでAndroidアプリ開発
ScalaでAndroidアプリ開発
 
インターンシップの学生にお届けしようとしたScalaの文法(初級編)
インターンシップの学生にお届けしようとしたScalaの文法(初級編)インターンシップの学生にお届けしようとしたScalaの文法(初級編)
インターンシップの学生にお届けしようとしたScalaの文法(初級編)
 
akka-doc-ja
akka-doc-jaakka-doc-ja
akka-doc-ja
 
Akkaとは。アクターモデル とは。
Akkaとは。アクターモデル とは。Akkaとは。アクターモデル とは。
Akkaとは。アクターモデル とは。
 
【LT】akka receive とScala Javaの違い
【LT】akka receive とScala Javaの違い 【LT】akka receive とScala Javaの違い
【LT】akka receive とScala Javaの違い
 
実践Akka
実践Akka実践Akka
実践Akka
 
ScalaにまつわるNewsな話
ScalaにまつわるNewsな話ScalaにまつわるNewsな話
ScalaにまつわるNewsな話
 
Akka stream
Akka streamAkka stream
Akka stream
 
AndroidでScalaを使う際の問題点と対策
AndroidでScalaを使う際の問題点と対策AndroidでScalaを使う際の問題点と対策
AndroidでScalaを使う際の問題点と対策
 
Servlet と Future の関わり方 #scala_ks
Servlet と Future の関わり方 #scala_ksServlet と Future の関わり方 #scala_ks
Servlet と Future の関わり方 #scala_ks
 
Developing an Akka Edge6
Developing an Akka Edge6Developing an Akka Edge6
Developing an Akka Edge6
 
20140518 JJUG MySQL Clsuter as NoSQL
20140518 JJUG MySQL Clsuter as NoSQL20140518 JJUG MySQL Clsuter as NoSQL
20140518 JJUG MySQL Clsuter as NoSQL
 
沢山のスマホサービス環境を カジュアルにセキュアに運用する
沢山のスマホサービス環境を カジュアルにセキュアに運用する沢山のスマホサービス環境を カジュアルにセキュアに運用する
沢山のスマホサービス環境を カジュアルにセキュアに運用する
 
アドテク×Scala×パフォーマンスチューニング
アドテク×Scala×パフォーマンスチューニングアドテク×Scala×パフォーマンスチューニング
アドテク×Scala×パフォーマンスチューニング
 
コンテナで作れるFaaS
コンテナで作れるFaaSコンテナで作れるFaaS
コンテナで作れるFaaS
 
ネットワーク自動化、なに使う? ~自動化ツール紹介~(2017/08/18追加開催)
ネットワーク自動化、なに使う? ~自動化ツール紹介~(2017/08/18追加開催) ネットワーク自動化、なに使う? ~自動化ツール紹介~(2017/08/18追加開催)
ネットワーク自動化、なに使う? ~自動化ツール紹介~(2017/08/18追加開催)
 
JOSUG2014 OpenStack 4th birthday party in Japan; the way of OpenStack API Dragon
JOSUG2014 OpenStack 4th birthday party in Japan; the way of OpenStack API DragonJOSUG2014 OpenStack 4th birthday party in Japan; the way of OpenStack API Dragon
JOSUG2014 OpenStack 4th birthday party in Japan; the way of OpenStack API Dragon
 

Ähnlich wie Real world android akka

20150101勉強会 dokku alt
20150101勉強会 dokku alt20150101勉強会 dokku alt
20150101勉強会 dokku alt
Shugo Numano
 
試して学べるクラウド技術! OpenShift
試して学べるクラウド技術! OpenShift試して学べるクラウド技術! OpenShift
試して学べるクラウド技術! OpenShift
Etsuji Nakai
 

Ähnlich wie Real world android akka (20)

Spark Streaming Snippets
Spark Streaming SnippetsSpark Streaming Snippets
Spark Streaming Snippets
 
Next2Dで始めるゲーム開発 - Game Development Starting with Next2D
Next2Dで始めるゲーム開発  - Game Development Starting with Next2DNext2Dで始めるゲーム開発  - Game Development Starting with Next2D
Next2Dで始めるゲーム開発 - Game Development Starting with Next2D
 
AKS と ACI を組み合わせて使ってみた
AKS と ACI を組み合わせて使ってみたAKS と ACI を組み合わせて使ってみた
AKS と ACI を組み合わせて使ってみた
 
Firefox Add-on SDK 入門
Firefox Add-on SDK 入門Firefox Add-on SDK 入門
Firefox Add-on SDK 入門
 
Wasm blazor and wasi 2
Wasm blazor and wasi 2Wasm blazor and wasi 2
Wasm blazor and wasi 2
 
Elixir入門「第3回:Phoenix 1.2で高速Webアプリ & REST APIをサクッと書いてみる」【旧版】※新版あります
Elixir入門「第3回:Phoenix 1.2で高速Webアプリ & REST APIをサクッと書いてみる」【旧版】※新版ありますElixir入門「第3回:Phoenix 1.2で高速Webアプリ & REST APIをサクッと書いてみる」【旧版】※新版あります
Elixir入門「第3回:Phoenix 1.2で高速Webアプリ & REST APIをサクッと書いてみる」【旧版】※新版あります
 
2019年度 CaaS ワークショップ @ NTTコム
2019年度 CaaS ワークショップ @ NTTコム2019年度 CaaS ワークショップ @ NTTコム
2019年度 CaaS ワークショップ @ NTTコム
 
20150101勉強会 dokku alt
20150101勉強会 dokku alt20150101勉強会 dokku alt
20150101勉強会 dokku alt
 
Dockerセキュリティ: 今すぐ役に立つテクニックから,次世代技術まで
 Dockerセキュリティ: 今すぐ役に立つテクニックから,次世代技術まで Dockerセキュリティ: 今すぐ役に立つテクニックから,次世代技術まで
Dockerセキュリティ: 今すぐ役に立つテクニックから,次世代技術まで
 
Node.jsアプリの開発をモダン化するために取り組んできたこと
Node.jsアプリの開発をモダン化するために取り組んできたことNode.jsアプリの開発をモダン化するために取り組んできたこと
Node.jsアプリの開発をモダン化するために取り組んできたこと
 
Elixir入門「第3回:Phoenix 1.3で高速webアプリ & REST APIアプリをサクッと書いてみる」
Elixir入門「第3回:Phoenix 1.3で高速webアプリ & REST APIアプリをサクッと書いてみる」Elixir入門「第3回:Phoenix 1.3で高速webアプリ & REST APIアプリをサクッと書いてみる」
Elixir入門「第3回:Phoenix 1.3で高速webアプリ & REST APIアプリをサクッと書いてみる」
 
OpenStack API
OpenStack APIOpenStack API
OpenStack API
 
Open Source x AI
Open Source x AIOpen Source x AI
Open Source x AI
 
Osc fukuoka xAI Meetup
Osc fukuoka xAI MeetupOsc fukuoka xAI Meetup
Osc fukuoka xAI Meetup
 
本気で使うStack storm
本気で使うStack storm本気で使うStack storm
本気で使うStack storm
 
Tekton 入門
Tekton 入門Tekton 入門
Tekton 入門
 
Dockerクイックツアー
DockerクイックツアーDockerクイックツアー
Dockerクイックツアー
 
試して学べるクラウド技術! OpenShift
試して学べるクラウド技術! OpenShift試して学べるクラウド技術! OpenShift
試して学べるクラウド技術! OpenShift
 
分散環境におけるDocker とオーケストレーション
分散環境におけるDocker とオーケストレーション分散環境におけるDocker とオーケストレーション
分散環境におけるDocker とオーケストレーション
 
Step-Oriented Programming による任意コード実行の可能性
Step-Oriented Programming による任意コード実行の可能性Step-Oriented Programming による任意コード実行の可能性
Step-Oriented Programming による任意コード実行の可能性
 

Mehr von Taisuke Oe

How to start functional programming (in Scala): Day1
How to start functional programming (in Scala): Day1How to start functional programming (in Scala): Day1
How to start functional programming (in Scala): Day1
Taisuke Oe
 

Mehr von Taisuke Oe (10)

プレScalaMatsuri2019「スピーカー入門」
プレScalaMatsuri2019「スピーカー入門」プレScalaMatsuri2019「スピーカー入門」
プレScalaMatsuri2019「スピーカー入門」
 
How to start functional programming (in Scala): Day1
How to start functional programming (in Scala): Day1How to start functional programming (in Scala): Day1
How to start functional programming (in Scala): Day1
 
Monix Taskが便利だという話
Monix Taskが便利だという話Monix Taskが便利だという話
Monix Taskが便利だという話
 
How to get along with implicits
How to get along with implicits How to get along with implicits
How to get along with implicits
 
What Dotty fixes @ Scala関西サミット
What Dotty fixes @ Scala関西サミットWhat Dotty fixes @ Scala関西サミット
What Dotty fixes @ Scala関西サミット
 
AuxパターンをDottyで解決する
AuxパターンをDottyで解決するAuxパターンをDottyで解決する
AuxパターンをDottyで解決する
 
Real World Android Akka
Real World Android AkkaReal World Android Akka
Real World Android Akka
 
多相な関数の定義から学ぶ、型クラスデザインパターン
多相な関数の定義から学ぶ、型クラスデザインパターン多相な関数の定義から学ぶ、型クラスデザインパターン
多相な関数の定義から学ぶ、型クラスデザインパターン
 
Android BLEのつらみを予防するTips
Android BLEのつらみを予防するTipsAndroid BLEのつらみを予防するTips
Android BLEのつらみを予防するTips
 
BONXを支える技術:Bluetooth編 ~Bluetoothを120%使い倒す方法~
BONXを支える技術:Bluetooth編 ~Bluetoothを120%使い倒す方法~BONXを支える技術:Bluetooth編 ~Bluetoothを120%使い倒す方法~
BONXを支える技術:Bluetooth編 ~Bluetoothを120%使い倒す方法~
 

Real world android akka