Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
akka-streamのマイクロサー
ビスへの適用
ナイル株式会社 開発室
佐藤 卓哉
自己紹介
佐藤 卓哉 (Nyleの佐藤の髪のない方)
年齢:30歳 独身
経歴
Java、PHP、Scalaを使うサーバーサイドエンジニア
現在まで業務システムやコンシュマー向けのWebサービ
スを開発
アジェンダ
● akka-streamについて
● マイクロサービスへの適用について
akka-streamについて
Reactive StreamのAkka実装
(ノンブロッキングでback pressureが可能な非同期ストリーム
処理の標準仕様)
http://www.reactive-streams.org/
● 基本的...
Materializer
Materialize : 実現する
Streamを実行する環境を表す。
Source
データの元を表し、データを出力、発信を行う。
インプットは持たず、ひとつのアウトプットチャンネルを持つ。
Source
Sink
「流し」、「溜める」という意味
Streamのデータの流れ着く先、Sourceの反対側でデータの受
信側。アウトプットは持たず、ひとつのインプットチャンネル
をもっている。
Sink
「流れ」の意味
インプット、アウトプットのチャンネルをひとつずつ持ち
SourceとSinkの中継を行える。データの編集やチェックなど、
色々な使い方ができる。
Flow
Flow
Source + Flow = 新しいSource
Flow + Sink = 新しいSink
Source + Flow + Sink = RunnableGraph
Flow
Source Flow
SinkFlow
Source Sink...
RunnableGraph
Akka Streamの実行トポロジー
Streamの実行トポロジーを表す概念をGraph(図)と呼ぶ。
線形、非線形、分岐のあるデータ処理は全部Graphである。
端的に言うとどういう流れで処理をするか
Back Pressure
非同期でストリームの処理を行う時にPublisher(送信)側の方が
早く動いて、Subscriber(受信)側に処理の依頼を投げすぎると
Subscriber側が溢れてしまう。
逆にPublisher側がSubsc...
Back Pressure
これらを解決する為に、Subscriberが自分が処理できる量を
Publisherに伝えることでSubscriber側を溢れさせることなく、
かつSubscriber側のリソースを無駄なく使える様にする仕組み
がb...
実装例:クローラー
Source
スクレーピングサービス
Flow
画像チェックサービス
Sink
画像移動サービス
構成
作った物
● スクレーピングして画像を落とし
● サイズをチェックして
● 一定サイズ以上の画像だけ移動
使った物
● akka-stream 2.4.8
● akka-actor 2.4.8
● scala-scraper 1.1.0
https://github.com/ruippeixotog/scala-scraper
Source スクレーピング
スライド用に抜粋
class ScrapeImpl {
val browser = JsoupBrowser()
var sequence = 1
implicit val ec: ExecutionContext...
Source スクレーピング
def download(list: List[Element]) = {
for {
e <- list
if (e.attr("src").startsWith("http://"))
} yield {
sa...
Flow 画像サイズチェック
import javax.imageio.ImageIO
import java.io.{File, IOException}
class ImageCheck {
def imageSizeCheck(file:...
Sink 画像移動
import java.io.File
import scala.sys.process._
class FileMove {
def moveImage(file: File) = {
val path = file.ge...
スライド用に抜粋
class ScrapeStream {
implicit val system = ActorSystem("HogeSystem")
implicit val materializer = ActorMaterialize...
Stream
画像チェックサービス
val step = Flow[List[File]].mapAsyncUnordered(2) { files =>
Future (
for {
file <- files
if (new ImageCh...
Source
スクレーピングサービス
Flow
画像チェックサービス
Sink
画像移動サービス
一連の実装にするのではなく、それぞれ独立したサービスとすることができる
Graph
独立 独立 独立
まとめ
● akka-streamを使うことによって、ノンブロッキングで高速
な非同期処理を手軽に実装できる。
● 複数のマイクロサービス間の連携を手軽に実現できる。
● モノリシックなサービスをマイクロサービスに分割すること
が出来る。
● ...
最後までご静聴
ありがとうございました。
Upcoming SlideShare
Loading in …5
×

akka-streamのマイクロサービスへの適用

579 views

Published on

下記イベントで使用した、発表用資料です。

【ヒカ☆ラボ】明日からはじめるマイクロサービス~サーバレスインフラ、実機テストからクローラー、レピュテーションリスクチェックまで~WEBサービス3社が実務に導入してみた

Published in: Engineering
  • Be the first to comment

  • Be the first to like this

akka-streamのマイクロサービスへの適用

  1. 1. akka-streamのマイクロサー ビスへの適用 ナイル株式会社 開発室 佐藤 卓哉
  2. 2. 自己紹介 佐藤 卓哉 (Nyleの佐藤の髪のない方) 年齢:30歳 独身 経歴 Java、PHP、Scalaを使うサーバーサイドエンジニア 現在まで業務システムやコンシュマー向けのWebサービ スを開発
  3. 3. アジェンダ ● akka-streamについて ● マイクロサービスへの適用について
  4. 4. akka-streamについて Reactive StreamのAkka実装 (ノンブロッキングでback pressureが可能な非同期ストリーム 処理の標準仕様) http://www.reactive-streams.org/ ● 基本的な概念 ● back pressure
  5. 5. Materializer Materialize : 実現する Streamを実行する環境を表す。
  6. 6. Source データの元を表し、データを出力、発信を行う。 インプットは持たず、ひとつのアウトプットチャンネルを持つ。 Source
  7. 7. Sink 「流し」、「溜める」という意味 Streamのデータの流れ着く先、Sourceの反対側でデータの受 信側。アウトプットは持たず、ひとつのインプットチャンネル をもっている。 Sink
  8. 8. 「流れ」の意味 インプット、アウトプットのチャンネルをひとつずつ持ち SourceとSinkの中継を行える。データの編集やチェックなど、 色々な使い方ができる。 Flow Flow
  9. 9. Source + Flow = 新しいSource Flow + Sink = 新しいSink Source + Flow + Sink = RunnableGraph Flow Source Flow SinkFlow Source SinkFlow
  10. 10. RunnableGraph Akka Streamの実行トポロジー Streamの実行トポロジーを表す概念をGraph(図)と呼ぶ。 線形、非線形、分岐のあるデータ処理は全部Graphである。 端的に言うとどういう流れで処理をするか
  11. 11. Back Pressure 非同期でストリームの処理を行う時にPublisher(送信)側の方が 早く動いて、Subscriber(受信)側に処理の依頼を投げすぎると Subscriber側が溢れてしまう。 逆にPublisher側がSubscriber側に遠慮して処理の依頼を投げる 抑制するとSubscriberに余裕があるのに、使えるリソースを余 らせてしまう。
  12. 12. Back Pressure これらを解決する為に、Subscriberが自分が処理できる量を Publisherに伝えることでSubscriber側を溢れさせることなく、 かつSubscriber側のリソースを無駄なく使える様にする仕組み がback pressure
  13. 13. 実装例:クローラー Source スクレーピングサービス Flow 画像チェックサービス Sink 画像移動サービス 構成 作った物 ● スクレーピングして画像を落とし ● サイズをチェックして ● 一定サイズ以上の画像だけ移動
  14. 14. 使った物 ● akka-stream 2.4.8 ● akka-actor 2.4.8 ● scala-scraper 1.1.0 https://github.com/ruippeixotog/scala-scraper
  15. 15. Source スクレーピング スライド用に抜粋 class ScrapeImpl { val browser = JsoupBrowser() var sequence = 1 implicit val ec: ExecutionContext = ExecutionContext.Implicits.global def scrape(url: String) = Future { val doc = browser.get(url) //urlのページのhtmlを取得 val images = doc >?> elementList("img") // imgタグを取得 images match { case Some(l) => download(l) case None => List.empty[File] } }
  16. 16. Source スクレーピング def download(list: List[Element]) = { for { e <- list if (e.attr("src").startsWith("http://")) } yield { save(e.attr("src")) } } def save(url: String) = { val data = Resource.fromURL(url).byteArray val file = new File(s"/Users/takuya_st/testimage/$sequence") sequence += 1 Resource.fromFile(file).write(data) file } }
  17. 17. Flow 画像サイズチェック import javax.imageio.ImageIO import java.io.{File, IOException} class ImageCheck { def imageSizeCheck(file: File) = { try { val image = ImageIO.read(file) image.getHeight() >= 100 && image.getWidth() >= 100 //100 x 100以上のサイズは転送 } catch { case e: IOException => false } } }
  18. 18. Sink 画像移動 import java.io.File import scala.sys.process._ class FileMove { def moveImage(file: File) = { val path = file.getPath() Process("mv " + path + " /Users/takuya_st/moveimage/" + file.getName).lineStream } }
  19. 19. スライド用に抜粋 class ScrapeStream { implicit val system = ActorSystem("HogeSystem") implicit val materializer = ActorMaterializer() implicit val ec: ExecutionContext = ExecutionContext.Implicits.global val targetUrls: List[String] = List ( "http://seiga.nicovideo.jp/tag/%E3%82%BB%E3%82%A4%E3%83%90%E3%83%BC", "http://seiga.nicovideo.jp/search/%E3%82%A4%E3%83%AA%E3%83%A4?target=illust" ) // 並列で実行 スクレーピングサービス val source = Source(targetUrls).mapAsyncUnordered(2) { url => new ScrapeImpl().scrape(url) } Stream
  20. 20. Stream 画像チェックサービス val step = Flow[List[File]].mapAsyncUnordered(2) { files => Future ( for { file <- files if (new ImageCheck().imageSizeCheck(file)) } yield file) } val sink = Sink.foreachParallel[List[File]](2) { files => files.map(file => new FileMove().moveImage(file)) } val graph = source via step to sink // source, flow, sink を連結して線形のGraphを作る def run(): Unit = { graph.run() //実行 } } 画像移動サービス
  21. 21. Source スクレーピングサービス Flow 画像チェックサービス Sink 画像移動サービス 一連の実装にするのではなく、それぞれ独立したサービスとすることができる Graph 独立 独立 独立
  22. 22. まとめ ● akka-streamを使うことによって、ノンブロッキングで高速 な非同期処理を手軽に実装できる。 ● 複数のマイクロサービス間の連携を手軽に実現できる。 ● モノリシックなサービスをマイクロサービスに分割すること が出来る。 ● ドメインに沿った自然な流れで実装を行うことができる。
  23. 23. 最後までご静聴 ありがとうございました。

×