-->

2013-08-03

PORTDIR_OVERLAYの追加 part3

http://pecl.php.net/package/event
http://jp1.php.net/manual/ja/book.event.php
http://devmanual.gentoo.org/eclass-reference/confutils.eclass/index.html

rootで作業はしません。"NOPASSWD:"無しのほうが安全です。この例は利便性を重視しています。
$ sudo visudo

$ /usr/bin/sudo /usr/bin/rcsdiff -r1.1 /etc/config-archive/etc/sudoers,v /etc/sudoers
===================================================================
RCS file: /etc/config-archive/etc/sudoers,v
retrieving revision 1.1
diff -r1.1 /etc/sudoers
78c78
< # %wheel ALL=(ALL) NOPASSWD: ALL
---
> %wheel ALL=(ALL) NOPASSWD: ALL

$ sudo usermod -a -G wheel username

make.confに設定します。
$ grep /usr/local/portage/test /etc/portage/make.conf
PORTDIR_OVERLAY="${PORTDIR_OVERLAY} /usr/local/portage/test"

参考にするebuildファイルを修正します。
$ cd /usr/local/portage/test/
$ sudo mkdir dev-php/
$ cd dev-php/
$ sudo cp -ri /usr/portage/dev-php/pecl-libevent/ .
$ sudo mv -i pecl-libevent/ pecl-event/
$ sudo chown -R owner.group pecl-event/
$ cd pecl-event/
$ cp -i pecl-libevent-0.1.0.ebuild pecl-event-1.7.2.ebuild
$ rm -i pecl-libevent-0.*

ファイルをダウンロードします。
$ cd /tmp/
$ wget http://pecl.php.net/get/event-1.7.2.tgz
$ sudo cp -i /tmp/event-1.7.2.tgz /usr/portage/distfiles/event-1.7.2.tgz
$ cd /usr/local/portage/test/dev-php/pecl-event/

ebuildファイルを修正します。
$ emacs pecl-event-1.7.2.ebuild

それっぽくなるまでマニュアルを読みます。
$ diff /usr/portage/dev-php/pecl-libevent/pecl-libevent-0.1.0.ebuild pecl-event-1.7.2.ebuild | htmlescape
6c6
< PHP_EXT_NAME="libevent"
---
> PHP_EXT_NAME="event"
11c11
< inherit php-ext-pecl-r2
---
> inherit php-ext-pecl-r2 confutils eutils
15,16c15,16
< DESCRIPTION="PHP wrapper for libevent"
< LICENSE="PHP-3"
---
> DESCRIPTION="Provides interface to libevent library"
> LICENSE="PHP-3.01"
18d17
< IUSE=""
20c19,34
< DEPEND=">=dev-libs/libevent-1.4.0"
---
> # --with-event-core        Include core libevent support
> # --with-event-pthreads    Include libevent's pthreads library and enable thread safety support in event
> # --with-event-extra       Include libevent protocol-specific functionality support including HTTP, DNS, and RPC
> # --with-event-openssl Include libevent OpenSSL support
> # --with-openssl-dir=DIR  Event: openssl installation prefix
> # --with-event-libevent-dir=DIR Event: libevent installation prefix
> # --enable-event-debug     Enable debug support in event
>
> # http://devmanual.gentoo.org/eclass-reference/confutils.eclass/index.html
>
> IUSE="+pecl_event_core +pecl_event_pthreads +pecl_event_extra +pecl_event_openssl pecl_event_debug examples"
>
> DEPEND="
>    >=dev-libs/libevent-1.4.0
>    pecl_event_openssl? ( >=dev-libs/openssl-0.9.7 )
> "
21a36,45
>
> src_configure() {
>    enable_extension_with "event-core" "pecl_event_core" 0
>    enable_extension_with "event-pthreads" "pecl_event_pthreads" 0
>    enable_extension_with "event-extra" "pecl_event_extra" 0
>    enable_extension_with "event-openssl" "pecl_event_openssl" 0
>    enable_extension_enable "event-debug" "pecl_event_debug" 0
>
>    php-ext-source-r2_src_configure
> }

