Apacheのモジュールでコンテンツの帯域制限をかける

Apache 2.xでコンテンツの転送速度制限をかける方法のメモです。共用レンタルサーバや従量課金の AWS などを使っていてサイトの転送量を抑えたい場合など使えると思います。

mod_bw モジュール導入

リポジトリを指定し yum でインストールします。

yum --enablerepo=epel install mod_bw

設定ファイルのバックアップを取り、設定ファイルの設定を行います。

mv /etc/httpd/conf.d/mod_bw.conf /etc/httpd/conf.d/mod_bw.conf.orig
vi /etc/httpd/conf.d/mod_bw.conf

同じクライアントからのアクセスを2Mbps(256kbytes/s)に制限する場合の mod_bw.conf の内容です。BandWidth は転送可能な秒間バイト数です。


  
    LoadModule bw_module    extramodules/mod_bw.so
  



  BandWidthModule On
  ForceBandWidthModule On
  BandWidth all 256000

128bytes 以上の .flv と .avi ファイルに対して2Mbps(256kbytes/s)に制限する場合の例です。LoadModule は省略。


  BandWidthModule On
  ForceBandWidthModule On
  BandWidth all 256000
  LargeFileLimit .flv 128 256000
  LargeFileLimit .avi 128 256000

設定が終了したらサーバを再起動します。

/etc/init.d/httpd restart

帯域制限がかかっていることを確認

ab コマンドなどでコンテンツの転送速度が制限なされていること、Apache のエラーログにエラーが出ないことを確認します。

ab -n 1 -c 1 http://example.com/hoge.flv

シェルからCakePHPを使うとAPC書き込みに失敗する問題

ウェブからアプリケーションにアクセスしてAPCを使うと普通に使えるのに、
コマンドラインから cake すると何故か使えなくて困っていました。

解決したので方法をメモしておきます。

環境

  • MAMP 2.1.3
  • PHP 5.4.10
  • CakePHP 2.4.0

事象

PHPUnitでテストしようと思ったらこんなエラーが出ていました。

$ ./lib/Cake/Console/cake test core AllTests
PHP Warning:  _cake_core_ cache was unable to write 'cake_dev_eng' to Apc cache in /var/www/line_street/lib/Cake/Cache/Cache.php on line 325
PHP Warning:  _cake_core_ cache was unable to write 'cake_console_eng' to Apc cache in /var/www/line_street/lib/Cake/Cache/Cache.php on line 325
Warning Error: include(PHPUnit/Autoload.php): failed to open stream: No such file or directory in [/var/www/line_street/lib/Cake/TestSuite/CakeTestSuiteDispatcher.php, line 150]

2013-11-24 15:36:39 Warning: include(PHPUnit/Autoload.php): failed to open stream: No such file or directory in [/var/www/line_street/lib/Cake/TestSuite/CakeTestSuiteDispatcher.php, line 150]
Warning Error: include(): Failed opening 'PHPUnit/Autoload.php' for inclusion (include_path='.:/usr/local/lib/php') in [/var/www/line_street/lib/Cake/TestSuite/CakeTestSuiteDispatcher.php, line 150]

