
2025.02.12
職員一人あたり52時間の残業削減に成功 kintone導入がもたらした富士吉田市の自治体DX“変革”ハウツー
提供: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株式会社
関連タグ:
2025.02.06
すかいらーく創業者が、社長を辞めて75歳で再起業したわけ “あえて長居させるコーヒー店”の経営に込めるこだわり
PR | 2025.02.07
プロジェクトマネージャーは「無理ゲーを攻略するプレイヤー」 仕事を任せられない管理職のためのマネジメントの秘訣
2025.02.06
落合陽一氏や松尾豊氏の研究は社会に届いているか? ひろゆき氏が語るアカデミアの課題と展望
2025.01.07
1月から始めたい「日記」を書く習慣 ビジネスパーソンにおすすめな3つの理由
2025.02.12
マネージャーは「プレイング3割」が適切 チームの業績を上げるためのマネジメントと業務の比率
2025.02.10
32歳で「すかいらーく」を創業、75歳で「高倉町珈琲」で再起業 「失敗したからすかいらーくができた」横川竟氏流の経営哲学
2025.02.10
A4用紙を持ち歩いて殴り書きでアウトプット コクヨのワークスタイルコンサルタントが語る、2種類のメモ術
2025.02.05
「納得しないと動けない部下」を変える3つのステップとは マネージャーの悩みを解消する会話のテクニック
2025.02.13
“最近の新人は報連相をしない”という、管理職の他責思考 部下に対する「NG指示」から見る、認識のズレを防ぐコツ
2025.02.07
なぜ日本企業のDXは世界の先端企業から3周遅れなのか? 『ゼロ秒思考』著者が指摘する経営者に足りない決断
着想から2か月でローンチ!爆速で新規事業を立ち上げる方法
2025.01.21 - 2025.01.21
新人の報連相スキルはマネージメントで引きあげろ!~管理職の「他責思考」を排除~
2025.01.29 - 2025.01.29
【手放すTALK LIVE#45】人と組織のポテンシャルが継承されるソース原理 ~人と組織のポテンシャルが花開く「ソース原理」とは~
2024.12.09 - 2024.12.09
『これで採用はうまくいく』著者が語る、今こそ採用担当に届けたい「口説く」力のすべて
2024.11.29 - 2024.11.29
【著者来館】『成果を上げるプレイングマネジャーは「これ」をやらない』出版記念イベント!
2025.01.10 - 2025.01.10