Manifestを更新します。
$ ebuild pecl-event-1.7.2.ebuild manifest

インストールに挑戦します。
$ sudo ACCEPT_KEYWORDS="~*" USE="examples" emerge --oneshot -avt pecl-event

These are the packages that would be merged, in reverse order:

Calculating dependencies... done!
[ebuild  N     ] dev-php/pecl-event-1.7.2::x-test  USE="examples pecl_event_core pecl_event_extra pecl_event_openssl pecl_event_pthreads -pecl_event_debug" PHP_TARGETS="php5-4 -php5-3" 0 kB

Total: 1 package (1 new), Size of downloads: 0 kB

Would you like to merge these packages? [Yes/No]

それっぽいか確認します。
...
 *   Disabling event-debug
 * econf: updating php5.4/config.sub with /usr/share/gnuconfig/config.sub
 * econf: updating php5.4/config.guess with /usr/share/gnuconfig/config.guess
./configure --prefix=/usr --build=x86_64-pc-linux-gnu --host=x86_64-pc-linux-gnu --mandir=/usr/share/man --infodir=/usr/share/info --datadir=/usr/share --sysconfdir=/etc --localstatedir=/var/lib --libdir=/usr/lib64 --with-php-config=/usr/lib64/php5.4/bin/php-config --with-event-core --with-event-pthreads --with-event-extra --with-event-openssl --disable-event-debug
configure: loading site script /usr/share/config.site
checking for grep that handles long lines and -e... /bin/grep
checking for egrep... /bin/grep -E
...

インストールされたファイルを確認します。
$ qlist pecl-event
/etc/php/apache2-php5.4/ext/event.ini
/etc/php/apache2-php5.4/ext-active/event.ini
/etc/php/cli-php5.4/ext/event.ini
/etc/php/cli-php5.4/ext-active/event.ini
/etc/php/fpm-php5.4/ext/event.ini
/etc/php/fpm-php5.4/ext-active/event.ini
/etc/php/cgi-php5.4/ext/event.ini
/etc/php/cgi-php5.4/ext-active/event.ini
/usr/share/doc/dev-php/pecl-event-1.7.2/examples/fibonacci_buffer.php.bz2
/usr/share/doc/dev-php/pecl-event-1.7.2/examples/httpv0client2.php.bz2
/usr/share/doc/dev-php/pecl-event-1.7.2/examples/timer.php.bz2
/usr/share/doc/dev-php/pecl-event-1.7.2/examples/http_accept.php.bz2
/usr/share/doc/dev-php/pecl-event-1.7.2/examples/uppercase_proxy.php.bz2
/usr/share/doc/dev-php/pecl-event-1.7.2/examples/listener.php.bz2
/usr/share/doc/dev-php/pecl-event-1.7.2/examples/httpv0client.php.bz2
/usr/share/doc/dev-php/pecl-event-1.7.2/examples/misc.php.bz2
/usr/share/doc/dev-php/pecl-event-1.7.2/examples/http_request.php.bz2
/usr/share/doc/dev-php/pecl-event-1.7.2/examples/http_alias.php.bz2
/usr/share/doc/dev-php/pecl-event-1.7.2/examples/eio.php.bz2
/usr/share/doc/dev-php/pecl-event-1.7.2/examples/signal.php.bz2
/usr/share/doc/dev-php/pecl-event-1.7.2/examples/ssl-echo-server/client.php.bz2
/usr/share/doc/dev-php/pecl-event-1.7.2/examples/ssl-echo-server/server.php.bz2
/usr/share/doc/dev-php/pecl-event-1.7.2/examples/http.php.bz2
/usr/share/doc/dev-php/pecl-event-1.7.2/examples/http_bind.php.bz2
/usr/share/doc/dev-php/pecl-event-1.7.2/examples/buffer_proxy.php.bz2
/usr/share/doc/pecl-event-1.7.2/package.xml.bz2
/usr/share/doc/pecl-event-1.7.2/CREDITS.bz2
/usr/lib64/php5.4/lib/extensions/no-debug-non-zts-20100525/event.so

