はじめに
kazu_iroiroと申します!
1年以上ぶりにQiitaへ戻ってきました。
大学生になって、これまで触れてこなかった言語を学んだり、趣味だった電子工作にお金をつぎ込めるようになったりと、日々を満喫しています。
今年の4月からは2年生になり、そろそろアウトプットをしたいなと感じていたので、記事投稿キャンペーンを機に、アウトプットの回数を増やしていこうと思います。
この記事では、バックエンドにClickHouse + Cloudflare Workers + Honoを、フロントエンドにDocker + nfcpy + PaSoRiを利用した、合宿参加者の状況把握システムについて紹介します!
この記事は Qiita Tech Festa Sprint 記事投稿キャンペーン 『「AI時代のデータベース、何が変わる?」について語ろう!』の投稿記事です
経緯
私は大学でデジタル創作系の団体に所属しています。
この団体で今年度の合宿担当をしているのですが、この夏の合宿参加者数が80人規模となる見込みで、大変不安に思っています。
この人数を目視でカウントすることは非現実的なので、今部員がどこにいるのか、状況をリアルタイムで確認できたらいいよねということになり、開発を始めました。
リアルタイム把握系のプロダクトは、プライバシーと利便性の間でバランスを取るのが難しかったり、誰かが操作を忘れたりして、破綻しがちです
できるだけノンストレス、かつプライバシーに配慮した形として、所属している全部員が持っている「学生証」に目をつけました。
「改札」を宿泊先の各所に設け、部員が通行する際に「学生証」で認証してもらえば、リアルタイムでの位置確認を実現できそうです。
仕様の検討
学生証について
弊学の学生証はFeliCaをベースとしており、これをPaSoRiにかざすことで学籍番号とIDmを取得できます。
FeliCaなら読み取り速度も速く、改札として運用するのに最適です。
また、部員のみが使う前提のため、IDm(各FeliCaカードに固有のID)を利用したシステムでもセキュリティ上の心配はありません。
利便性向上のため、部員が持っている任意のFeliCaを学生証と紐づける仕組みを導入し、任意のFeliCaをかざしても反応させることとしました。
(自分がモバイルSuicaで通りたかっただけ)
ネットワーク環境について
合宿先では安定したインターネット環境が手に入りません。
毎年、複数の通信回線を束ねた冗長化回線を構築していますが、どうしてもレイテンシが大きくなってしまったり、接続が途切れてしまうことがあります。
そんな時でもログを保持できるような仕組みが必要です。
パソコンの台数について
デジタル創作サークルのため、もちろん部員から募ることでパソコンは沢山手に入ります。
しかし改札用に「放置してよいパソコン」というのは少なく、できる限りクライアントになる端末数は削減したいです。
したがって、2台のPaSoRiを1台のパソコンで管理することを要件としました。
これにより、「改札」を出るとき、入るときで別々のPaSoRiに学生証をタッチすることができるので、通過時の利便性を向上できます。
技術検討と失敗
最終的な構成に至るまでに、いくつかの試作を行ったので紹介します。
クライアント側
- Go (github.com/ebfe/scard)
ライブラリの仕様上モバイルSuicaの読み取りができなかった - Python (nfcpy)
Windowsだとドライバーの入れ替えが必要だった - .NET (felicalib)
ライブラリの仕様上、複数台のPaSoRiを同時に扱えなかった
サーバー側
- GAS + Googleスプレッドシート
認証APIとして動かすにはレスポンスが遅く、スプレッドシート側の情報表示も遅い - Cloudflare Workers (Hono)
認証APIとしては優秀だが、Workersに重たいDB処理をさせるわけにいかない(CPUの実行時間に制限がある)ので、単体では使いにくい
最終的に
どうしようか悩んでいたところで、ちょうどQiitaの記事投稿キャンペーンからClickHouseを知り、Cloudflare Workersと組み合わせることにしました。
Windowsでnfcpyを使う際にドライバの入れ替えが必要な問題については、usbipd-winを通してWSL上のDockerコンテナにPaSoRiをアタッチしてあげることで解決できることが分かりました。
ClickHouseって?
列でデータを管理する、オープンソースのデータベースです。
PostgreSQLなどは、行単位でデータを管理するので、データの持ち方が異なります。
列ごとにデータを処理できるため、分析に向いているらしく、今回のような蓄積したログを管理するのにも向いていそうです。
逆に、Cloudflare D1のような、Key-Value型のDBが得意とする「認証」には向いてないわけですね。
だからこそ、Cloudflare Workers と ClickHouseの組み合わせがちょうど良さそうです。
実際に作ってみた
構成
以下のような構成で作ってみました。
【Reader: 検知部】
Windows + usbipd-win + WSL2 + Docker + nfcpy + PaSoRi RC-S380
【認証】
Cloudflare Workers + Hono + Cloudflare D1
【DB】
ClickHouse Cloud
【Viewer: Webダッシュボード】
Cloudflare Workers + Hono + Cloudflare Pages
の組み合わせです。
他の記事で楽だと言われていたので、ClickHouseはセルフホストではなく、Cloud版の無料トライアルで試してみました。
ClickHouse Cloudの登録から認証情報の取得まで
登録手順
この認証情報を、Cloudflare Workersに登録してあげれば、準備完了です。
利用規約がシンプルで読みやすく、簡単に登録できて便利でした。
ランニングコストの観点から、セルフホスト版のClickHouseも試してみたいです。
クラウド系のサービスを展開しつつも、オープンソースかつ自前の環境ですぐ動かせる、というのは珍しく、大変ありがたいです。
動いた!!
パソコンに2台のPaSoRiを繋いだ状態で、実際にWebダッシュボードがリアルタイムに更新されることを確認できました。
感想
GAS + Googleスプレッドシートでバックエンドを構成していた時よりも、圧倒的に速くなって感動しました。
検討していた仕様も満たせたので、大変満足です。
ClickHouse側の更新がとても速いため、Webダッシュボードのデータ取得間隔が、表示の更新頻度に大きく影響を与えるようになってしまいました。
今後の展望
実運用を始めると、ClickHouseに蓄積されるデータ量も膨大になると思うので、これからレスポンス速度がどうなるのかが楽しみです。
合宿まではもう少し時間があるので、Cloudflare Workersの改修をして、少しでもレイテンシが短くなるようにしようと思います。
ダッシュボードのUI・UX向上もしていきたいです。
最後までお読みいただきありがとうございました!
参考文献









