livedoor Reader 終了に寄せて: Fastladder オープンソース版は GitHub で開発継続中です
どうせ長らく放置なんでしょ、と思ってたらRails最新版に追従してくれててありがたい限りでした。
HerokuにデプロイするボタンがあるのでHerokuで動かすところまでは一瞬。
Basic認証をかける
全世界に公開するものではないので、RackのミドルウェアでBasic認証をかけた。
config/environments/production.rb
の一番下あたりにこれを追加して、
config.middleware.use '::Rack::Auth::Basic' do |u, p|
[u, p] == [ENV['HTTP_USER'], ENV['HTTP_PASSWORD']]
end
Herokuの環境変数設定で HTTP_USER
と HTTP_PASSWORD
という環境変数をセットする。
crawlerを起動する
これだけだとまだクローラーのプロセスが動いていない(Procfileにはcrawlerというプロセス定義があるけど、Herokuのがデフォで動かしてくれるのはworkerのため)。
crawlerを常時起動してしまうとwebとcrawlerで2プロセスになってお金がかかってしまうので、process-schedulerというのでこんなふうに夜の1時間だけクローラーをまわしていた。ギリギリ月々750 Dyno Hoursにおさまるらしい。
自分の利用頻度的にはこれで十分なのだけど、この方法は結局やめることにした。(後述)
NewRelicで監視
Herokuは1時間アクセスが無いとウェブのプロセスがスリープさせられてしまうので、NewRelicのAvailability Monitoringという機能を使って定期的にリクエストを飛ばすことにした。元ネタ
- https://addons.heroku.com/newrelic ここからNewRelicのStarkという無料のやつを追加し、
- 説明に従ってAPIキーの入った
config/newrelic.yml
とnewrelic_rpm
gemをgit add
し、 - NewRelicのサイドバーのAvailability monitoringというところから監視するURLを設定する
これで指定したURLに30秒に1回ぐらいリクエストしてくれるので、スリープにならなくなる。
NewRelicは401 Authentication Requiredでも落ちてないと判断するらしい。
せっかくなのでNewRelicからリクエストされるたびにクローラーを走らせる
これで24時間クローラーを動かすことができる。
クローラーの実体は lib/fastladder/crawler.rb
にあるけど、10秒ぐらいだけクロールして死んでくれるオプションが無いみたいなので、こんなメソッドを作り、
def run_with_timeout(timeout)
@interval = 0
start = Time.now
finish = false
until finish
finish = run_loop
break if Time.now - start >= timeout
end
end
Railsのルーティングを追加するのが面倒だったので、Rack Middlewareを作って、
class Crawl
def initialize(app, opts = {})
@app
@opts = opts
end
def call(env)
request = Rack::Request.new(env)
if request.path != @opts[:path]
return @app.call(env)
end
Fastladder::Crawler.new(@opts[:logger]).run_with_timeout(@opts[:timeout])
[200, {}, ["ok"]]
end
end
config/environments/production.rb
のBasic認証を追加したところのすぐ上にこれを書いた。
config.middleware.use 'Crawl', {timeout: 10, path: '/my_secret_crawl_url', logger: Logger.new(STDOUT)}
Basic認証より前じゃないとだめ。
最後にNewRelicの画面でリクエストしてもらうURLを変えておく。
HerokuでFastladderを無料で使えるか
実際のところ、厳しそう。
Postgresの無料枠が1万行までで、DBのほとんどが記事レコードなので、200アイテムx50フィードぐらいでいっぱいになる。月9ドル払って100万行プランにするのが妥当ではないかと思う。
ちなみに古いアイテムを削除するコードは無いみたいなので(特殊ケースを除く)、気が向いたら各フィード200アイテムより前のものを消せばよいかもしれない。