eixのキャッシュを更新します。
$ sudo eix-update
$ eix pecl-event
[D] dev-php/pecl-event [1]
     Available versions:  ~1.7.2 {examples +pecl_event_core pecl_event_debug +pecl_event_extra +pecl_event_openssl +pecl_event_pthreads PHP_TARGETS="php5-3 php5-4"}
     Installed versions:  1.7.2[?](02時07分43秒 2013年08月03日)(examples pecl_event_core pecl_event_extra pecl_event_openssl pecl_event_pthreads -pecl_event_debug PHP_TARGETS="php5-4 -php5-3")
     Homepage:            http://pecl.php.net/event
     Description:         Provides interface to libevent library

[1] /usr/local/portage/test

ソースから入れればいいじゃんとか思ったりします。
例えば下記のような手間が減りますし、オプションとか変更しての再インストールが楽になった気がします。
$ rm -i aclocal.m4
$ autoreconf -ifv

stripもしています。
$ file /tmp/event-1.7.2/modules/event.so
/tmp/event-1.7.2/modules/event.so: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, not stripped
$ file /usr/lib64/php5.4/lib/extensions/no-debug-non-zts-20100525/event.so
/usr/lib64/php5.4/lib/extensions/no-debug-non-zts-20100525/event.so: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, stripped

このように手動で入れるより便利になっている気がします。
もしくはxstowなどでも良いかと思います。
自分用であれば多少いい加減でも問題ないと思います。

インストールしたエクステンションをテストします。
$ bzcat /usr/share/doc/dev-php/pecl-event-1.7.2/examples/http.php.bz2 > http.php
$ php http.php

$ nc -t 127.0.0.1 8010
POST /about HTTP/1.0
Content-Type: text/plain
Content-Length: 4
Connection: close

a=12
HTTP/1.0 200 OK
Content-Type: text/html; charset=ISO-8859-1
Connection: close

_http_about
URI: /about

 >> Sending reply ...OK

$ nc -t 127.0.0.1 8010
GET /dump HTTP/1.0
Content-Type: text/plain
Content-Encoding: UTF-8
Connection: close

HTTP/1.0 200 OK
Content-Type: text/html; charset=ISO-8859-1
Connection: close

_http_dump called
request:object(EventHttpRequest)#4 (0) {
}
data:array(2) {
  [0]=>
  int(4)
  [1]=>
  int(8)
}

===== DUMP =====
Command:1
URI:/dump
Input headers:array(3) {
  ["Content-Type"]=>
  string(10) "text/plain"
  ["Content-Encoding"]=>
  string(5) "UTF-8"
  ["Connection"]=>
  string(5) "close"
}
Output headers:array(0) {
}

 >> Sending reply ...OK

 >> Reading input buffer ...
No more data in the buffer

$ nc -t 127.0.0.1 8010
GET /unknown HTTP/1.0
Connection: close

HTTP/1.0 200 OK
Content-Type: text/html; charset=ISO-8859-1
Connection: close

_http_default
URI: /unknown

 >> Sending reply ...OK

$ ab -n 2 -c 1 "http://127.0.0.1:8010/dump"

_http_dump called
request:object(EventHttpRequest)#3 (0) {
}
data:array(2) {
  [0]=>
  int(4)
  [1]=>
  int(8)
}

===== DUMP =====
Command:1
URI:/dump
Input headers:array(3) {
  ["Host"]=>
  string(14) "127.0.0.1:8010"
  ["User-Agent"]=>
  string(15) "ApacheBench/2.3"
  ["Accept"]=>
  string(3) "*/*"
}
Output headers:array(0) {
}

 >> Sending reply ...OK

 >> Reading input buffer ...
No more data in the buffer
Counter reached max requests 2. Exiting

負荷テストします。
$ php http.php > /dev/null

