uzullaがブログ

uzullaがブログです。

新、PHPとH2OをfastCGIでつなぐ話、解決編

前回までのあらすじ

uzulla.hateblo.jp

  • PHPerもH2Oをつかって高速化したい
  • 色々やったらできたぞ!
  • でも、ちょっと設定で解らない所あるな…
  • kazuhoさん「こうやるのですよ」

https://gist.github.com/kazuho/15754c8e2b2bdc1c8cc5

最初にオチ

前回のテスト3がクリアでき、無事に本番投入が出来る状態になりまして、銅鑼パーソン総選挙サイトが、H2O+PHP7というイケてる環境にアップグレードしました!!!

https://doraperson2015.yapcasia.org/doraperson2015.yapcasia.org

是非サイトにアクセスし、光り輝くプロトコル"h2"を皆さまも是非ご確認ください!!!
(ほぼHTTP/2プロトコルを見る為だけに、証明書を新たに購入しました!!!)

最終的な設定ファイル

pid-file: /var/www/logs/h2o.pid
access-log: /var/www/logs/access.log
error-log: /var/www/logs/error.log
user: nobody

listen: 80
listen:
  port: 443
  ssl:
    certificate-file: /var/www/cert/ssl.crt
    key-file: /var/www/cert/ssl.key

file.custom-handler:
  extension: .php
  fastcgi.connect:
    host: 127.0.0.1
    port: 9000
    type: tcp

hosts:
  "doraperson2015.yapcasia.org:80":
    paths:
     /:
       redirect:
         status: 301
         url: https://doraperson2015.yapcasia.org/

  "doraperson2015.yapcasia.org:443":
    paths:
      /auth:
        file.dir: /var/www/dora-person-election/app/htdocs/auth
        redirect:
          url: /auth/index.php/
          internal: YES
          status: 307

      /:
        file.dir: /var/www/dora-person-election/app/htdocs
        redirect:
          url: /index.php/
          internal: YES
          status: 307

※ 実際の設定ファイルの全行です

見事に短いですね。これで相応の設定になっている(らしい)のは感動があります。

後、今後phpphp-fpmではなく、H2Oで管理するようになるかもしれませんが、それは後日に取っておきます。

前回のテスト3の話

続、PHPとH2OをfastCGIでつなぐ話、暗黒道 - uzullaがブログ

  • / 以下で、実ファイルが存在しないパスは /index.phpで全部処理したい
  • しかし /form 以下は /form/index.php を呼び出したい

という良くあるケースを私は上手く設定できませんでしたが、kazuhoさんからの指摘通りに修正し、

      /form:
        file.dir: /var/www/app/htdocs/form
        redirect:
          url: /form/index.php/
          internal: YES
          status: 307

こうすればちゃんとうごきました。file.dirがそうなるのか〜という感じがあります。

kazuhoさん指摘大変ありがとうございました。

SSL設定で一瞬つまった所

nginxもそうなんですが、証明書ファイル(.crt)はCAやIntermediateを結合したものにする必要があります。Apacheに慣れた諸氏におきましては、「SSLCACertificateFile」で別のファイルに指定するでしょうが、H2Oでは、証明書の1ファイルのなかに同梱する必要があります(後述)


とりあえず設定を書いて`h2o -m test`でテストすると、初心者には多少解りづらいエラーメッセージが出ますので、一応ここに記載しておきます。

[OCSP Stapling] testing for certificate file:/var/www/cert/ssl.crt
fetch-ocsp-response (using OpenSSL 1.0.1f 6 Jan 2014)
--issuer option was not used, and failed to extract issuer certificate from the certificate
[/var/www/h2o.conf:10] in command listen, [OCSP Stapling] does not work, will be disabled for file:/var/www/cert/ssl.crt

これは、証明書のチェインがつながっていません。多分認証局が発行したcrtファイルをそのまま指定しています。caの証明書(やIntermediateの証明書)を、証明書の「後」に追記しましょう

つまり`cat 「証明書」 「ca証明書」 「Intermediate証明書」 > ssl.crt` みたいなかんじです。*1


あるいは、こういうエラーがでるかもしれません。

[/var/www/h2o.conf:11] in command listen, failed to load private key file:/var/www/cert/ssl.key

140246669301760:error:0B080074:x509 certificate routines:X509_check_private_key:key values mismatch:x509/x509_cmp.c:355:

証明書と、暗号鍵が一致してないわけですが、証明書をとりまちがえていなければ、前述のコピペの順序が間違ってるんでしょう(実際俺は間違えたのでこの文章を書いている)。

残作業

実際に運用していくには、h2oをあげたり下げたり再起動したりする必要があります。

Quick Start - Configure - H2O - the optimized HTTP/2 server

こんな感じで起動して、
% sudo h2o -m daemon -c /path/to/the/configuration-file

こんな感じで終了せよ
% sudo kill -TERM `cat /path/to/the/pid-file`

と、ドキュメントにはあります。HUPを送ればリロードもされるようです(別途testはしましょう)。


環境にもよりますが、sysvスタイルのinitスクリプトとか、upstartとかのタレが今後必要になりますね(まだ書いて無い)。

ちなみに、`-m daemon`とするとh2oが自前で動くのではなく、裏ではstart_server(Server::Starter)スクリプトが、固定パスにあることを前提に呼び出されます。
(だもんで、横着してmake installまでやらないと、h2o -m daemonはつかえない)

ここら辺は、なかなか他のhttpdとはスタイルが違う感じですね。

*2


あとは

  • せっかくHTTP/2なんですから、Prefetchとかさせてみたい(まだやってない)。
  • PHPのプロセス管理もH2Oにまかせるのよさそう(そのうち試す)。
  • 前回のテスト2も、やろうとおもえばできそかも(そのうち試す)。

という感じでしょうか。

まとめ

H2O+PHP7を本番に投入したぞー!だがPHPerの戦いはこれからだ!

こちらからは以上です。

*1:1つのファイルの中に、順番にコピペしていけ、ということです

*2:Apacheやnginxとはかなり異なる、日本的現場のスタイル感を感じる。pstreeみてるとへーーってなるけど、start_serverへの引数はどうやって生成されてるんだ?他のマネージャと差し替えたりとかはないのだろうか。ホットデプロイをこれで実現してる事を考えると、基本server_starterだけなのかな