Open1

アンテナサイト開発

rubellumrubellum

APEX アンテナ

https://apex-antenna.com/

開発経緯

現在進行形で汎用的なクローラを開発しています。

具体的に何に利用するかは決めずにクローラを作っていたので、
クローラ開発に一区切りついた今実際にクローラを利用したWebアプリケーションを作ることにしました。
題材として今ハマっている APEX として選び、APEX関連のアンテナサイトを開発することにしました。
(なおAPEXの最高ランクはプラチナです)

構成

フロントエンド

  • React
  • Tailwind.css
  • Parcel

React は勉強がてらチョイス。
サーバーサイドがRubyなのでRubyMineで書いています。IDEの補完がつよつよで大変よろし。

Tailwind.css は最近ハマっているので採用。
以前はsassを自分で書いていましたが、だんだん面倒になってきたので今はこればっかりです。

ビルドはParcelでおこなっています。

次にやりたいこと

TypeScript

TypeScriptの恩恵にあずかると幸せになれると聞いています。
最近出版された『プロを目指すための人のTypeScript入門』の評判が良さそうなので、今読んで勉強中です。

サーバーサイド

  • Ruby
  • Sinatra
  • Sequel

DBから記事情報を取ってきてJSONを返すWebAPIです。
やることは本当に記事を返すだけなので素朴な構成で実装しました。
(普段はPHPばかり書いててRubyをよく知らないので、おそらく素朴な構成と信じています)

記事データの生成はクローラシステム側でおこない、そこからデータをインポートしています。

Webサーバーはnginxのリバースプロキシが前段にいて、うしろにRubyアプリケーションがいます。
アプリケーションサーバーはpumaです。

RubyアプリケーションはDockerのコンテナで動いています。
k8s の勉強がてらこのアプリケーションをk8sで動かしてみたかったからですが、まだ k8s 上では動いていません。

次にやること

特になし

採用しなかったもの

PHP

普段仕事でたくさんPHPを書いているので、今回はRubyで作ることとしました。

ActiveRecord

つい手慣れたSequelを使ってしまっただけの理由で採用しませんでした。
Railsを使わず単独で利用できるようなら、次のWebAPIで使ってみようと考えています。

クローラ

このアプリケーションとは別に現在進行形で汎用的なクローラを開発しており、その仕組みでデータを取得・生成しています。

このクローラはこのアンテナサイトとは完全に独立して動作しています。
データの流れは次のようになっています。

  • ①クローラがWebサイトからデータを取得し、JSONをCloud Storageに出力する:クローラの役割
  • ②定期的にEmbulkでJSONをDBにインポートする:アンテナサイトの役割

クローラは自分的にそこそこ良い感じの構成で開発できたので、別のスクラップでまとめる予定です。

DB

VPSにMySQL 5.7 MySQL 8.0をインストールして動かしています。
ROW_NUMBER()を使いたくなったので、MySQL 8.0にアップデートしました。

アプリケーションサーバーと同居しています。
悲しきかなアクセスも全然上がらないでしょうし、表示用のデータしか保存していないため必要な容量も負荷も少ないためです。
負荷が増えてきたら移動します。

以下、採用しなかった案。

Cloud SQL

元々Cloud SQLを使っていましたが、最小プランでも4000〜5000円/月かかっており、個人で使う分には思ったよりお金がかかってしまいました。
そのため、VPSにアプリケーションサーバー/DBサーバーを同居させる方法で節約することにしました。

定期ジョブを動かすだけの場合、アプリケーション環境のCloud Runが思ったより安かったので元が取れるかなと思っていましたが、甘かったです。
(Cloud Runは〜100円/月でした)

ワークフローエンジン

今回開発したアンテナサイトのジョブはWebAPIの呼び出しのシーケンスによって機能します。
ワークフローエンジンはWebAPIの呼び出しの制御、スケジュール実行、パラメータ管理をします。

参考までに現在使用中のn8nでのワークフローの一部を載せておきます。
このアンテナサイト以外の機能も含みますが、こういったワークフローが現在10個ほどあります。

以下、ワークフローエンジンの候補を含めて記載していきます。

n8n

今使っているワークフローエンジンです。GUIでゴリゴリ作っていきます。
今のところライトな使い方しかしていないので、永続化はデフォルトのSQLiteのまま使っています。

Redisトリガーがとても便利です。
このアンテナサイトのジョブは基本JSONを受け取るWebAPIで書かれています。
そのため、JSONをRedisにpublishコマンドに投げ、n8nのRedisトリガーノードで受け取るだけでジョブキュー代わりになります。

Google Workflows

最初はこれを使っていました。
元々GCPでアプリケーションを動かしており、Cloud RunとCloud Schedulerとの相性がよかったです。
GCP上にアプリケーションを展開する場合はこれが最良でしたが、後からアプリケーションをVPSに移動したため現在は使っていません。

airflow

仕事でも使う予定があったので使ってみましたが、今回のWebAPIの呼び出しのシーケンス用途に限っていうとオーバーキルだったので採用しませんでした。

digdag

airflowよりも簡単でyaml(正確にはdigファイル)でワークフローを書けるのでとてもよかったです。
今回のWebAPIの呼び出しのシーケンス用途に限っていうとオーバーキルだったので採用しませんでした。

また別の命題としてWebAPIの呼び出しシーケンスの作成を生粋のプログラマ以外でも触れるような環境にしたかったため、その点ではairflowよりよかったです。

インフラ

サーバーはさくらのVPSを使っています。
以前から利用していたサーバーに相乗りしています。
特にさくらのVPSのコレ!といった理由はありませんが、不満もありません。
メモリ2GB・仮想3コア・SSD100GBの約15000円/年プランです。(約19000円の初年度30%OFF)

デプロイ

フロントエンドは静的ファイルのみで完結しているので、ビルド後にrsyncでWebサーバーにアップロードしています。
今はVPS上においていますが、Netlifyに慣れているので移行予定です。

サーバーサイドのWebAPIもソースをrsyncでアップロード⇒アプリケーションサーバー上でdocker build&runしています。
そのため、デプロイ時に瞬断しています(笑)

デプロイはどちらもrake deploy の1ライナーで実行できる形になっています。
ローカルの開発マシンから実施しています。

アンテナサイト開発まではCloud Runを多用していたので、今はVPSへのデプロイが大変泥臭い状態です。

アクセス解析

フロント側にGoogle Analytics を使っています。
いつも何も考えずに入れていますが、使いこなせてはいません。