$ ps -eo %cpu,%mem,vsz,rss,stat,command|grep -P \[h\]ttp\\.php\|\[h\]ttp://127.0.0.1:8010/; echo "==="; vmstat; echo "==="; free; echo "==="; cat /proc/loadavg; time (((ab -n 3000000 -c 3000 "http://127.0.0.1:8010/" > /tmp/ab.log 2>&1 && killall watch) &) && watch -n1 "ps -eo %cpu,%mem,vsz,rss,stat,command|grep -P \[h\]ttp\\.php\|\[h\]ttp://127.0.0.1:8010/; echo "==="; vmstat; echo "==="; free; echo "==="; cat /proc/loadavg"); for cnt in $(seq 1 3); do ps -eo %cpu,%mem,vsz,rss,stat,command|grep -P \[h\]ttp\\.php\|\[h\]ttp://127.0.0.1:8010/; echo "==="; vmstat; echo "==="; free; echo "==="; cat /proc/loadavg; echo "### sleep 1"; sleep 1; done


### 実行直前
 0.0  0.1 101396  8716 S+   php http.php
===
procs -----------memory---------- ---swap-- -----io---- -system-- ----cpu----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa
 2  0      0 5098616 410800 1910992    0    0     3    11  114   82  2  2 96  0
===
             total       used       free     shared    buffers     cached
Mem:       8170124    3071508    5098616          0     410800    1910992
-/+ buffers/cache:     749716    7420408
Swap:       131068          0     131068
===
0.89 1.03 1.12 1/128 1891


### 終了直後
Every 1.0s: ps -eo %cpu,%mem,vsz,rss,stat,command|grep -P \[h\]ttp\.php\|\[h\]ttp://127.0.0.1:8010/; echo ===; vm...  Sat Aug  3 14:24:05 2013

81.0  0.1 108520 16028 S+   php http.php
99.4  1.9 259668 161992 R+  ab -n 3000000 -c 3000 http://127.0.0.1:8010/
===
procs -----------memory---------- ---swap-- -----io---- -system-- ----cpu----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa
 1  0      0 4910780 411116 1911016    0    0     3    11  120   91  2  2 96  0
===
             total       used       free     shared    buffers     cached
Mem:       8170124    3261328    4908796          0     411116    1911016
-/+ buffers/cache:     939196    7230928
Swap:       131068          0     131068
===
1.87 1.53 1.31 2/134 3653


### 終了直後~3秒後まで
real    4m9.695s
user    0m0.607s
sys     0m1.062s
80.7  0.1 107836 15472 S+   php http.php
===
procs -----------memory---------- ---swap-- -----io---- -system-- ----cpu----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa
 2  0      0 5090652 411116 1911016    0    0     3    11  120   91  2  2 96  0
===
             total       used       free     shared    buffers     cached
Mem:       8170124    3079472    5090652          0     411116    1911016
-/+ buffers/cache:     757340    7412784
Swap:       131068          0     131068
===
1.87 1.53 1.31 1/128 3660
### sleep 1
80.4  0.1 107836 15472 S+   php http.php
===
procs -----------memory---------- ---swap-- -----io---- -system-- ----cpu----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa
 1  0      0 5090924 411116 1911016    0    0     3    11  120   91  2  2 96  0
===
             total       used       free     shared    buffers     cached
Mem:       8170124    3079084    5091040          0     411116    1911016
-/+ buffers/cache:     756952    7413172
Swap:       131068          0     131068
===
1.87 1.53 1.31 1/128 3666
### sleep 1
80.1  0.1 107836 15472 S+   php http.php
===
procs -----------memory---------- ---swap-- -----io---- -system-- ----cpu----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa
 1  0      0 5091172 411116 1911016    0    0     3    11  120   91  2  2 96  0
===
             total       used       free     shared    buffers     cached
Mem:       8170124    3078836    5091288          0     411116    1911016
-/+ buffers/cache:     756704    7413420
Swap:       131068          0     131068
===
1.72 1.51 1.30 1/128 3672
### sleep 1

abの出力。
$ cat /tmp/ab.log
This is ApacheBench, Version 2.3 <$Revision: 655654 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking 127.0.0.1 (be patient)
Completed 300000 requests
Completed 600000 requests
Completed 900000 requests
Completed 1200000 requests
Completed 1500000 requests
Completed 1800000 requests
Completed 2100000 requests
Completed 2400000 requests
Completed 2700000 requests
Completed 3000000 requests
Finished 3000000 requests


