SVX日記
2008-02-09(Sat) パルスを数えまくる
長らくチマチマと作業を進めてきた、家庭用電源の50Hzで時計を作るプロジェクトであるが、とりあえず50Hzをカウントして時刻を表示する、というところまできた。ずっと疑問に思っていた電源の50Hzの精度であるが、脇に腕時計を置き、秒単位のズレを目視で確認した限りでは、1時間で0.5秒程度のズレが生じるようだ。
しかし、1時間で0.5秒ということは、24時間で12秒、5日で1分、1ヶ月で6分……うーむ、100円で売っている腕時計でも、平均月差は30秒程度だろうから、ちょっとイマドキの時計としては使い物にならない感じだ。でも、敢えてコレで行ってみようかな、と思う。日や季節によっても多少は違ってくるかもしれず、それを体感してみたいという気持ちもあり……
その「コレ」とは、ロータリーエンコーダ。ふたつのパルスを読み取ることで、回転方向と速度を検出するセンサだ。かなり前にアルカノイドのパドルコントローラを作ろうと思って実験用に購入しつつ、放置してあったパーツだ。
RotaryDecode
SWAP (GPIO)>A
AND A, 0000_0011b
LD (BUF), A
RR (BUF)>A ; 観測値を正規化
AND A, 0000_0001b
XOR (BUF), A>A
SUB (LAST), A ; 前回 - 今回
BIT 0, (LAST)
JP Z, RotaryDecode1 ; 不動 or 無効
SKIPRES 1, (LAST)
INC (VAL) ; 正転
SKIPSET 1, (LAST)
DEC (VAL) ; 逆転
RotaryDecode1
LD (LAST), A
messagesをみると、OOM-Killerが動いているので、何かのプロセスのリークか何かだろうと判断し、たいして気にもせず強制再起動で回避してきたが、最近、落ちる頻度が増してきて、リセットボタンを押すのがうっとおしくなってきた。特に設定をイジっていないのに頻度が増すということは、内部要因ではない可能性が高いということだ。どうにかせねばなるまい。
それ以前に、お客のLinuxサーバをどうにかすることで飯を食っているのに、自分のサーバをボコボコと落としているというのは、カッコ悪い。まさに医者の不養生なので、どうにかするコトにする。まずは、ロギングツールを稼動……した途端、都合よく、すぐ再現した。どれどれ。
なんと、バカみたいにhttp要求を連続(秒間20とか)で投げ続けるアホがいた。rubyのcgiプロセスが溢れかえっていて、落ちる寸前にはロードアベレージは数百に達している。tdiaryはかなり重く、メモリも食うので、秒間1アクセス程度にしてもらわないと困るんだがなぁ。どうしようかなぁ。いくつか案を考える。
- アホのIPをハジく
- Apacheに負荷制御モジュールを入れる
- ユーザの同時プロセス起動数を制限する
- iptablesに連続アクセス防御ルールを書く
1はアホが複数現れるとイチイチ面倒。2はモジュールを入れるのが面倒。4は画像が多いウチのサイトには適応しづらい。というわけで、3がいい。連続でCGIにアクセスされた場合、CGIの起動を故意に失敗させ、Apacheには内部エラーとして処理させる。結果としては負荷制御になるワケだ。
ユーザの同時プロセス起動数といえばulimit -uのmax user processesなのだが、これは環境変数みたいなものなので、CGIが起動してから設定しても遅い。そもそも、CGIの起動を抑制するという目的に合わない。Apacheの起動時に指定してしまう手もあるが、Apache自身に制限が加わるのは困る。
print `/bin/bash -c 'ulimit -a'`.gsub(/\n/, "<BR>\n")
RLimitNPROC 20
max user processes (-u) 20