29 ポイント 投稿者 leelou2 2025-01-06 | 17件のコメント | WhatsAppで共有

URL Shortener プロジェクトを作って改善し、また作って改善し……を繰り返し、ついに最終版の v9 オープンソースプロジェクトを作ることができました。

🚀 Github : https://github.com/lee-lou2/rust-url-shortener


プロジェクトを準備するにあたり、以下の要件は必ず守るよう努めました。

要件

  1. Short URL は非常に高速に生成されなければならない
  • データが増えても遅くなってはならない
  • いつ、どのような状況で、どのようなデータを使ってリクエストしても速くなければならない
  1. Short URL から Original URL へリダイレクトする際も高速でなければならない
  • これは実際のところ当然の話ですが… 😅
  1. さまざまなユーザーを満足させられる付加機能が含まれていなければならない
  • 必要に応じてプラットフォームごとに異なる URL へ遷移できなければならない
  • 必要に応じてユーザーが生成した URL への流入データを確認できなければならない

これらの要件を満たすため、以下のように開発しました。

反映事項

Q. Short Key の生成を、データ量に関係なく高速に行うには?
A.
一般的に Short Key を生成する方法はいくつかあります。
1つ目は、ランダムな値を生成してデータベースに存在するか確認し、なければそのまま使う方式です。しかしこの場合、データベースで確認し、必要なら再生成しなければならない手間があります。また、すでに大量のデータがある場合や Short Key の桁数を変える必要があるタイミングでは、大きな遅延が発生する可能性があります。
2つ目は、あらかじめランダムな Short Key を生成しておき、それをマッピングする方式です。これは事前に作っておいた Short Key を割り当てるだけなので、常に高速に Short URL を生成できます。しかし、これも完全な答えにはなりません。事前生成できる量には限界があるかもしれず、用意していた数を超えて Short URL が生成された場合など、追加で考慮すべき点が発生します。
では、もっと良い方法はないのか?
多くの検討の末、以下の方法を適用しました。ランダムな4文字列と PK を利用した文字列を組み合わせて使う方式です。各値についての説明は以下を参照してください。流れは次のとおりです。ユーザーが Short URL の生成をリクエストすると、ランダムな4文字列を生成してそのままデータベースに保存します。保存時に発行される PK を、以下の説明の方法で文字列に変換します。最初に生成したランダム文字列と PK 文字列を組み合わせて Short Key を作ります。こうすることで、どれだけデータが蓄積しても、重複なく高速かつ安全に生成できるようになります。

  • ランダムな4文字とは?
    ここでいうランダムな4文字は、英小文字・英大文字・数字で構成された完全にランダムな文字列です。この文字列は重複しても問題ありません。
  • PK を文字列に?
    次に2つ目の値である PK 文字列です。英小文字・英大文字・数字を組み合わせて、文字列を順番に作るとします。順序は英小文字 a -> z、英大文字 A -> Z、数字 0 -> 9 です。すると a は最初に作られる値、b は2、c は3……というように順番に値を組み合わせていくことができます。9 まで作り終えたら aa、ab、ac のように桁数を増やして作れます。このように順番に作っていくと、文字列に対応するインデックスが生まれます。a のインデックスは 1 になるわけです。ここで使える方法があります。PK をインデックスとし、その PK に対応する文字列を見つければよいのです。

Q. Short URL から Original URL へ高速に遷移させるには?
A.
これはとても単純で、キャッシュを使いました。さまざまなサービスがありますが、このプロジェクトではメモリキャッシュを使い、高速にデータを参照できるようにしました。さらに、単にデータを取得してリダイレクトする以外の付加機能については、軽量スレッドを生成して処理しました。

Q. 追加の付加機能にはどのようなものを実装しましたか?
A.
まず1つ目として、プラットフォームごとに異なる URL へ遷移するよう実装しました。iOS、Android それぞれの基本 DeepLink を受け取って保存し、DeepLink へ遷移できなかった場合に備えて FallbackUrl も追加で受け取るようにしました。そのほか、デスクトップでアクセスした際に遷移する URL も受け取り、あらゆるケースに備えました。
2つ目として、Original URL へ遷移するタイミングで、ユーザーがアクセスログを確認できるよう Webhook URL を受け取り、Original URL へ遷移するたびに Webhook URL を呼び出す機能を追加しました。現時点では User Agent と Short URL 情報のみを送るよう実装しています。
3つ目として、Short URL 生成時に Head タグの情報を追加で入力できるようにしました。これを追加した目的は、og タグをカスタマイズするためです。該当タグを入力しない場合は、Default URL の head 情報が保存されるようにしてあります。