Server Software:
Server Hostname:        127.0.0.1
Server Port:            8010

Document Path:          /
Document Length:        0 bytes

Concurrency Level:      3000
Time taken for tests:   246.588 seconds
Complete requests:      3000000
Failed requests:        0
Write errors:           0
Total transferred:      192019520 bytes
HTML transferred:       0 bytes
Requests per second:    12166.05 [#/sec] (mean)
Time per request:       246.588 [ms] (mean)
Time per request:       0.082 [ms] (mean, across all concurrent requests)
Transfer rate:          760.46 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0  167 336.8     68    7092
Processing:    16   80  19.7     79    1466
Waiting:       12   61  18.4     60    1453
Total:         26  246 337.1    146    7171

Percentage of the requests served within a certain time (ms)
  50%    146
  66%    151
  75%    154
  80%    156
  90%    167
  95%   1144
  98%   1153
  99%   1157
 100%   7171 (longest request)

"http://127.0.0.1:8010/" => "http://127.0.0.1:8010/about" へ変更。
$ time ab -n 3000000 -c 3000 "http://127.0.0.1:8010/about" 2>&1
This is ApacheBench, Version 2.3 <$Revision: 655654 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking 127.0.0.1 (be patient)
Completed 300000 requests
apr_socket_recv: Connection reset by peer (104)
Total of 419630 requests completed

real    0m35.768s
user    0m8.857s
sys     0m26.726s

$ php http.php > /dev/null
PHP Fatal error:  Allowed memory size of 134217728 bytes exhausted (tried to allocate 72 bytes) in /tmp/http.php on line 81

setCallbackに登録して, "_http_dump", "_http_about", "_http_400" を呼ぶ場合がダメなようです。
...
function _http_default($req, $data) {
    switch ($req->getUri())
    {
    case "/dump-001":
        return _http_dump($req, $data);
    case "/about-001":
        return _http_about($req, $data);
    case "/err400-001":
        return _http_400($req, $data);
    case "/phpinfo-001":
        return _http_phpinfo($req, $data);
    }
    echo __METHOD__, PHP_EOL;
...

emergeはコンパイルしているのでオプションが不適切かもしれません。
$ grep ^C /etc/portage/make.conf
CHOST="x86_64-pc-linux-gnu"
CFLAGS="-march=native -O2"
CXXFLAGS="${CFLAGS}"

完走しました。
$ time ab -n 3000000 -c 3000 "http://127.0.0.1:8010/about-001" 2>&1
This is ApacheBench, Version 2.3 <$Revision: 655654 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking 127.0.0.1 (be patient)
Completed 300000 requests
Completed 600000 requests
Completed 900000 requests
Completed 1200000 requests
Completed 1500000 requests
Completed 1800000 requests
Completed 2100000 requests
Completed 2400000 requests
Completed 2700000 requests
Completed 3000000 requests
Finished 3000000 requests


Server Software:
Server Hostname:        127.0.0.1
Server Port:            8010

Document Path:          /about-001
Document Length:        0 bytes

Concurrency Level:      3000
Time taken for tests:   247.819 seconds
Complete requests:      3000000
Failed requests:        0
Write errors:           0
Total transferred:      192029568 bytes
HTML transferred:       0 bytes
Requests per second:    12105.61 [#/sec] (mean)
Time per request:       247.819 [ms] (mean)
Time per request:       0.083 [ms] (mean, across all concurrent requests)
Transfer rate:          756.72 [Kbytes/sec] received

Connection Times (ms)
Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0  167 333.2     68    7118
Processing:    22   80  19.3     79     690
Waiting:       11   61  17.9     60     676
Total:         43  247 333.1    147    7164

Percentage of the requests served within a certain time (ms)
  50%    147
  66%    151
  75%    155
  80%    158
  90%    184
  95%   1144
  98%   1153
  99%   1159
 100%   7164 (longest request)

real    4m10.841s
user    0m57.686s
sys     3m12.013s

見た目は早いという結果になりましたが、長時間起動を続けても問題ないように作るのは大変そうです。
http://www.php.net/manual/ja/faq.installation.php#faq.installation.apache2

0 件のコメント: