2024.12.24
「経営陣が見たい数字」が見えない状況からの脱却法 経営課題を解決に導く、オファリングサービスの特長
提供:LINE株式会社
リンクをコピー
記事をブックマーク
川田裕貴氏:今日は、LINE Messaging APIの中のServer Side Kotlinについてお話をしようと思います。まず、自己紹介をします。私は川田裕貴と言います。LINEに初めて関わったのは2014年の開発インターンシップからなのでけっこう長いのですが、新卒入社で入社しました。
Kotlinに関わり始めたのは2018年くらいからです。「LINE Things」というプロジェクトに参加した時にKotlinを初めて書いて、その年にオランダで行われた「KotlinConf」に参加しました。2019年からは、Messaging APIのサーバーサイド開発をしています。
1日20億以上のメッセージを送信するシステムですが、どんなふうにMessaging APIが動いていて、どんなふうにKotlinが使われているのか、中身の紹介をしたいと思います。
LINE Messaging APIを使ったことがある方も多いと思いますが、今日は知らない人もいると思うので一応紹介すると、LINEのBotを作るAPIやプラットフォームのことです。
LINEアプリは、ユーザー同士でコミュニケーションするという機能もありますが、LINE公式アカウントと言われているアカウントがたくさんあって、LINE NEWS、LINEの通訳Bot、お天気のBotなど、いろいろなものが提供されています。これらのLINE公式アカウントを作るためのAPIが、LINE Messaging APIです。
LINE Messaging APIには、メッセージをブロードキャストしたり、プッシュやリプライと言われている個別にメッセージを配信するAPIだったり、ユーザーからメッセージを受け取るためにBotに対してWebhookを送信していたり、さまざまな機能があります。
また、LINE公式アカウントの画面を開くと出てくる「リッチメニュー」や、どういうユーザーがこのメッセージを受け取ってアクションしたのか判別する機能や、ユーザーのメッセージ送信数を集計する機能など、すべてをまとめてMessaging APIとして提供しています。
どういうことをやっているのかを、簡単な図で説明したいと思います。LINEユーザーは、直接Messaging APIを使っていませんし、Botと会話しているわけでもありません。LINEユーザーは、talk-serverと言われる大きなLINEを司るコンポーネントに対して通信を行なっています。
ただしMessaging APIは、talk-serverのプロトコルとはまったく異なるAPIで通信しています。そこの橋渡し役が私たちのチームで開発しているMessaging APIのバックエンドサーバーです。
Messaging APIはAPIを直接使っているChatbotだけが利用しているわけではありません。LINE公式アカウントのWebから操作できる管理画面や、外部の会社で提供している「LINE WORKS」というアカウントもLINEの中で1つのBotとして動いています。
このような機能も、すべて私たちのMessaging APIのバックエンドを使っていて、実際のLINEユーザーはtalk-serverを経由してコミュニケーションしています。中身はたくさんのキューがあって、たくさんのマイクロサービスコンポーネントが集まっているシステムです。
実際にどういうところでKotlinが使われているのか。LINE Messaging APIには、ユーザーからBot側と、Botからユーザー側と、大きく2つの経路があります。まずはユーザーからBotへメッセージを送信した場合のフローを見ていこうと思います。
Webhook送信側のサーバー構成は、2020年から2021年に大幅に構成を刷新しています。刷新をする際にKotlinを積極的に採用したので、多くのコンポーネントがKotlinで動いています。
昔はtalk-serverの中で、実際にBotを1つのユーザーとして一般のLINEユーザーがAPIを呼んで、メッセージをフェッチしてWebhookを送信していたのですが、今はtalk-serverからLINEが処理するイベントをすべて受け取って、その中からBotに関するイベントを抽出して、そのイベントを処理しながらWebhookとして送信しています。
イベントは本当に多く、秒間で100万以上あります。LINEで取り扱うすべてのイベントを受け取り、大量のイベントの中からBotに関するイベントだけをフィルターするコンポーネントが最初にあります。
(スライドを示して)ここはJavaで、その先はすべてKafkaのキューを挟んでKotlinのシステムになっています。なのでみなさんがMessaging APIのWebhookを受け取る時に送出しているサーバーはすべてKotlinで書かれています。
中身はReactorやCoroutinesを使って非同期化もされていて、REST APIやApache Thriftなど、いろいろなAPIを使ってマイクロサービス化されて動いています。こちら側はかなりKotlinが使われています。
逆にメッセージ配信側はKotlinが使われているところが少なく、JavaやScalaで書かれています。これには歴史的な事情もあります。LINE公式アカウントは10年近く動いているサービスなので、かなり初期からあるコンポーネントも多く、JavaやScalaで書かれています。
api.line.meというドメインを叩くとつながるAPI Gatewayは、すべてJavaで書かれていますし、その先のメッセージ送信サーバーには、コンポーネントがさまざまあって、ブロードキャスト用のサーバーやナローキャスト用のサーバーなどありますが、JavaやScalaで書かれています。その先にRabbitMQがあって、配信処理サーバーはほぼScalaで書かれていて、talk-serverへ送信しています。
ただ、それらがそれぞれ使うマイクロサービスコンポーネントは、一部Kotlinで書かれていたりします。あとで説明しますが、これらのサーバーの中で使っているコモンモジュールみたいなものは、最近Kotlinで書かれるようになってきました。
今まさにこのメッセージ配信側の、Kotlinへの移行を計画中です。最近、LINEのコンポーネントはKafkaへどんどん移行しているので、JavaやScalaで書かれたコンポーネント、RabbitMQを使っている部分はKafkaや、Reactorや、Kotlinを使っていこうと計画をしています。
古いコンポーネントもJavaで書かれていますが、私たちはMonorepoという方式を採用しています。マイクロサービスはいっぱいありますが、実際のリポジトリは1つに統合されています。
サーバー、サービスのコードがたくさんありますが、それぞれの中で共通の部分が出てきます。私たちはGradleでリポジトリを全部管理していて、Gradleの中のモジュールがそれぞれマルチモジュールになっていて、:commonsというモジュールの下にKafka、Redis、Cacheなどのモジュールが合わさっています。
Webhook側の刷新の時に、共通モジュールを書き直したり追加したりしたので、この部分に関してはかなりの割合でKotlinが使われています。
Javaで書かれているコンポーネントからも新しく書いた:commonsモジュールが使いやすく、なにかの理由でちょっと書き換えなきゃいけない時にこちらのモジュールで書き換えているので、表面上はJavaで動いていても中身のモジュールはKotlinで書かれているというものもかなり多いです。なのでもうKotlinなしでは生きていけないシステムになっています(笑)。
私たちのチームの特徴として、Java、Kotlin、Scala、それぞれ使っているのですが、私はKotlinがちょうどいいと思っています。JavaはJava 9以降進化していていろいろ増えてきてはいますが、まだ言語の機能が追いついていません。
Scalaは、やはり機能が強力でFunctional Programingをやりたい方はとても使い心地がいいと思いますが、若干読みづらく、例えば先ほどのKotlinのコモンモジュールみたいなものをScalaで書いてしまった場合、Javaから呼ぶとどうしてもScala特有の型やオプションが特殊な扱いになってしまいます。
このあたりのやりとりが難しく、その点Kotlinだとほとんど気にならずに使えるので、Javaから置き換えていくにもちょうどいいです。学習コストという面でも、Scalaほどパラダイムが変わらないのかなという点で、ちょうどいい言語だと私たちは思っています。
Kotlinというと、みなさんCoroutinesを使うと思いますが、私たちのチームではあえてCoroutinesを使わずに、非同期化しているところもあります。主にReactorを使ってReactive Streamsで書いています。
Coroutinesはいいのですが、私たちのシステムはキューを使ってたくさんのオペレーションをフィルターしたりflatMapしたり、さらにもっと大きな非同期オペレーションを高速で呼んだりというのを繰り返すので、どうしてもCoroutinesのAsynchronous Flowみたいな機能が必要になってきます。
ReactorもRxJavaも使ったことがありますが、それに比べるとCoroutinesのFlowのOperatorが貧弱かなと思っています。そういう処理をするとどうしても冗長になってしまったり、きれいに書けないことがあったりして、やはりこういう処理にはReactorのほうが向いているのかなと思っています。
また、ReactorはSpringのサポートも手厚いので、Reactive Streamsの学習コストさえ乗り越えられるのであれば、Coroutinesを無理やり使わなくてもいいのかなと思うところがあり、Reactorを採用しています。
Messaging APIの中でKotlinを使ってみての書き心地ですが、Javaを使っているとほぼ困るところがないのがいいところかなと思っています。Nullableやsmart castなど便利な機能が取り入れられているので、かゆいところに手が届きます。
また、Scalaよりもはるかに良いJavaとの親和性があります。拡張関数など、今まではきれいに書けなかったコードもきれいに書けるようになるのがKotlinのいいところです。
ただ、チームの中にはScala派閥の方もいます(笑)。そういう方からすると、やはりKotlinでも機能が足りず、パターンマッチングが弱いだとか、Scalaのforみたいなフラットマップが言語としてサポートしてほしいだとか、そういう意見がよく出てきます。
また、最近KotlinのExperimentalな機能はけっこう変わっていて、実験的に全部書き直さなければいけません。特にExperimental timeあたりのメソッドがdeprecatedになっていたりしてすごく気になります。
Javaから移行するとどうしてもコンパイルに時間がかかったり、IDEもちょっと重いのが気になる点かなと思いますが、これ以上にKotlinのメリットは多いと今のところ私は思っています。
(次回へつづく)
LINE株式会社
関連タグ:
2024.12.20
日本の約10倍がん患者が殺到し、病院はキャパオーバー ジャパンハートが描く医療の未来と、カンボジアに新病院を作る理由
2024.12.24
なぜ「場当たり的」なタスク処理になるのか? マッキンゼー流、「優先順位づけ」のポイント
2024.12.19
12万通りの「資格の組み合わせ」の中で厳選された60の項目 532の資格を持つ林雄次氏の新刊『資格のかけ算』の見所
PR | 2024.12.20
モンスター化したExcelが、ある日突然崩壊 昭和のガス工事会社を生まれ変わらせた、起死回生のノーコード活用術
2024.12.23
DMM亀山会長が語る、事業撤退の見極め 600もの事業に挑戦した中でロジックよりも大事にしていたこと
2023.03.21
民間宇宙開発で高まる「飛行機とロケットの衝突」の危機...どうやって回避する?
2024.12.20
「資格のかけ算」で切り開くキャリア戦略 4パターンの資格の組み合わせで自分の強みを最大化するヒント
2024.12.24
生成AIを“業務のために使う”より、もっと効率のいい方法 深津貴之氏が語る、AIのビジネス活用法
2024.12.18
「社長以外みんな儲かる給与設計」にした理由 経営者たちが語る、優秀な人材集め・会社を発展させるためのヒント
2024.12.25
今300万円の貯金を1年後に450万円に増やすには? マッキンゼー流、目標額との差額を埋めるための考え方