<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>digape.com</title>
	<atom:link href="http://digape.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://digape.com</link>
	<description>開発と毎日。</description>
	<lastBuildDate>Thu, 17 May 2012 06:41:28 +0000</lastBuildDate>
	<language>ja</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<item>
		<title>[Apache] mod_rpafをApache2.4系で使う</title>
		<link>http://digape.com/201205/apache-mod_rpaf%e3%82%92apache2-4%e7%b3%bb%e3%81%a7%e4%bd%bf%e3%81%86/</link>
		<comments>http://digape.com/201205/apache-mod_rpaf%e3%82%92apache2-4%e7%b3%bb%e3%81%a7%e4%bd%bf%e3%81%86/#comments</comments>
		<pubDate>Thu, 17 May 2012 06:40:57 +0000</pubDate>
		<dc:creator>teriyakisan</dc:creator>
				<category><![CDATA[対処する]]></category>
		<category><![CDATA[Apache]]></category>
		<category><![CDATA[AWS]]></category>
		<category><![CDATA[ELB]]></category>
		<category><![CDATA[mod_rpaf]]></category>

		<guid isPermaLink="false">http://digape.com/?p=626</guid>
		<description><![CDATA[Apache2.4系では2.2系からオブジェクト構造などに一部変更があったらしく、メンテされてないモジュールなどで、コンパイルが通らないことがあります。 今回は、バランサを前においたApacheで、X-Forwarded [...]]]></description>
			<content:encoded><![CDATA[<p>Apache2.4系では<strong>2.2系からオブジェクト構造などに一部変更</strong>があったらしく、メンテされてないモジュールなどで、コンパイルが通らないことがあります。</p>
<p>今回は、バランサを前においたApacheで、X-Forwarded-Forをアクセス元ホストとして使うためのモジュール「<a title="mod_rpaf" href="http://stderr.net/apache/rpaf/" target="_blank">mod_rpaf</a>」のコンパイルをする際に問題がでました。</p>
<p>&nbsp;</p>
<p>調べてみたところ、対象モジュールは違いますが、以下で紹介されている「remote_ip」「remote_addr」の名称変更がビンゴっぽい。</p>
<p><a title="apache2.4.1リリース" href="http://t-sat7.way-nifty.com/blog/2012/02/apache241-5544.html" target="_blank"> apache2.4.1リリース<br />
</a></p>
<p>&nbsp;</p>
<p>mod_rpaf-2.0.cファイルの対象箇所を修正します（<a title="gistはこちら" href="https://gist.github.com/2716030" target="_blank">gistはこちら</a>）。</p>
<pre class="brush:diff">--- mod_rpaf-2.0.c.org  2012-05-17 12:05:34.082130109 +0900
+++ mod_rpaf-2.0.c      2012-05-17 12:16:41.648138252 +0900
@@ -147,8 +147,8 @@

 static apr_status_t rpaf_cleanup(void *data) {
     rpaf_cleanup_rec *rcr = (rpaf_cleanup_rec *)data;
-    rcr-&gt;r-&gt;connection-&gt;remote_ip   = apr_pstrdup(rcr-&gt;r-&gt;connection-&gt;pool, rcr-&gt;old_ip);
-    rcr-&gt;r-&gt;connection-&gt;remote_addr-&gt;sa.sin.sin_addr.s_addr = apr_inet_addr(rcr-&gt;r-&gt;connection-&gt;remote_ip);
+    rcr-&gt;r-&gt;connection-&gt;client_ip   = apr_pstrdup(rcr-&gt;r-&gt;connection-&gt;pool, rcr-&gt;old_ip);
+    rcr-&gt;r-&gt;connection-&gt;client_addr-&gt;sa.sin.sin_addr.s_addr = apr_inet_addr(rcr-&gt;r-&gt;connection-&gt;client_ip);
     return APR_SUCCESS;
 }

@@ -161,7 +161,7 @@
     if (!cfg-&gt;enable)
         return DECLINED;

-    if (is_in_array(r-&gt;connection-&gt;remote_ip, cfg-&gt;proxy_ips) == 1) {
+    if (is_in_array(r-&gt;connection-&gt;client_ip, cfg-&gt;proxy_ips) == 1) {
         /* check if cfg-&gt;headername is set and if it is use
            that instead of X-Forwarded-For by default */
         if (cfg-&gt;headername &amp;&amp; (fwdvalue = apr_table_get(r-&gt;headers_in, cfg-&gt;headername))) {
@@ -180,11 +180,11 @@
                 if (*fwdvalue != '\0')
                     ++fwdvalue;
             }
-            rcr-&gt;old_ip = apr_pstrdup(r-&gt;connection-&gt;pool, r-&gt;connection-&gt;remote_ip);
+            rcr-&gt;old_ip = apr_pstrdup(r-&gt;connection-&gt;pool, r-&gt;connection-&gt;client_ip);
             rcr-&gt;r = r;
             apr_pool_cleanup_register(r-&gt;pool, (void *)rcr, rpaf_cleanup, apr_pool_cleanup_null);
-            r-&gt;connection-&gt;remote_ip = apr_pstrdup(r-&gt;connection-&gt;pool, ((char **)arr-&gt;elts)[((arr-&gt;nelts)-1)]);
-            r-&gt;connection-&gt;remote_addr-&gt;sa.sin.sin_addr.s_addr = apr_inet_addr(r-&gt;connection-&gt;remote_ip);
+            r-&gt;connection-&gt;client_ip = apr_pstrdup(r-&gt;connection-&gt;pool, ((char **)arr-&gt;elts)[((arr-&gt;nelts)-1)]);
+            r-&gt;connection-&gt;client_addr-&gt;sa.sin.sin_addr.s_addr = apr_inet_addr(r-&gt;connection-&gt;client_ip);
             if (cfg-&gt;sethostname) {
                 const char *hostvalue;
                 if (hostvalue = apr_table_get(r-&gt;headers_in, "X-Forwarded-Host")) {</pre>
<p>&nbsp;</p>
<p>パッチ当て＆インストール手順をまとめるとこんな感じです。<br />
（自前環境ではapxsにパスを通してなかったので、Makefileも一部書き換えてます）</p>
<pre>wget http://stderr.net/apache/rpaf/download/mod_rpaf-0.6.tar.gz
tar xvzf mod_rpaf-0.6.tar.gz
cd mod_rpaf-0.6
vi Makefile
&gt; APXS2=$(shell which apxs2)
&gt;  ↓ ↓
&gt; #APXS2=$(shell which apxs2)
&gt; APXS2=/usr/local/apache/bin/apxs

git clone git://gist.github.com/2716030.git
patch &lt; 2716030/mod_rpaf-2.0.c.patch

make rpaf-2.0
make install-2.0</pre>
<p>&nbsp;</p>
<p>mod_rpafはバランサのIPアドレスを決め打ちでしか指定できず、<strong>ELBのようにIPが固定されないケースなどではかなりつらい仕様</strong>なので、以下のような事例を参考にコンパイル前に少し動きをいじってあげると幸せです。</p>
<p><a title="mod_rpaf の RPAFproxy_ips に 192.0.2. とか書きたい" href="http://cl.pocari.org/2011-08-04-1.html" target="_blank">mod_rpaf の RPAFproxy_ips に 192.0.2. とか書きたい</a></p>
<p>&nbsp;</p>
<p>毎回同じローカルIPがログに出力されてもうれしくないので、バランサを使う際は、これ系のモジュールを入れるかログ出力内容の書き換えは必須っぽいですね。</p>
]]></content:encoded>
			<wfw:commentRss>http://digape.com/201205/apache-mod_rpaf%e3%82%92apache2-4%e7%b3%bb%e3%81%a7%e4%bd%bf%e3%81%86/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[Apache] Apache2.4系でSSIを使う</title>
		<link>http://digape.com/201205/apache-apache2-4%e7%b3%bb%e3%81%a7ssi%e3%82%92%e4%bd%bf%e3%81%86/</link>
		<comments>http://digape.com/201205/apache-apache2-4%e7%b3%bb%e3%81%a7ssi%e3%82%92%e4%bd%bf%e3%81%86/#comments</comments>
		<pubDate>Fri, 11 May 2012 09:52:55 +0000</pubDate>
		<dc:creator>teriyakisan</dc:creator>
				<category><![CDATA[対処する]]></category>
		<category><![CDATA[Apache]]></category>
		<category><![CDATA[HTML]]></category>
		<category><![CDATA[SSI]]></category>

		<guid isPermaLink="false">http://digape.com/?p=613</guid>
		<description><![CDATA[拡張子.htmlのファイルでSSI(Server Side Include）を使いたい、というニーズはまだまだ根強いと思ってます（手軽なので）。 今回、Apache2.2系→2.4系にした際に、既存のSSIファイルが動か [...]]]></description>
			<content:encoded><![CDATA[<p>拡張子.htmlのファイルでSSI(Server Side Include）を使いたい、というニーズはまだまだ根強いと思ってます（手軽なので）。</p>
<p>今回、Apache2.2系→2.4系にした際に、既存のSSIファイルが動かなくなっていたので対処をメモ。</p>
<p>基本セットとして、以下をhttpd.confまたは設定の上書きが許可されている状態で.htaccessに記述します。<br />
&nbsp;</p>
<pre>AddType application/x-httpd-php .html
AddType text/html .html
AddHandler server-parsed .html
AddOutputFilter INCLUDES .html
Options All</pre>
<p>&nbsp;</p>
<p>その上でApache再起動してもうまくいかない！という場合は、Includeモジュールが読みこまれてない可能性があります。<br />
httpd.confで以下の記述を確認。<br />
&nbsp;</p>
<pre>LoadModule include_module modules/mod_include.so</pre>
<p>&nbsp;</p>
<p>読み込まれてなければ、コメントアウトを外してからApache再起動。<br />
これで解決するはずです。</p>
<p>2.2系のときを覚えていないのですが、少なくとも2.4系からはinclude_moduleの<strong>デフォルト設定はOFFに</strong>なってるようです。</p>
<p>バージョンアップ時はいろいろでてきますね。。</p>
]]></content:encoded>
			<wfw:commentRss>http://digape.com/201205/apache-apache2-4%e7%b3%bb%e3%81%a7ssi%e3%82%92%e4%bd%bf%e3%81%86/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[PHP] PHP5.4でpukiwikiを動かす</title>
		<link>http://digape.com/201205/php-php5-4%e3%81%a7pukiwiki%e3%82%92%e5%8b%95%e3%81%8b%e3%81%99/</link>
		<comments>http://digape.com/201205/php-php5-4%e3%81%a7pukiwiki%e3%82%92%e5%8b%95%e3%81%8b%e3%81%99/#comments</comments>
		<pubDate>Wed, 02 May 2012 11:52:16 +0000</pubDate>
		<dc:creator>teriyakisan</dc:creator>
				<category><![CDATA[対処する]]></category>
		<category><![CDATA[PHP5.4]]></category>
		<category><![CDATA[pukiwiki]]></category>

		<guid isPermaLink="false">http://digape.com/?p=581</guid>
		<description><![CDATA[日本製wikiとしてはおなじみのpukiwiki。 2006年以降公式なバージョンアップもなく、開発フリーズな状態っぽいですが、海外含めたwikiの中でも非常に使いやすいので、いまだに重宝させてもらってます。 今回は、P [...]]]></description>
			<content:encoded><![CDATA[<p>日本製wikiとしてはおなじみの<a title="pukiwiki" href="http://pukiwiki.sourceforge.jp/" target="_blank">pukiwiki</a>。</p>
<p>2006年以降公式なバージョンアップもなく、開発フリーズな状態っぽいですが、海外含めたwikiの中でも非常に使いやすいので、いまだに重宝させてもらってます。</p>
<p>今回は、PHP5.4を導入した環境で画面真っ白になってしまったので、そのときの対応をまとめてみます。</p>
<h3>とりあえず動くようにする</h3>
<p>とりあえず真っ白画面から抜けだそうということで、Fatalエラーをつぶしていきます。<br />
index.phpの10行目あたりにある以下のコメントアウトを外します。</p>
<pre>error_reporting(E_ALL); // Debug purpose</pre>
<p>その状態ででてきたFatalエラーについて対応します。<br />
Fatalが出た時点で処理は止まってしまうので、<strong>Fatalを解決→ページを確認→Fatalを解決→・・・</strong>の流れになると思います。<br />
おそらく、Warning,Notice,Deprecatedあたりもいっぱい出ると思いますが、ここでは一旦無視します。</p>
<p>&nbsp;</p>
<p>自前環境では以下の2つを対応しました。</p>
<h4>hex2bin関数をコメントアウト</h4>
<p>lib/func.php にある「hex2bin」関数が、PHP5.4からネイティブ関数化されているためコメントアウト。</p>
<pre>// Inversion of bin2hex()
/*
function hex2bin($hex_string)
{
        // preg_match : Avoid warning : pack(): Type H: illegal hex digit ...
        // (string)   : Always treat as string (not int etc). See BugTrack2/31
        return preg_match('/^[0-9a-f]+$/i', $hex_string) ?
                pack('H*', (string)$hex_string) : $hex_string;
}
*/</pre>
<h4></h4>
<h4>ls2プラグインの関数呼び出し時の参照渡しを修正</h4>
<p>plugin/ls2.inc.php で、関数呼び出し時の参照渡しがされているため、修正。</p>
<pre>array_walk($args, 'plugin_ls2_check_arg', &amp; $params);
↓
array_walk($args, 'plugin_ls2_check_arg', $params);</pre>
<p>&nbsp;</p>
<p>これでさきほどコメントアウトを外した index.php のエラー出力をもとに戻すと、とりあえずは使える状態になりました。<br />
現状は、Warning含めエラーを表示していないだけの状態で、同じようにPHP5.4対応されている以下のサイトにもあるように「<strong>date関数の設定値</strong>」「<strong>参照渡し</strong>」まわりや「<strong>クラスの継承</strong>」まわりなどで、もろもろ問題は残ってしまっている状況だと思います。<br />
（dateの設定とかはやっておいたほうがベターかもしれません）</p>
<p><a title="martianの日記： PHP5.4 と PukiWiki" href="http://slashdot.jp/journal/548548/PHP5.4-%E3%81%A8-PukiWiki" target="_blank">martianの日記： PHP5.4 と PukiWiki</a></p>
<p>&nbsp;</p>
<p>今回は、ユーザ向けに提供しているシビアな環境ではなかったので、エラー発生ベースで直していく方針にしています。<br />
クリティカルな問題がでてきてしまったら、追記していきたいと思います。</p>
<p>viva pukiwiki</p>
]]></content:encoded>
			<wfw:commentRss>http://digape.com/201205/php-php5-4%e3%81%a7pukiwiki%e3%82%92%e5%8b%95%e3%81%8b%e3%81%99/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[コマンド] wgetでBasic認証</title>
		<link>http://digape.com/201204/%e3%82%b3%e3%83%9e%e3%83%b3%e3%83%89-wget%e3%81%a7basic%e8%aa%8d%e8%a8%bc/</link>
		<comments>http://digape.com/201204/%e3%82%b3%e3%83%9e%e3%83%b3%e3%83%89-wget%e3%81%a7basic%e8%aa%8d%e8%a8%bc/#comments</comments>
		<pubDate>Wed, 25 Apr 2012 01:34:25 +0000</pubDate>
		<dc:creator>teriyakisan</dc:creator>
				<category><![CDATA[TIPS]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[コマンド]]></category>
		<category><![CDATA[認証]]></category>

		<guid isPermaLink="false">http://digape.com/?p=567</guid>
		<description><![CDATA[よく忘れるのでメモ。 wget http://example.com/ --http-user=XXXXX --http-passwd=XXXXX &#160; wgetほんと使い勝手良いです。]]></description>
			<content:encoded><![CDATA[<p>よく忘れるのでメモ。</p>
<pre>wget http://example.com/ --http-user=XXXXX --http-passwd=XXXXX</pre>
<p>&nbsp;</p>
<p>wgetほんと使い勝手良いです。</p>
]]></content:encoded>
			<wfw:commentRss>http://digape.com/201204/%e3%82%b3%e3%83%9e%e3%83%b3%e3%83%89-wget%e3%81%a7basic%e8%aa%8d%e8%a8%bc/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[DNS] digコマンドでドメインからネームサーバを確認する</title>
		<link>http://digape.com/201204/dns-dig%e3%82%b3%e3%83%9e%e3%83%b3%e3%83%89%e3%81%a7%e3%83%89%e3%83%a1%e3%82%a4%e3%83%b3%e3%81%8b%e3%82%89%e3%83%8d%e3%83%bc%e3%83%a0%e3%82%b5%e3%83%bc%e3%83%90%e3%82%92%e7%a2%ba%e8%aa%8d%e3%81%99/</link>
		<comments>http://digape.com/201204/dns-dig%e3%82%b3%e3%83%9e%e3%83%b3%e3%83%89%e3%81%a7%e3%83%89%e3%83%a1%e3%82%a4%e3%83%b3%e3%81%8b%e3%82%89%e3%83%8d%e3%83%bc%e3%83%a0%e3%82%b5%e3%83%bc%e3%83%90%e3%82%92%e7%a2%ba%e8%aa%8d%e3%81%99/#comments</comments>
		<pubDate>Wed, 18 Apr 2012 15:11:41 +0000</pubDate>
		<dc:creator>teriyakisan</dc:creator>
				<category><![CDATA[TIPS]]></category>
		<category><![CDATA[DNS]]></category>
		<category><![CDATA[Linux]]></category>

		<guid isPermaLink="false">http://digape.com/?p=539</guid>
		<description><![CDATA[ドメインやサーバの引越しなどで、DNSレコードの保持先とネームサーバを切り替える際、伝搬のタイミングが読みにくいので、変更後の設定があっているのか、やきもきすることがあります。 ネームサーバが切り替わった状態で、ドメイン [...]]]></description>
			<content:encoded><![CDATA[<p>ドメインやサーバの引越しなどで、DNSレコードの保持先とネームサーバを切り替える際、伝搬のタイミングが読みにくいので、変更後の設定があっているのか、やきもきすることがあります。</p>
<p>ネームサーバが切り替わった状態で、ドメインが正しく名前解決できていることを確認できればよいので、「<strong>今どっちのネームサーバを見ているか</strong>」が把握できればよさそうです。</p>
<p>&nbsp;</p>
<p>そんなときに使えるのが「<strong>dig</strong>」コマンドです。</p>
<p>&nbsp;</p>
<p>「hogehoge.com」というドメインを切り替える想定で、整理してみます。</p>
<h3>切り替え前</h3>
<p>切り替え前は「before1.dns.com」「before2.dns.com」というネームサーバを利用していました。<br />
このときコマンドを叩くと、「AUTHORITY SECTION」のところで現在のネームサーバの向き先が確認できます。</p>
<pre>$ dig hogehoge.com

; &lt; &lt;&gt;&gt; DiG 9.3.6-P1-RedHat-9.3.6-16.P1.el5 &lt; &lt;&gt;&gt; hogehoge.com
;; global options: printcmd
;; Got answer:
;; -&gt;&gt;HEADER&lt; &lt;- opcode: QUERY, status: NOERROR, id: 64469
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 2, ADDITIONAL: 0

;; QUESTION SECTION:
;hogehoge.com. IN A

;; ANSWER SECTION:
hogehoge.com. 5 IN A XXX.XXX.XXX.XXX

;; AUTHORITY SECTION:
hogehoge.com. 5 IN NS before1.dns.com.
hogehoge.com. 5 IN NS before2.dns.com.

;; ADDITIONAL SECTION:
before1.dns.com.          5       IN      A       XXX.XXX.XXX.XXX
before2.dns.com.          5       IN      A       XXX.XXX.XXX.XXX

;; Query time: 9 msec
;; SERVER: XXX.XXX.XXX.XXX#53(XXX.XXX.XXX.XXX)
;; WHEN: Wed Apr 18 12:11:04 2012
;; MSG SIZE rcvd: 88</pre>
<h3></h3>
<h3>切り替え実施</h3>
<p>ここで、DNSレコードとネームサーバの向き先を変更します。<br />
バリュードメインやムームードメインなど、基本的にはウェブ画面上で設定変更ができると思います。</p>
<h3></h3>
<h3>切り替え後</h3>
<p>切り替え後は「after1.dns.com」「after2.dns.com」というネームサーバを利用することになります。<br />
一定時間（経験則で数時間以内）経ってから、コマンドを叩くと、切り替え前と同じく「AUTHORITY SECTION」のところでネームサーバの向き先が変わっていることが確認できると思います。</p>
<pre>$ dig hogehoge.com

; &lt; &lt;&gt;&gt; DiG 9.3.6-P1-RedHat-9.3.6-16.P1.el5 &lt; &lt;&gt;&gt; hogehoge.com
;; global options: printcmd
;; Got answer:
;; -&gt;&gt;HEADER&lt; &lt;- opcode: QUERY, status: NOERROR, id: 64469
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 2, ADDITIONAL: 0

;; QUESTION SECTION:
;hogehoge.com. IN A

;; ANSWER SECTION:
hogehoge.com. 5 IN A XXX.XXX.XXX.XXX

;; AUTHORITY SECTION:
hogehoge.com. 5 IN NS after1.dns.com.
hogehoge.com. 5 IN NS after2.dns.com.

;; ADDITIONAL SECTION:
after1.dns.com.          5       IN      A       XXX.XXX.XXX.XXX
after2.dns.com.          5       IN      A       XXX.XXX.XXX.XXX

;; Query time: 9 msec
;; SERVER: XXX.XXX.XXX.XXX#53(XXX.XXX.XXX.XXX)
;; WHEN: Wed Apr 18 14:11:01 2012
;; MSG SIZE rcvd: 88</pre>
<p>&nbsp;</p>
<p>この状態で、「nslookup」コマンドなどを利用して、変更前と同じように名前解決ができていれば、切り替えはめでたく完了ということになるかと思います。</p>
<p>知ってる方にとっては、「当たり前！」とも言われそうですが、以前に大きなDNS切り替えをおこなったときにやきもきしたので、確認手順を整理してみました。</p>
<p>&nbsp;</p>
<p><strong>2012/04/25追記</strong><br />
こちら</p>
<pre>
dig hogehoge.com
</pre>
<p>では、name server情報が拾えない場合もあるようです。</p>
<pre>
dig hogehoge.com ns
</pre>
<p>として、明示的にname server情報を見るのが一般的なやり方のようでした。<br />
もし上記の手順でうまくいかなかった場合は、「ns」をつけて試してみてください。</p>
]]></content:encoded>
			<wfw:commentRss>http://digape.com/201204/dns-dig%e3%82%b3%e3%83%9e%e3%83%b3%e3%83%89%e3%81%a7%e3%83%89%e3%83%a1%e3%82%a4%e3%83%b3%e3%81%8b%e3%82%89%e3%83%8d%e3%83%bc%e3%83%a0%e3%82%b5%e3%83%bc%e3%83%90%e3%82%92%e7%a2%ba%e8%aa%8d%e3%81%99/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[PHP] PHP5.4 + Apache 2.4でSegmentation fault</title>
		<link>http://digape.com/201204/php-php5-4-apache-2-4%e3%81%a7segmentation-fault/</link>
		<comments>http://digape.com/201204/php-php5-4-apache-2-4%e3%81%a7segmentation-fault/#comments</comments>
		<pubDate>Mon, 16 Apr 2012 13:28:22 +0000</pubDate>
		<dc:creator>teriyakisan</dc:creator>
				<category><![CDATA[対処する]]></category>
		<category><![CDATA[Apache]]></category>
		<category><![CDATA[core]]></category>
		<category><![CDATA[PHP5.4]]></category>

		<guid isPermaLink="false">http://digape.com/?p=476</guid>
		<description><![CDATA[PHP5.4.0 + Apache2.4.1で、PHPプログラムを動かした際、数回アクセスすると500エラーが発生しているケースがちらほら。 &#160; Apacheのエラーログを確認すると、以下のようなメッセージが出 [...]]]></description>
			<content:encoded><![CDATA[<p>PHP5.4.0 + Apache2.4.1で、PHPプログラムを動かした際、数回アクセスすると500エラーが発生しているケースがちらほら。</p>
<p>&nbsp;</p>
<p>Apacheのエラーログを確認すると、以下のようなメッセージが出ていました。</p>
<pre>[Fri Apr 13 22:50:04.385611 2012] [core:notice] [pid 2499:tid 140578174879488] AH00051: child pid 3659 exit signal Segmentation fault (11)</pre>
<p>&nbsp;</p>
<p>同じページにアクセスした場合でも必ず発生するというわけではなく、いまいち規則性も見えない状況です。</p>
<p>&nbsp;</p>
<p>利用してるApacheモジュール群が怪しいんじゃないかと思い、不要そうなmoduleのLoadModuleをコメントアウトして再起動してみるも、状況はあまり変わらず。</p>
<p>そもそもApache2.4系になってデフォルトで最小限のmodule読み込みになっているので、不要なモジュールが少ない、というものありました。</p>
<p>&nbsp;</p>
<p>となると、通常のエラーログからはわからない「Segmentation fault」の根本原因を探らないとなのですが、いろいろ調べてみると、c<strong>oreファイルを吐き出してデバッグ</strong>、がセオリーのようです。</p>
<p><a href="http://d.hatena.ne.jp/sarface2012/20101027">http://d.hatena.ne.jp/sarface2012/20101027</a></p>
<p>手順を参考にさせてもらって、とにかくやってみます。</p>
<h3>coreファイルの出力制限を解除</h3>
<p>現在のcoreファイルの出力制限を確認します。</p>
<pre>$ ulimit -a | grep "core file size"</pre>
<p>値が0の場合は、制限を解除します。</p>
<pre>$ vi /etc/profile
# ulimit -S -c 0 &gt; /dev/null 2&gt;&amp;1
ulimit -c unlimited &gt; /dev/null 2&gt;&amp;1</pre>
<p>変更後は再ログインします。</p>
<p>確認して出力制限が外れていればOKです。</p>
<pre>$ ulimit -a
core file size          (blocks, -c) unlimited。</pre>
<h3>Apacheにcoreファイル出力の設定を追加</h3>
<p>httpd.confに設定を追加します。</p>
<pre>$ vi httpd.conf
CoreDumpDirectory /tmp</pre>
<p>追加後、再起動します。</p>
<pre>apachectl restart</pre>
<h3>coreファイルのデバッグ</h3>
<p>ここで、再度「Segmentation fault」を発生させます。<br />
すると、/tmp下にcoreファイルが吐かれました。</p>
<pre>$ ls -lr /tmp/core.*
core.3086</pre>
<p>coreファイルをデバッグするためにはgdbコマンドを使います（CentOSの利用環境に入っていなかったので、yumインストールしました）</p>
<pre>gdb &lt;command&gt; -c &lt;core file&gt;</pre>
<p>で利用できるということで</p>
<pre>$ gdb httpd -c /tmp/core.3086
License GPLv3+: GNU GPL version 3 or later
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-redhat-linux-gnu".
For bug reporting instructions, please see:
...
Reading symbols from /XXXXX/httpd...done.

warning: exec file is newer than core file.

  :
  略
  :

(gdb)</pre>
<p>ここで、「where」をタイプするとエラー発生箇所がでてきます。</p>
<pre>(gdb) where
#0  0x00007fdae71d14ed in read () from /XXX/libpthread.so.0
#1  0x00000000004657f7 in ap_worker_pod_check (pod=) at pod.c:57
#2  0x0000000000463154 in child_main (child_num_arg=1) at worker.c:1332
#3  0x0000000000463fb6 in make_child (s=0x1dab4c0, slot=1) at worker.c:1417
#4  0x0000000000464b57 in perform_idle_server_maintenance (_pconf=, plog=, s=) at worker.c:1618
#5  server_main_loop (_pconf=, plog=, s=) at worker.c:1739
#6  worker_run (_pconf=, plog=, s=) at worker.c:1810
#7  0x000000000042de6e in ap_run_mpm (pconf=0x1d82138, plog=0x1de5528, s=0x1dab4c0) at mpm_common.c:98
#8  0x0000000000428874 in main (argc=3, argv=0x7fff9696e8c8) at main.c:777</pre>
<p>正直わからない部分もあるのですが、</p>
<pre>#1  0x00000000004657f7 in ap_worker_pod_check (pod=) at pod.c:57</pre>
<p>あたりを見ると、workerでの実行に関係がありそうです。</p>
<p>&nbsp;</p>
<p>そこで、現在のApache環境を確認してみると</p>
<pre>$ apachectl -V | grep "Server MPM"
Server MPM:     worker</pre>
<p>workerで動いてました。</p>
<p>もともとPHPはpreforkが基本の認識でいたのですが、今回Apacheのインストール時にMPMをworkerにしてしまっていたようです。</p>
<p>Apacheを自前インストールしていて、コンパイルをやり直す必要があるため、configure時に</p>
<pre>--with-mpm=prefork</pre>
<p>をつけて、Apacheを再インストール。<br />
設定をもろもろして、起動。</p>
<p>結果、、、</p>
<p>&nbsp;</p>
<p><strong>「Segmentation fault」が発生しなくなりました！</strong></p>
<p>&nbsp;</p>
<p>調べてみたところ、PHPをworkerで動かす際はFastCGIなどを組み合わせるのが通例のようです。</p>
<p>マニュアルにも非推奨とありました。</p>
<p><a href="http://www.php.net/manual/ja/faq.installation.php#faq.installation.apache2">http://www.php.net/manual/ja/faq.installation.php#faq.installation.apache2</a></p>
<p>ただ、Apache、PHPのバージョンが古い自前環境ではworkerでも問題なく動く環境もあったので、バージョン依存のある問題かもしれません。</p>
<p>workerのほうが、待機時のメモリ利用を抑えられるなど利点も大きいと思ってますが、基本PHPはpreforkという認識はあっていたみたいです。</p>
<p>&nbsp;</p>
<p>今回は、</p>
<ul>
<li>workerが悪さをしていたと思われる（詳細な原因の判明まではできず）</li>
<li>preforkにすることで解決できた</li>
</ul>
<p>という結論になりました。</p>
<p>coreファイルのデバッグを実践できたのは収穫でしたが、コンパイル時に注意していればPHP+preforkで問題なく動いてくれて、調査もいらなかったんじゃないか・・・とも思ってしまいます。</p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://digape.com/201204/php-php5-4-apache-2-4%e3%81%a7segmentation-fault/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[PHP] TwitterのユーザアイコンURLをキャッシュする</title>
		<link>http://digape.com/201204/php-twitter%e3%81%ae%e3%83%a6%e3%83%bc%e3%82%b6%e3%82%a2%e3%82%a4%e3%82%b3%e3%83%b3url%e3%82%92%e3%82%ad%e3%83%a3%e3%83%83%e3%82%b7%e3%83%a5%e3%81%99%e3%82%8b/</link>
		<comments>http://digape.com/201204/php-twitter%e3%81%ae%e3%83%a6%e3%83%bc%e3%82%b6%e3%82%a2%e3%82%a4%e3%82%b3%e3%83%b3url%e3%82%92%e3%82%ad%e3%83%a3%e3%83%83%e3%82%b7%e3%83%a5%e3%81%99%e3%82%8b/#comments</comments>
		<pubDate>Thu, 12 Apr 2012 17:04:21 +0000</pubDate>
		<dc:creator>teriyakisan</dc:creator>
				<category><![CDATA[つくる]]></category>
		<category><![CDATA[github]]></category>
		<category><![CDATA[memcached]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Twitter]]></category>

		<guid isPermaLink="false">http://digape.com/?p=427</guid>
		<description><![CDATA[Twitterのユーザアイコンを表示するケースはよくあると思いますが、素直にAPIを使ってしまうとIPアドレス単位で150回/時APIのアクセス制限にひっかかったりして、厄介です。 また、ドキュメントを見ると、&#60;i [...]]]></description>
			<content:encoded><![CDATA[<p>Twitterのユーザアイコンを表示するケースはよくあると思いますが、素直にAPIを使ってしまうとIPアドレス単位で150回/時APIのアクセス制限にひっかかったりして、厄介です。</p>
<p>また、ドキュメントを見ると、&lt;img src=&#8221;画像APIのURL&#8221; /&gt;とかで直接リダイレクトさせて使うのはやめてね、みたいなことも書いてあって、さらに厄介です。</p>
<p><a title="https://dev.twitter.com/docs/api/1/get/users/profile_image/%3Ascreen_name" href="https://dev.twitter.com/docs/api/1/get/users/profile_image/%3Ascreen_name" target="_blank">https://dev.twitter.com/docs/api/1/get/users/profile_image/%3Ascreen_name</a></p>
<p>&nbsp;</p>
<p>そんな中で、<a title="tweetimag.es" href="http://img.tweetimag.es/" target="_blank">tweetimag.es</a>というサービスはいけていて、ユーザIDを渡せば画像が返ってくるAPIを無料で提供してくれています。</p>
<p>レスポンスも速いので、小規模なサービスや個人用途あればこのAPIを使わせてもらうのがベターだと思います。</p>
<p>&nbsp;</p>
<p>ただ、ある程度の規模やTwitterクライアントみたいなものになると、無料の外部APIに頼るのはちょっと・・・という場合がありそうです。</p>
<p>多くのサービスは裏でうまく対応しているんだと思いますが、公開されているものでいい感じのライブラリが見つからなかったので、過去に自前で対応していた時のやり方をベースにPHPのライブラリをつくってみました。</p>
<p><a title="twicon" href="https://github.com/teriyakisan/twicon" target="_blank">twicon</a></p>
<p>memcachedを使ってURLをキャッシュするようにしていて、ざっくり以下の仕様です。</p>
<ul>
<li>ユーザIDとサイズを指定して、関数を呼び出す</li>
<li>過去のキャッシュがある → そのままURLを返す</li>
<li>過去のキャッシュがない → TwitterAPIに画像URLを取得しにいき、キャッシュを保存</li>
</ul>
<p>SSLのURLも取得でき、memcachedサーバの指定、キャッシュ時間の変更、キー名のprefix変更に対応しています。</p>
<pre class="brush:php">&lt;img src="/twicon.php?id=XXXXX" alt="icon" /&gt;</pre>
<p>みたいな使い方もOKです。</p>
<p>対象ユーザIDが存在しない場合や、API接続失敗したときなどは1px×1pxの透明gifを返すので、最悪とれなくても画像取得がエラーになることはない安心仕様になってます。</p>
<p>&nbsp;</p>
<p>ちょっと気になる、という方でmemcachedサーバ用意できる方は、サンプルを参考に使ってみてもらえれば幸いです。</p>
<p>（何かおかしかったら、コメントかpull requestください）</p>
]]></content:encoded>
			<wfw:commentRss>http://digape.com/201204/php-twitter%e3%81%ae%e3%83%a6%e3%83%bc%e3%82%b6%e3%82%a2%e3%82%a4%e3%82%b3%e3%83%b3url%e3%82%92%e3%82%ad%e3%83%a3%e3%83%83%e3%82%b7%e3%83%a5%e3%81%99%e3%82%8b/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