2013-11-24 15:36:39 Warning: include(): Failed opening 'PHPUnit/Autoload.php' for inclusion (include_path='.:/usr/local/lib/php') in [/var/www/line_street/lib/Cake/TestSuite/CakeTestSuiteDispatcher.php, line 150]
Error: Please install PHPUnit framework (http://www.phpunit.de)
#0 /var/www/line_street/lib/Cake/Console/ShellDispatcher.php(208): TestShell->initialize()
#1 /var/www/line_street/lib/Cake/Console/ShellDispatcher.php(68): ShellDispatcher->dispatch()
#2 /var/www/line_street/lib/Cake/Console/cake.php(51): ShellDispatcher::run(Array)
#3 {main}
Warning Error: _cake_core_ cache was unable to write 'file_map' to Apc cache in [/var/www/line_street/lib/Cake/Cache/Cache.php, line 325]

2013-11-24 15:36:39 Warning: _cake_core_ cache was unable to write 'file_map' to Apc cache in [/var/www/line_street/lib/Cake/Cache/Cache.php, line 325]

ここで言われていることは二つ。

APC の書き込みが出来ないということと、PHPUnit をインストールしてくださいということです。

コマンドラインからの APC 有効化

app/Config/core.php のキャッシュエンジン設定はこうなってます。

$engine = 'Apc';

一応 php のパスを確認。

$ which php
/Applications/MAMP/bin/php/php5.4.10/bin/php

ちゃんと MAMP の PHP を読み込んでいるので大丈夫そうです。

次に apc_sma_info を実行してみて APC の動作確認。
今回は直接 php コマンドの -r オプションで実行して確認してみます。

$ /Applications/MAMP/bin/php/php5.4.10/bin/php -r 'var_dump(apc_sma_info());'
Warning: apc_sma_info(): No APC SMA info available.  Perhaps APC is disabled via apc.enabled? in Command line code on line 1

Call Stack:
    0.0005     226808   1. {main}() Command line code:0
    0.0005     227416   2. apc_sma_info() Command line code:1

bool(false)

false が返ってきていて、APC が無効だと言われています。
「php.ini の apc.enabled が有効になっていますか」という旨のことを言われているので確認します。

$ php -r 'phpinfo();' | grep apc.enable
apc.enable_cli => Off => Off
apc.enabled => On => On

apc.enabled はちゃんと有効でしたが、apc.enable_cliが無効になっています。
apc.enable_cli が無効だと、コマンドラインから APC を利用することが出来ません。

php.ini を編集します。

$ vi /Applications/MAMP/bin/php/php5.4.10/conf/php.ini

一番下に以下の設定を追記しました。

apc.enable_cli = 1

Apache を再起動して再度確認します。

$ php -r 'phpinfo();' | grep apc.enable
apc.enable_cli => On => On
apc.enabled => On => On

有効になりました!

PHPUnit のインストール

ついでにさっき怒られていた PHPUnit がインストールされていない件も対応します。

pear コマンドで PHPUnit のインストール先を確認しておきます。

$ /Applications/MAMP/bin/php/php5.4.10/bin/pear config-get php_dir
/Applications/MAMP/bin/php/php5.4.10/lib/php

インストールします。

$ /Applications/MAMP/bin/php/php5.4.10/lib/php upgrade-all
$ /Applications/MAMP/bin/php/php5.4.10/lib/php config-set auto_discover 1
$ /Applications/MAMP/bin/php/php5.4.10/lib/php install pear.phpunit.de/PHPUnit

エラーが出なければ OK です。
これで無事に CakePHP で PHPUnit が使えるようになりました。
今回は MAMP 環境でしたが、XAMPP でも似たような感じだと思います。

参考ドキュメント

【Android】現在のActivityスタックの状態を確認したい

Androidアプリ開発をしていると、現在のActivityスタック(画面の重なり)を確認したくなることありませんか。

Androidは画面を開いていくとスタック方式でどんどん上に画面が重なっていき、バックキーを押すと上から順に画面が破棄されていく仕組みになっています。

実際に複雑な画面遷移を実現してみようと試行錯誤していると今のActivityスタックの状態が分からなくなったりします。そんな時は取りあえずコマンドラインの adbコマンドで現在の Task と Activity スタックの状態をダンプしてみるといいと思います。

USBで端末を繋いで以下のコマンドを叩くとダンプできます。

adb shell dumpsys activity

ただ、このコマンドは出力される情報量が膨大です。そこで、上記コマンドの結果に対して更にgrepをかけて、起動しているタスクとアクティビティの一覧だけ表示されるようフィルタリングすると見やすくなります!コマンド例は以下です。最近多用しているコマンドの一つです:)

adb shell dumpsys activity | grep -B 1 "Run #[0-9]*:"

標準のマップアプリを起動して上記コマンドを実行したときの結果はこんな感じになります。

TaskRecord{42466fe0 #7 A com.google.android.apps.maps U 0}
 Run #6: ActivityRecord{4238bb10 u0 com.google.android.apps.maps/com.google.android.maps.MapsActivity}
TaskRecord{42954380 #8 A com.android.systemui U 0}
 Run #5: ActivityRecord{42953138 u0 com.android.systemui/.recent.RecentsActivity}
TaskRecord{424a50d8 #2 A com.android.launcher U 0}
 Run #4: ActivityRecord{424a32b0 u0 com.android.launcher/com.android.launcher2.Launcher}
TaskRecord{425c3758 #6 A com.google.android.gm U 0}
 Run #3: ActivityRecord{42598ed0 u0 com.google.android.gm/.ConversationListActivityGmail}
TaskRecord{423acbd8 #5 A com.google.android.youtube U 0}
 Run #2: ActivityRecord{42350d90 u0 com.google.android.youtube/.app.honeycomb.phone.HomeActivity}
TaskRecord{4254bc50 #4 A com.android.chrome U 0}
 Run #1: ActivityRecord{423e3720 u0 com.android.chrome/com.google.android.apps.chrome.Main}
TaskRecord{42354ec8 #3 A com.android.settings U 0}
 Run #0: ActivityRecord{423b2af0 u0 com.android.settings/.Settings}

上に表示されている Activity が最近開いた画面です。

アクティビティはタスクに属しますが、上記の出力結果は TaskRecord #7 に対して ActivityRecord #6 MapsActivity(GoogleMap) が所属していることを表しています。