ネットワーク初心者が、さくらクラウドからAWSに移行した時のメモ
ネットワーク素人が、さくらクラウドで負荷分散構築した時のメモ1【準備編】 - なりせなるてず
この記事を4月に書いてからたった5ヶ月ですがAWSに半分移行しました。
AWSに移行するきっかけ
嬉しいことに自社サービスが順調に成長してて、アクティブユーザーがだいたい常時300以上、多い時は1500から3000位にまでアクセスが集まるようになったことです。
勿論さくらクラウドでも対応出来るんですが、瞬間的に通常時の5倍から10倍のアクセスを捌きつつ、通常時はサーバーを減らして安く抑えたいという要求を叶えるためにはさくらクラウドじゃムリだろうということになりました。
さくらクラウドはオートスケーリング対応してませんし、今のところその予定もなさそうなのでAWSの出番というわけです。
AWSのお勉強
AWSはオートスケール出来て凄い!くらいの知識しか無かったのでお勉強です
これと
自分がしたいと思ってたことはほぼこの2つに概要からやり方まで書いてあり、非常に参考になりました。
ただ、AWSのコンソール画面はしょっちゅう変わってるので、AWSコンソールからオートスケーリングさせる設定は
AWS - 【AutoScalingをManagementConsoleから設定してみる】 - Qiita
こちらを参考にしました。
EC2のインスタンスを作るときにAmazon Linuxを選ぶと、スペックはしょぼいですが1年間無料で使えるプランがあるので色々テストできます。
クラウドサービス無料利用枠 | アマゾン ウェブ サービス(AWS 日本語)
サーバー構成
先ほどのスライドにありますが、こういう構築にしたほうがいいよ!ってのをほぼ丸パクリして構築しようと考えました。
オートスケーリングを使う流れとしては、
1.EC2でwebサーバーとして機能するものを作る。起動時に自動で最新のプロジェクトがデプロイする仕組みを作っておく
2.EC2でwebサーバーが出来たら、インスタンスをstopして、AMIを作る
3.ロードバランサーを作る
4.オートスケーリングの設定を作る
こんな感じで作って移行してみたんですが、移行3時間で転送量がめちゃめちゃかかってやばい事が判明。
このまま行くと月額80万位かかる計算でした・・・(゚д゚;)
冷や汗が止まらなかったです。
急いで転送量がかからないさくらクラウドに画像を置くことにしました。
で、結局最終的にはこういう構築になりました。
画像をNFSでさくらクラウドのファイルサーバーにアップロードして、画像のURLをさくらクラウド側にしアクセスさせるようにしました。
webサーバーはオートスケーリング出来るAWSを使い、画像は転送量でお金がかからないさくらクラウドにして、両者のいいとこ取りを実現しました。
戸惑ったこと
移行するにあたって色々ハマった事があったのでメモ
RDSのストレージは追加出来るけど減らすことは出来ない
作ったあとでこんなに容量要らないやと思い容量の変更をしようと思ったのですが、追加することは出来ても削除することは出来ませんでした。
CentOSが色々入ってない
vimとかwgetとか、あと色々サービス群が入ってませんでした。
さくらクラウドのCentOSには初期から色々サービスが入っててすぐ使えるので便利でした。
ただその反面初期から起動してるサービスはそのままにしてると、かなりの確率でDDosなどの踏み台にされるので対応しなければならず面倒です。
当然といえば当然ですが、AWSのCentOSは余計なサービスは入っておらず軽量です。
topコマンドで見れるCPU使用率があてにならない
ApacheBenchで負荷テストをしてる時、同時接続数をいくら増やしても40%位を限度にそれ以上CPU使用率が上がりませんでした。
Amazon EC2 インスタンスの負荷測定 : まだプログラマーですが何か?
こういう理由があるみたいです。
ELBはIPアドレスがない
ELBにはIPアドレスが無く、EIPを使っても設定することが出来ません。
つまりAレコードでDNSを設定することが出来ず、CNAMEしか無理ということです。
不勉強で知らなかったのですが、CNAMEはサブドメインしか指定することが出来ないので、
「www.example.com」みたいなアドレスで良ければいいのですが、「example.com」みたいなURLでアクセスさせることが出来ません。
これを解決するにはRoute53を使うしかありません。よく出来てますね・・・。
営業でも簡単!Route 53の基本設定 « サーバーワークス エンジニアブログ
上記を見て設定しました。
オートスケーリンググループの設定を変えると突然EC2が死ぬことがある
AMIを更新してオートスケーリンググループも変更したりするんですが、それをやると数時間後(タイミングは不明)で突然EC2群が死んで、新しいAMIで立ち上がります。
検索しても出てこない現象なので詳細は不明です。
よく出てくる意味分からなかった単語
AMI
Amazon Machine Imageの略。
インスタンスを作るときのひな形。
ApacheやPHPなど必要なものをインストールしておいて、オートスケーリングするときになどにこのひな形を元にインスタンスを自動追加出来る。
ELB
Elastic Load Balancingの略。
ロードバランサです。ただし普通のロードバランサと違い、ロードバランサ自体がスケールアップ出来る。
EBS
Elastic Block Storeの略。
ストレージのこと。
起動中のEC2にストレージを追加できたりする。
AZ
Availability Zoneの略。
データセンターの中で、電源などが物理的に分かれている場所の事らしいです。
Multi-AZは別々のAZにEC2やRDSを配置することで、天災時などで万が一どちらかの電源が落ちたりしても別のAZにはアクセスでき、耐障害性に優れているということみたいです。
IOPS
I/O per Secondの略。
HDDなどのディスクが1秒間に出来るI/O処理の数のことらしい。
この数値が高いほど性能がいいということ。100IOPSだったら1秒間に100回トランザクション処理が出来る(多分)
さくらクラウド vs AWS
さくらクラウドが有利だと思う点
1. さくらのほうが1インスタンスに対しての費用対スペックがいいです。
例えば社内向けのコミュニケーションツールみたいに、ある程度アクセスする人数やPVがわかっている状態ではさくらクラウドで構築したほうが安上がりになると思います。
2. ドキュメントやコンソールが日本語
AWSのように頻繁にコンソール画面が変わることが無いのでドキュメントやブログで見た情報のまま使えることが多いです
3. 転送量がかからない
標準的なWebサービスをAWSで運用する時、最もお金がかかるのが画像などの転送量だと思います。
ここにお金がかからないのは相当デカイです。
FuelPHPで全てのコントローラーにフィルタをかける
全部のコントローラーで決まった処理、例えば認証処理とかを行いたい場合、Symfonyみたいな全部のコントローラーにかかるフィルタが欲しいところですが、用意されてないようです(見つけられてないだけかも)
なので今までずっと、それぞれのコントローラーにbefore(),after()メソッドを書いていたんですが公式ドキュメントをちゃんと読んだら解決できました。
ベースコントローラー
<?php class Controller_Public extends Controller_Template { public function before() { parent::before(); // 認証処理などの共通処理を記述 } public function after($response) { $response = parent::after($response); // アクション実行後に行いたい共通処理を記述 return $response; } }
こんな感じで共通処理だけを記述したベースとなるコントローラーを作成します。
そして共通処理を行いたいコントローラーに継承させます。
<?php class Controller_Top extends Controller_Public { public function before() { parent::before(); } public function after($response) { $response = parent::after($response); return $response; } public function action_index() { // 処理 } }
Controller_Publicを継承することで、毎回before()メソッドなどに処理を書かなくてよくなります。
今回はベースコントローラーをController_Templateを継承して作成しましたが、Controller_HybridでやればTemplateもRestも対応できます。
ちゃんとドキュメント読まなきゃダメですね
FuelPHPで画像圧縮と圧縮率
webページの表示速度を上げるうえで必ずネックになる画像。
圧縮するとどのくらい変わるものなのか調査してみました。
FuelPHPで画像圧縮
いつもどおりFuelPHPです
$filepath = 'image.jpg'; Image::forge(array('quality' => 90))->load($filepath)->output();
Image::forgeメソッドに配列でqualityキーと値を渡します。
qualityが90%になるように?圧縮してくれます。
圧縮率
元画像が307KBでした。
クオリティ90%で110KB
80%で75KB
70%で60KB
60%で51KB
50%で45KB
40%で39KB
30%で33KB
20%で25KB
10%で17KB
と、なりました。
90%の時点で約3分の1にまで小さくなるでの非常に有効ですね。
勿論画像自体も汚くなるのですが、僕の見た限りでは70%くらいまでは余裕で使えるなーという感じでした。
参考画像を上げれなくて申し訳ないです。
Chromeで日本語変換中の文字色が変わる時の対処
Chromeアップデートしたら日本語変換中に文字が消えてしまい、調査した結果。
Chromeのバージョン36から変換中の文字に、選択時の文字色CSSが反映されるようになったみたいです。
つまり日本語変換中に文字色が変わる場合は::selectionでcolorなどを弄ってるはずなので、そこを削除すればなおります。
::selection { background-color: #999; color: #fff; } ::-moz-selection { background-color: #999; color: #fff; }
僕はこんな感じで指定していたので変換中は文字色が白になってしまい、あたかも消えたようになって見えたのでした。
::selection { background-color: #999; } ::-moz-selection { background-color: #999; }
こうすることで直りました。
が、テキスト選択中の色が普通のままなので見づらくなりました。対策方法は見当たりません。
変換中の文字に選択中のCSSを当てるのはいいとして、何故文字色だけにしたんでしょう。
日本語ドメインからfile_get_contentsを使ってHTMLを取得する
file_get_contentsって日本語ドメインに対応してないので、
$url = 'http://日本語.jp/'; $html = file_get_contents($url); echo $html;
とかやろうとすると
PHP Warning: file_get_contents(http://日本語.jp/): failed to open stream: php_network_getaddresses: getaddrinfo failed: nodename nor servname provided, or not known in nihongo_domain.php on line 2
とか出て怒られます。
punycode
日本語ドメインってpunycodeという、普通のURLと同じような半角英数で出来たURLに変換されるようです。
日本語.jpだと
http://xn--wgv71a119e.jp/
というURLに変換されます。
このURLならfile_get_contentsでも取得できそうです。
日本語ドメインをpunycodeに変換する
PHP標準ライブラリでは変換出来ないのでPEARのライブラリを使います。
sudo pear channel-update pear.php.net
sudo pear install Net_IDNA2-0.1.1
PHPで日本語ドメインを扱う方法(Punycode変換)
ここを参考にしてやってたんですが、
Non-static method NET_IDNA2::getInstance() should not be called statically.
ってエラーが出たのでちょっと変えてこうします
require_once 'Net/IDNA2.php'; $idna = new Net_IDNA2(); $idna_instance = $idna->getInstance(); $url = 'http://日本語.jp/'; $encoded_url = $idna_instance->encode($url); $html = file_get_contents($url); echo $html;