このプロジェクトは Rust を使って開発しました。実は Rust を学び始めてまだ 2か月しか経っていません。URL Shortener プロジェクトは最初は FastAPI で開発し、その次は Golang でも開発していました。その後 Rust を学ぶ中で大きな魅力に引き込まれ、完全に高度化した URL Shortener プロジェクトをもう一度作ることになりました。

まだ文法や所有権、ライフタイムなどに慣れておらず、コード面で不足している点があるかもしれません。ぜひ関心と応援、そしてフィードバックをお願いします 🙏

最後まで読んでいただき、ありがとうございます

17件のコメント

 
leelou2 2025-01-09

ほかのプロジェクトも投稿しました。ぜひご関心をお寄せください 🎉
https://ja.news.hada.io/topic?id=18647

 
po5678 2025-01-07

とても素晴らしいプロジェクトです。
書かれているように、Docker がサポートされるととても嬉しいです!

 
leelou2 2025-01-07

ありがとうございます 👏 Docker は今週中に追加して掲載しておきます 🙇‍♂️

 
po5678 2025-01-07

メールアドレスの入力は必須でしょうか? メール認証が完了しないと、Webhook やアドレス生成ができないとは知りませんでした。

 
leelou2 2025-01-07

もし社内利用のみでカスタマイズが必要であれば、そのプロジェクトとは別に個別でカスタマイズ対応します!

 
leelou2 2025-01-07

はい、公開サービスとして使えるようにするため、メールアドレスを必須で受け取るようにしてあります(会員登録なしでメール認証を使用)。

JWT入力時にメールアドレスがなくても済むように修正する案も、一度検討してみます 🙏

 
po5678 2025-01-07

UbuntuのLightsailを入れて試しながら進めてみていますが、SSLとかpkg-config、sqlite、cargo など、インストールしなければならないものが多いですね :) 私は https の部分を NPM ではなく Cloudflare tunnel を使おうと思っていたのですが、やはり私には難しいようです haha.. Docker版を期待しています! ちょうど dynamic link がなくなって困っていたので、とてもいいですね。

 
leelou2 2025-01-07

Dockerfile と実行可能なコマンド(deploy.sh)を追加しました 🎉

 
leelou2 2025-01-07

できるだけ早くDockerを追加します(笑)

 
po5678 2025-01-07

おお、でも実行はしました! どうやったんだろう? ほえーん

 
jin225675 2025-01-07

GitHubのリポジトリにREADMEだけでなく、websiteにもデモURLを追加しておくと良いと思います!

たいてい、ホームページやプレイグラウンドがあるかどうかは、まずリポジトリ右側の情報を見ることが多いので、デモサイトがないのだと思っていました(笑)

良いプロジェクト、楽しく拝見しました!

 
leelou2 2025-01-07

あっ、見落としていました。すぐに設定します、ありがとうございます🤩

 
balthasar 2025-01-07

こだわりが感じられるプロジェクトですね!
私も会社で似たようなものを作って使っているのですが、私の場合は印刷媒体に載せる必要があるため、紛らわしい文字を避けるように文字セットを設定しました。

関連内容もGeekNewsにありました。

https://ja.news.hada.io/topic?id=14479

 
laeyoung 2025-01-07

いいですね!! idやリンクを生成するときに、それを考慮してくれると助かるんですよね

 
leelou2 2025-01-07

わあ、ありがとうございます👍

 
leelou2 2025-01-06

Rustをインストールして環境変数を指定するだけで、すぐに使用できます!
GoogleのURLサービスが今年終了するので、代替としてお使いください。気になる点や改善が必要な部分、インストール方法など、どのような内容でもメールを歓迎します 👏

 
leelou2 2025-01-06

https://f-it.kr/ で簡単にお試しいただけます 🙇‍♂️