Slide 1

Slide 1 text

0 一休.comレストランにおける Rustの活用 2024-10-31 山本浩平 @ Findy Job LT

Slide 2

Slide 2 text

1 自己紹介 ● 山本浩平 @kymmt90 ● 2023年9月入社 ● 一休.comレストランのプロダクト開発 兼 技術広報 ● Rustバックエンド開発に途中から参画 ● Rust歴は1年程度

Slide 3

Slide 3 text

2 本発表で話すこと ● 一休.comレストランのRust移行の概要 ● Rustバックエンドの技術的な詳細 ● 今後の課題や求人中のポジションにおけるチャレンジ

Slide 4

Slide 4 text

3 一休.comレストラン | サービス概要 ● 上質なレストランを対象 に、店舗や食事コースの 検索、詳細情報の閲覧、 Web予約を提供 ● 2006年ローンチの長い 歴史を持つサービス

Slide 5

Slide 5 text

4 一休.comレストラン | Rustに移行中 ● スマートフォンビューのバックエンドはRustに移行済み ○ スマートフォンからの利用が多く、後述する 高速/省リソース化が狙いの1つ ○ 検索と詳細情報取得のためのGraphQL API ○ 予約コアロジック (後述) へのリクエスト委譲

Slide 6

Slide 6 text

5 一休.comレストラン | Rustに移行中 ● デスクトップビューのバックエンドもRustに移行中 ● Solr (全文検索エンジン)のインデクサーもRustに移行中 ● Fastly ComputeでRustを用いたキャッシュロジックも 運用中 ● 本日はバックエンドの技術的詳細に絞って説明します🙏

Slide 7

Slide 7 text

6 一休.comレストラン | 移行途中の旧システム ● Python/Flask (現行デスクトップビューのバックエンド) ● C# (一部APIサーバーやSolrのインデクサー) ● 運用面の課題や技術選定方針からRust移行へ

Slide 8

Slide 8 text

7 一休.comレストラン | 移行途中の旧システム ● VBScript ○ Windows Serverで動く、予約作成、変更、キャンセル などを担うシステムで、当初からある古いコード ○ 後述する課題を抱えており、遅くとも2027年までに リプレースが必要

Slide 9

Slide 9 text

8 一休.comレストラン | 2024年現在は過渡期 ● 最終的にはRustへの移行完了を目指している ● 現状は複数の言語をまたいだ開発も ○ Rustも書く ○ プロジェクトの状況やビジネス要求に応じて Python/VBScript側を改修することもある

Slide 10

Slide 10 text

9 Rustバックエンド | 選定理由 ● 社内技術選定方針「シンプル、かつすばやく、それでいて 堅牢に作れる」を意識しつつ、以下を狙った ○ 表現力の高い型システムでドメインモデルをコード化 ○ 高速/省リソースなバックエンドサーバを実現し、 サービス運用コストを中長期的に改善

Slide 11

Slide 11 text

10 Rustバックエンド | 設計 ● オニオンアーキテクチャ ○ モデルはデータストアや 設定の詳細に非依存、 I/Fだけに依存 ○ 実際のデータストアや 設定値はサーバ起動時に 注入

Slide 12

Slide 12 text

11 Rustバックエンド | 設計 async fn fetch_restaurants( &self, database: &crate::Database, keys: &[RestaurantId], ) -> Result>> { let query = format!( // クエリ ); // レコードフェッチ、DTOからクエリモデルへ let restaurant_models = database .query_as::(&query, params) .await .context("failed to query restaurants")? .into_iter() .map(|d| (d.id, Restaurant::try_from(d))) .collect(); Ok(restaurant_models) } データアクセス層のコードのイメージ データストアや設定は外から注入 上位層→モデルの依存方向で モデルは外界に依存しない

Slide 13

Slide 13 text

12 Rustバックエンド | Cargo Workspace ● Cargoを活用して1つのリポジトリの中をモジュラーに ○ 各層(実際はもう少し細粒度)をworkspace crateで表現 ○ 各crateのCargo.tomlでcrate間の依存の向きを強制 # ルートディレクトリのCargo.toml [workspace] resolver = "2" members = [ "backend/*", ] [workspace.dependencies] backend-query-model = { path = "./backend/query-model" } # ...

Slide 14

Slide 14 text

13 Rustバックエンド | Cargo Workspace ● workspace.dependenciesで設定した特定のcrateへの 依存をCargo.tomlに明記 # データアクセス層のCargo.toml [package] name = "backend-data-access" version.workspace = true authors.workspace = true edition.workspace = true publish.workspace = true [dependencies] backend-query-model = { workspace = true }

Slide 15

Slide 15 text

14 Rustバックエンド | API ● GraphQLとREST ○ ユーザー向けフロントエンドはGraphQL ■ フロントエンドでも型生成に利用 ○ 社内の他システムとの連携用エンドポイントはREST ○ フレームワークはAxum、GraphQLはasync-graphqlを 利用

Slide 16

Slide 16 text

15 Rustバックエンド | ライブラリ ● サービスの業務に直接関連しないロジックはライブラリ として分離 ○ SQL ServerやRedis、クラウドサービスの クライアントなど

Slide 17

Slide 17 text

16 Rustバックエンド | ライブラリ ● 24時以降を表現できる時間型 のcrateもここに実装 ○ 飲食店予約業務では必要 ○ サービスに直接関係する ロジックではないので分離 /// 31:59:59 まで表現できる時刻型 #[derive(Clone, Copy, …))] pub struct Time24 { /// 00:00:00 からの経過秒数 secs: u32, } impl Time24 { ... } impl chrono::Timelike for Time24 { ... }

Slide 18

Slide 18 text

17 Rustバックエンド | デプロイ/運用 ● GitHub Actionsでイメージ作成からデプロイまで自動化 ● Google Cloud Runで運用 ○ トラフィックは最大1,000req/sほど(夕方〜夜が多い)

Slide 19

Slide 19 text

18 技術課題 | 中長期 ● 予約コアロジックの移行 ○ VBScriptは2027年ごろデフォルト無効化予定 https://techcommunity.microsoft.com/t5/windows-it-pro-blog/vbscript-deprecation-timelines-and-next-steps/ba-p/4148301

Slide 20

Slide 20 text

19 技術課題 | 中長期 ● 予約コアロジックの移行 ○ 新規予約、変更、キャンセル、割引やポイント付与を 含む既存のVBScriptからRustへの移行 ○ Rustのコードとして、どうデータモデルを表現するか から取り組むことが求められる

Slide 21

Slide 21 text

20 エンジニアを募集しています ● 本ポジションにおける技術的チャレンジ ○ レガシーと向き合いつつ、予約コアロジックなどの Rustへの移行をスムーズに進めること ○ 今後サービスを支えるRustコードベースを設計から コードまで健全な状態に保つこと ● Rust自体は未経験でも問題ありません

Slide 22

Slide 22 text

21 エンジニアを募集しています https://findy-code.io/companies/830