PHPのpreg_matchについて
いろいろなところで利用されているpreg_matchについてはまったのでメモ。
今回はまったのはcodeigniterのクエリビルダで使われているところで、
nginxのエラーログから調査していたけど、ちゃんとした内容がみつからなかった。
・エラー内容
Warning: preg_match(): Compilation failed: regular expression is too large at offset XXXXX
なにやら最後の数字(恐らくByte)を超えるとpreg_matchが意図した動作をしないようで。
日本語情報のほとんどが「pcre.backtrack_limit」と「pcre.recursion_limit」の上限を上げると解消する、というもの。backtrackというのがどういった動作に影響する値かが良くわからなかったけど、今回の現象とは違うと思いつつ設定したけど案の定解決せず。
おそらくpcreのコンパイルオプションで「link size」という値をデフォルトの2から3以上にすると解決するのではないかというところまで調べたけど時間切れで諦めた。
そもそもで正規表現にかけてる文字数が多すぎるのが、誰が見てもイケてないという結論になったのでそこを修正した。
ということで今回のハマリで注意することは、
・フレームワークでは結構使われているので、他人事ではない。
・上記warningが出た場合、マッチするはずであろうがなかろうがreturnは「0」になる。
・warningなので処理が続行されてしまうので、条件分岐では「x==0」のようにしない。
(マッチしない場合も0、warningが出た場合も0なので意図した条件分岐にならない可能性が高い)
・使用上どうしても長い・大きい値を正規表現にかけないといけない場合はpcreをコンパイルし直す。
・pcreなのでpreg_match以外のpcre系関数でも同様の制限がかかる模様。
・特に他人が書いたコードでは要注意。
Phalcon 2 はまりどころメモ
あとで清書するよてい
phalcon1系から2になることで実装が純粋なC言語からZephirを挟んでいるようで、よく次のような事に巻き込まれる。
経験したことのあるタイミング:autoloder等で設定を読み込ませる、viewのsetvarする時
発生した事象1:「Parameter 'key' must be a string」的なエラー
発生した事象2:コンフィグ等、配列・連想配列で読み込ませた値が参照できない
原因:値を格納する際に可変変数を利用して実装しているため
可変変数使ってるの初めてみるんじゃないかって感じで理解するまで時間かかった。
連想配列の値を格納する際に、連想配列のkeyを可変変数で指定しており、そのkeyが数値だった場合、エラーがでたりkeyを指定して値が参照できなくなります。
可変変数で格納された連想配列はdumpとかすると次のような見えかたします。
(["0"] => 'aaa', ["1"] => '123')
ちょこっとしらべたところ、こういう形ではいっちゃうとforearchとかしないと中身とりだせない仕様っぽい?
実装箇所によってエラー出てくれるけど、場所によっては上記のような入りかたしちゃうこともあるので、注意。
英語できないからこっそりと修正待ち。
Dockerでredisを動かそうとしてはまった件
環境 ホストOS : CentOS6.5 Docker : 1.5
Dockerファイル(詳細は別記事)でfromをcentos6にし、yumってインストールまでは問題なく完了。
いざ起動しようと以下コマンドをうつと
/etc/init.d/redis start Starting redis-server:could not open session
となった。
起動スクリプトを調べると、どうやらrunuserがちゃんと動作していないっぽい。 PAM回りかとおもい、runuserのpamファイルをコメントアウトしてみたけど駄目。 調査時間があまりとれなかったので、とりあえず起動スクリプトを以下のようにして暫定処置した。
-runuser ~ +#runuser ~ +sudo -u redis $exec $REDIS_CONFIG --daemonize yes --pidfile $pidfile
1年前くらいに似たようなバグがあったっぽいけど再発なのかセキュリティの観点から仕様にしたのか・・・ 時間ができたら調べるかも・・・
DockerでPhalcon+mysql実行環境を構築する
dockerhubのものを使うのも味気なかったので自分でdockerfileを作ったのでメモ。
開発する際にローカルで動作確認するためのモノを想定しているので、いろんなサービス乗っけてます。
動くモノ Php5.5 phalcon1.3.4 nginx+Php-fpm mysql5.6 redis3
From centos:6 ADD conf /tmp/ RUN yum install -y epel-release && \ Rpm -Uvhp iusrepo && \ Rpm -Uvhp mysqlrepo && \ Rpm -Uvhp nginxrepo && \ Yum install -y wget vim git gcc make zip unzip re2c file zsh sudo && \ Yum install -y php55u php55u-pdo php55u-devel php55u-mbstring php55u-apcu-devel php55u-pecl-igbinary php55u-pecl-jsonc-devel php55u-pecl-memcached php55u-mysql php55u-mysqlnd php55u-pecl-redis php55u-opcache pcre-devel && \ Yum install -y mysql-community-server && \ Yum install -y nginx php55u-fpm redis30u && \ Cd /usr/local/src && \ Wget cphalcon.zip && \ Unzip phalcon-v1.3.4.zip && \ Cd cphalcon-phalcon-v1.3.4/build/ && \ ./install && \ Cd ../../ && \ Rm -rf phalcon* && \ Rm -rf cphalcon-phalcon-v1* && \ Echo 'extension=phalcon.so' >> /etc/php.d/50-phalcon.ini && \ Chmod 755 /etc/php.d/50-phalcon.ini && \ Mv /tmp/config /etc/config CMD /bin/zsh
PHPは55を56にするとPHP56系が、Phalconは1.3.4を2.0.3に変えるとPhalcon2がインストールできます。
Dockerfileとおなじディレクトリにconfディレクトリを作成し、その中にnginx等の設定ファイルを置いて、ビルドは「docker build -t phalcon/test .」でok。 恐らく1gb弱のイメージができるので 「docker run --name phalcon-testy -p 8080:80 -p 8806:3306 -v /var/www/html:/var/www/html:ro -itd phalcon/test」 のような感じでコンテナを起動すればok。
場合によってCMDをENTRYPOINTに変えて運用したりする。
VPS・PaaS・IaaS比較と所感
(2016/11/17 GCE更新)
仕事用途よりも個人でゲームサーバを立てる、という視点で調べてみた。 最重要ポイントである日本リージョンがあるサービスを軽く調べた。 secdsがギリギリ稼動しそうなインスタンスで比較してみたが、 全く同等のものは無いのでそこは似たようなモノで比較。なお、Pingは東京から発信してます。
サービス | 種類 | 費用 | Ping |
---|---|---|---|
Amazon EC2 | c3.large | $0.128 /1 時間 | 6ms |
Vultr | 2CPU 2GBMEM 45GBSSD | $0.024 /1 時間 | 4ms |
Linode | Linode 2GB | $0.03 /1 時間 | 4ms |
GoogleComputeEngine | n1-highcpu-2 | $0.069/1 時間 | 4ms |
AmazonEC2は必要なときに必要なだけスケールアップ、スケールアウトが 容易に出来るので扱いやすいが、インスタンスのプランが仕事でも微妙に噛み合わない時が多い。
Vultrはスペック・Ping共に申し分ないサービスだが、 インスタンスを停止しても料金が発生するので、止めるならインスタンス毎消し去らないといけない。 動的に複数インスタンスを運用する場合のコストは割り切りか工夫が必要となる。
Linodeはまだ利用したことないので詳細はわかってないです。
GooglwCEは日本リージョンが来ていないけどAWSの対抗なんじゃないかと思って 調べてみたら、インスタンスのプランがよさげな感じで仕事でも使えそうだと思った。
なお、追加ストレージや帯域費用は別で、上記はインスタンスのみの費用なので動画配信とか帯域を 大量に必要とするようなモノを動かす場合は月額固定費用のサービスを利用することをお勧めします。