cloudflare d1とhonoで5ch型掲示板を作ってみた

作ったものはここに動いているので、ちょっとでも見ていってくれると嬉しい。

d1ch.cc

作った動機

この記事で、Cloudflare d1というサービスが開発されつつあることを知った。 zenn.dev

簡単に言うと、Cloudflare WorkersというCDNのエッジノードで動くFunctionサービスがあって、Cloudflare d1はそこにSQLiteも配置しちゃうぜ大作戦。
SQLiteは単なるファイルをDBとして使う技術であり、常駐するサーバープロセスが必要ないので、他のミドルウェアに比べるとかなり安くなりそう。安価なDBサービスを探していた自分も興味を持って色々と試していた。

大規模に使う場合、ホットスポットが予想して、アクセスが少ないものは他のストレージに退避しつつ、部分的に乗せる、みたいな工夫が必要になるかもしれません。 ただこれも D1 で sqlite テーブル単位の分散ができるようになったら解決するかもしれません。

Cloudflare d1のボトルネックとして、↑は自分もそう思っていて、とすると5chの板のように、スレッドの量が増えると書き込みがないスレがdat落ちし、アーカイブに似た、過去ログに移動するという仕様は最適では?と考えていた。

一方、これを作ろうと思った時はちょうど2023年のWBCの頃で、なんGやなんJがスクリプトDDos攻撃によるサーバーダウンに悩まされていたので、よし一丁作ってみるか、とやってみることにした。

開発のこと

技術スタックはだいたい以下

  • Cloudflare Workers
  • Cloudflare d1
  • hono
  • drizzle-orm

他には専ブラが投げてくるリクエストを覗くのはProxyman(https://proxyman.io)も大変役に立った(無料でも単用途の範囲なら十分使える)。専ブラはどれもProxy機能を備えているのも大きかった。

実装したことは以下

  • dat API
    • スレッド一覧
    • 書き込みGET
    • 書き込みPOST
      • トリップ計算
      • 書き込み者ID
    • スレッド終了時の処理
  • 圧縮ワーカー(いわゆるdat落ちをさせる仕組み)
  • クッキーの返却とIPアドレスの紐付け
  • クッキーのRECAPTCHA認証(必要であれば)

5chは旧世代のCGIで実装されているものであり、専ブラ対応の掲示板を作るのにそんなに難しいことは必要なくて、必要なことは大体と〜く2ちゃんねる - Talk 2chに書いてある。ただし文字コードはShift-JISなので気を配る必要があるし、Shift-JISで表現できない絵文字を返す時は実体参照にする必要がある。その点honoはShift-JISにエンコードしたByte列を返せば問題なく動いてくれた。

更に補足すると、dat APIはスレッドの差分取得がキモになっている。具体的に言うと専ブラは欲しい範囲をRangeヘッダーで指示してくるので、これの挙動を愚直にSQLで再現するのが面白いところだった。

また、Cloudflare Workersを使って開発する時はCloudFlare Tunnelで自宅サーバーを公開する(FreeプランOK)を使うのが便利で、自分の場合、xxx.d1ch.ccみたいなサブドメインを開発環境のポートとして公開することで、開発環境と本番環境の差異なく開発することができた。このシステムで言うと、書き込み者IDの計算などにクライアントのIPアドレスが必要なんだけど、ローカルホストだと取得できないが、トンネルしているドメインからアクセスすることでCloudflareがCF-Connecting-IPというヘッダーにIPアドレスをセットしてくれたりする。

honoは、単なるCloudflareとブラウザとの境界面という役割以上に、[Cloudflare Workers] HonoにJSXミドルウェアが追加されましたで紹介されているhono/jsxhono/htmlの合わせ技を使うと、昔ながらのSSRなんだけどシンプルなフレームワークならではの不思議な開発者体験があり、なんだかとても直感的な感じがした。

d1で気になったこと

d1自体はまだOpen alphaであって全くProduction Readyではないので、僕が気にするまでもないことだとは思うけど、冒頭で挙げたボトルネックに加えて、writeがスケールしないのが気になる。現状だと、1つのCloudflare Workersに1つのDB、1つのファイルしかマウントできないので、水平分割をするにしても垂直分割をするにしても、APIで動的にファイルを増やせるような機能が必要だと思われる。

また現状のd1にはトランザクションがないので純粋に困る部分がある。これに関しては代替機能としてBatchがあり、drizzleではPRが出ているのでみんな楽しみにしているという感じ。

作ってみてわかったこと

ある程度動くものができてわかったけど、作るのはとにかく楽しかったが、こういう場を運営することに対する意欲や能力はないということである。

また、現在はいろいろあって住民が離散してしまったので、更に分散させるのものなあ、という感じ。

某所でちょっとだけ紹介したところ、クソスレも含めてスレッドを立ててくれる人がいて、いわゆる過疎掲示板のような様相になっており、そんな感じの書き込みがエッジノードに存在しているという事実がなんだか楽しい。