2024.10.10
将来は卵1パックの価格が2倍に? 多くの日本人が知らない世界の新潮流、「動物福祉」とは
提供: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.11.13
週3日働いて年収2,000万稼ぐ元印刷屋のおじさん 好きなことだけして楽に稼ぐ3つのパターン
2024.11.11
自分の「本質的な才能」が見つかる一番簡単な質問 他者から「すごい」と思われても意外と気づかないのが才能
2024.11.13
“退職者が出た時の会社の対応”を従業員は見ている 離職防止策の前に見つめ直したい、部下との向き合い方
2024.11.12
自分の人生にプラスに働く「イライラ」は才能 自分の強みや才能につながる“良いイライラ”を見分けるポイント
2023.03.21
民間宇宙開発で高まる「飛行機とロケットの衝突」の危機...どうやって回避する?
2024.11.11
気づいたら借金、倒産して身ぐるみを剥がされる経営者 起業に「立派な動機」を求められる恐ろしさ
2024.11.11
「退職代行」を使われた管理職の本音と葛藤 メディアで話題、利用者が右肩上がり…企業が置かれている現状とは
2024.11.18
20名の会社でGoogleの採用を真似するのはもったいない 人手不足の時代における「脱能力主義」のヒント
2024.11.12
先週まで元気だったのに、突然辞める「びっくり退職」 退職代行サービスの影響も?上司と部下の“すれ違い”が起きる原因
2024.11.14
よってたかってハイリスクのビジネスモデルに仕立て上げるステークホルダー 「社会的理由」が求められる時代の起業戦略
2024.11.13
週3日働いて年収2,000万稼ぐ元印刷屋のおじさん 好きなことだけして楽に稼ぐ3つのパターン
2024.11.11
自分の「本質的な才能」が見つかる一番簡単な質問 他者から「すごい」と思われても意外と気づかないのが才能
2024.11.13
“退職者が出た時の会社の対応”を従業員は見ている 離職防止策の前に見つめ直したい、部下との向き合い方
2024.11.12
自分の人生にプラスに働く「イライラ」は才能 自分の強みや才能につながる“良いイライラ”を見分けるポイント
2023.03.21
民間宇宙開発で高まる「飛行機とロケットの衝突」の危機...どうやって回避する?
2024.11.11
気づいたら借金、倒産して身ぐるみを剥がされる経営者 起業に「立派な動機」を求められる恐ろしさ
2024.11.11
「退職代行」を使われた管理職の本音と葛藤 メディアで話題、利用者が右肩上がり…企業が置かれている現状とは
2024.11.18
20名の会社でGoogleの採用を真似するのはもったいない 人手不足の時代における「脱能力主義」のヒント
2024.11.12
先週まで元気だったのに、突然辞める「びっくり退職」 退職代行サービスの影響も?上司と部下の“すれ違い”が起きる原因
2024.11.14
よってたかってハイリスクのビジネスモデルに仕立て上げるステークホルダー 「社会的理由」が求められる時代の起業戦略