AutoPatchWorkのサーバー周りのこと
地味に色々と調整しているのでまとめておきます。見よう見まねの継ぎ接ぎばかりですが…。
AutoPatchWorkはwedata(About - wedata)のAutoPagerize用SITEINFOを使わせて頂いていますが、wedataのサーバーは負荷に弱いので、SITEINFOは自前のサーバー(といっても安心のhetemlですが)に置いています。
hetemlサーバーでcronを設定して1時間に1回、SITEINFOを更新するようにしていて、AutoPatchWorkユーザーは一日に1回hetemlサーバーからSITEINFOを取得しています。
ただ、AutoPagerizeのSITEINFOは2MB近くあるので、1万人が毎日アクセスしたら転送量が20GBに達します(全員が毎日更新にくるわけではないので、実際はもっと少ないですが)。hetemlの転送量は「目安として 1日 20GB まで」(2011年6月27日時点。ちなみに以前は10GBだった)で、ChromeのAutoPatchWorkユーザーだけで6万人以上いるので余裕でアウトです(といっても、一度問い合わせてみたところ、目安を超えたら即制限がかかるようなことはないそうです)。
ただ、容量を節約するポイントは色々あって、まずオリジナルのSITEINFOは次のようなJSONデータです。
{ "name": "Google Search", "resource_url": "http:\/\/wedata.net\/items\/472", "updated_at": "2011-04-24T23:09:52+09:00", "created_by": "swdyh", "database_resource_url": "http:\/\/wedata.net\/databases\/AutoPagerize", "data": { "pageElement": "id(\"search\")\/div[ol or div]|id(\"res\")[not(@role)]\/div[ol or div]|id(\"ofr\")", "url": "^https?:\/\/[^.\/]+\\.google(?:\\.[^.\/]{2,3}){1,2}\/(?:c(?:se|ustom)|search|webhp|#)", "nextLink": "id(\"pnnext\")|id(\"navbar navcnt nav\")\/\/td[span]\/following-sibling::td[1]\/a|id(\"nn\")\/parent::a", "exampleUrl": "http:\/\/www.google.com\/search?q=AutoPagerize\r\nhttp:\/\/www.google.com\/cse?cref=http%3A%2F%2Fwww.guha.com%2Fcref_cse.xml&q=firefox&sa=Search&siteurl=www.google.co.jp%2Fcse%2Fdocs%2Fcref.html\r\nhttp:\/\/www.google.co.jp\/custom?q=firefox\r\nhttp:\/\/www.google.com\/webhp?hl=en#hl=en&expIds=17259,18167,25901,25980,26440,26459,26512&sugexp=ldymls&tok=So3knfbAtc2kJy-W-lXiWw&xhr=t&q=autopagerize&cp=10&pf=p&sclient=psy&safe=off&site=webhp&aq=f&aqi=g5&aql=&oq=autopageri&gs_rfai=&pbx=1&fp=6052204b889acdd8" }, "created_at": "2008-04-16T12:35:37+09:00" }
実際に使うのはdataの中身で、さらにexampleUrlなどはデバッグ用なので、普段は使用しません。つまり、こうできます。
{ "pageElement": "id(\"search\")\/div[ol or div]|id(\"res\")[not(@role)]\/div[ol or div]|id(\"ofr\")", "url": "^https?:\/\/[^.\/]+\\.google(?:\\.[^.\/]{2,3}){1,2}\/(?:c(?:se|ustom)|search|webhp|#)", "nextLink": "id(\"pnnext\")|id(\"navbar navcnt nav\")\/\/td[span]\/following-sibling::td[1]\/a|id(\"nn\")\/parent::a" }
これだけで1.9MBから715KBまで節約できます(ただ、元のデータを引けなくなるので、IDだけ追加しています)。結構節約できますが、まだ3万ユーザー程度しかカバーできません。
これにgzipを加えてみます。cronバッチの中でgzファイルを静的に作成して、.htaccessで次のように指定します。
RewriteEngine on RewriteCond %{HTTP:Accept-Encoding} gzip RewriteCond %{REQUEST_FILENAME}\.gz -s RewriteRule ^(.+)$ $1.gz AddEncoding x-gzip .gz
- Accept-Encodingにgzipが含まれていて、
- リクエストされたファイル名+.gzなファイルが存在したら、
- URLを.gzつきに書き換え、
- ファイルタイプをjsonとして強制する
という指定です。
AddEncoding x-gzip .gz はレスポンスヘッダにContent-Encoging: gzipをつけて、ブラウザにgzipとして解釈させるようにしている(のだと思うのですが、あまり自信ない…)
gzip効果で、1.9MBのファイルは355KBに、715KBのファイルは152KBまで節約されます。
152KBならすくなくとも13万ユーザーまで大丈夫です。
実際、今のところ1日の転送量は8GB程度に抑えられています。
ついでにhetemlがmod_expiresにも対応していたので、ExpiresByTypeなんかも加えて、 http://ss-o.net/json/ の .htaccess はこんな感じになっています。
Options +Indexes Header append Access-Control-Allow-Origin: * ExpiresActive on ExpiresByType application/json "access plus 12 hours" ExpiresByType application/x-javascript "access plus 2 days" <Files ~ "\.json"> ForceType "application/json; charset=utf-8" </Files> RewriteEngine on RewriteCond %{HTTP:Accept-Encoding} gzip RewriteCond %{REQUEST_FILENAME}\.gz -s RewriteRule ^(.+)$ $1.gz AddEncoding x-gzip .gz IndexIgnore .htaccess *.bak *.gz IndexOptions FancyIndexing HTMLTable NameWidth=* XHTML