読者です 読者をやめる 読者になる 読者になる

decadence

個人のメモ帳

個人開発のBot Serverメモ

今更感あるけど、LINE Trial BotFacebook Messager PlatformMicrosoft Bot Frameworkと色々ある。 個人で勝手に自分用のBotを動かしていて、現状の記録。

構成

今はこうなってる、シンプル*1

+------------+     +--------------+
| Bot Server | ==> | http gateway |
+------------+     +--------------+ ==> +-----------+
                                        | rabbit mq |
  +---------+       +-------------+ <== +-----------+
  | Bot API |  <==  | bot workers |
  +---------+       +-------------+

Bot ServerとBot APIってのは、メッセージをwebhookで投げてくれるやつと、メッセージを送信出来るAPIであればなんでもいい。

http gateway

nginxをreverse proxyに、akka-httpでリクエストを待ち受けるアプリケーションを立ててる。こいつの責務はリクエストを受けて、そもそものメッセージかどうかのvalidationなどして、message queueに投げるとこまで。mqに投げる以外のIOは無いし、そもそもmqに投げる処理もactorに渡してるから一瞬でレスポンス返してる。200でも202でもそのへん返したらいい。

もしBot Serverがwebhookじゃなくてstreamingでメッセージをくれるなら、適当にstreaming取ってくるprocessをこいつの代わりにおいたらいい。

rabbit mq

ただのmessage queue。shardっぽくユーザidやroom idに応じてqueueを適当に分けるなどしてる*2

http gatewayとrabbitmqさえ生きていたら、データは落ちない

bot workers

ここは、大きく分けて以下の3種類のworkerがいる

  1. message consumer actor
  2. worker supervisor actor
  3. worker actor (⇔ user actor)

message consumer actor

message queueの数に合わせて横に増やせる、便利。特定ユーザのメッセージは同じqueueに連なってるわけだし、対応するactorを用意するだけ。処理が遅くなってもそもそものqueueの分け方を増やしたら良いだけ*3。基本的に処理が正常に済んでからackするようにして、messageをちゃんと処理するようにする。

worker supervisor actor

次に、messageはこいつに投げられる。何をするかってこいつは特定のユーザ(user/worker actor)にメッセージを投げることが出来るやつ。誰宛のメッセージかを確認して、そいつにroutingする。

worker actor (⇔ user actor)

残りのこいつは、worker actorと言いつつ実際はuser actorで、ユーザが今どういう状態なのかってのを表すFSMとして機能してる。対話式のbotとか出来て面白い。後はこういうメッセージ飛ばしといてって投げるだけ。

状態持ってるやつのdeployってのがよく分からなくて、適当に死ぬ前に必要なのだけ保存して起動時に復旧してるけど、akka-persistenceのsnapshotだけとか使えたりもするのかな、まだやってない。journal取る程じゃない。

  • server provisioning全部ansibleに変えた
  • server process、全部systemdの管理下にした
  • mqのmessage数とかmackerelで見れて楽しい

  • 初akka
  • 無駄機能
    • この記事自体ネタです

*1:完全に無駄だけど趣味の範囲なので

*2:ただし今はユーザ数1

*3:ただし今はユーザ数1

広告を非表示にする