在Httpd部署HTTP/2的踩坑之旅 === ###### tags: `Linux` `HTTP/2` Date = 2019/04/05 起始環境:`CentOS 7`、`Httpd 2.4.6`、`PHP 7.1.28 (remi)` ## 前言 先解釋需要更新、安裝哪些軟體,以及設定。分別是`Httpd`和`php-fpm`。 #### Httpd Httpd從2.4.17版開始支援HTTP/2,而CentOS 7現時提供的只有2.4.6版,因此我採用[IUS](https://ius.io/)這個CentOS[官方介紹](https://wiki.centos.org/zh-tw/AdditionalResources/Repositories)的第三方Repo,更新到最新的2.4.38版。 #### php-fpm 一般來說,Httpd預設的 MPM 是使用`prefork`模式。 但是自從2.4.27版開始,HTTP/2功能的真實身分`mod_http2`不支援在`prefork`模式下工作,只支援另外兩種:`worker`和`event`模式,我選擇使用比較多人推薦的`event`。 而事情還沒完,我的網站有使用PHP,但Httpd內建的傳統PHP解譯器`mod_php`無法在像是`event`這樣的新式MPM上運作,所以要改用其他的解譯器,這裡我使用`php-fpm`。 *[MPM]: Multi-Processing Module 簡單圖解比較**相依性**關係(非實際API呼叫流程): ``` (更新前) httpd -> mod_mpm_prefork <- mod_php (更新後) httpd -> mod_http2 -> mod_mpm_event <- mod_proxy_fcgi -> php-fpm ``` 這是個牽一髮動全身的概念。 ## 正文 先安裝所需套件`IUS Repo`、`Httpd`、`php-fpm`: ```bash curl -s https://setup.ius.io |sh && \ yum update && yum install -y yum-plugin-replace && \ yum replace httpd --replace-with httpd24u && \ yum install -y httpd24u-mod_ssl php-fpm && \ mkdir -p /var/run/php-fpm ``` 編輯 ==/etc/httpd/conf.modules.d/00-mpm.conf== 把MPM改成用`event`,並把原本的`prefork`註解掉: ```bash # Select the MPM module which should be used by uncommenting exactly # one of the following LoadModule lines: # prefork MPM: Implements a non-threaded, pre-forking web server # See: http://httpd.apache.org/docs/2.4/mod/prefork.html #LoadModule mpm_prefork_module modules/mod_mpm_prefork.so # worker MPM: Multi-Processing Module implementing a hybrid # multi-threaded multi-process web server # See: http://httpd.apache.org/docs/2.4/mod/worker.html # #LoadModule mpm_worker_module modules/mod_mpm_worker.so # event MPM: A variant of the worker MPM with the goal of consuming # threads only for connections with active processing # See: http://httpd.apache.org/docs/2.4/mod/event.html # LoadModule mpm_event_module modules/mod_mpm_event.so ``` 編輯 ==/etc/httpd/conf/httpd.conf== 的`<VirtualHost>` 部分, 1) 指定連線使用的協定,`h2`代表HTTP/2,後面接著的是其他備用協定選項,常用的有`h2c`、`http/1.1`。 2) 把FastCGI Proxy用的Socket檔路徑設定好,這樣`Httpd`才能跟`php-fpm`通訊。 注:這邊假設你已經把SSL/TLS憑證相關的設定做完,故不贅述。 ``` <VirtualHost *:443> ... Protocols h2 http/1.1 ... <Proxy "unix:/var/run/php-fpm/default.sock|fcgi://php-fpm"> ProxySet disablereuse=off </Proxy> # Redirect to the proxy <FilesMatch \.php$> SetHandler proxy:fcgi://php-fpm </FilesMatch> ... </VirtualHost> ``` 編輯 ==/etc/php-fpm.d/www.ini== 把`php-fpm`這端對應的接口設定妥當: ``` ... listen = /var/run/php-fpm/default.sock ... listen.owner = apache listen.group = apache listen.mode = 0660 ... ``` 最後把設定相關的服務重啟,並查看狀態 ```bash systemctl restart httpd php-fpm && \ systemctl enable httpd php-fpm && \ systemctl status httpd php-fpm ``` 看到 `active (running)` 就完成啦! ![](https://i.imgur.com/2LFLx2u.png) 如果使用`phpinfo()`去查看`Server API`,顯示`FPM/FastCGI`就表示PHP解譯器和Proxy的溝通正常 (可以看到這畫面就代表正常了啦)。 ![](https://i.imgur.com/Z6LQpbR.png) 最後,可以到 [HTTP2.Pro](https://http2.pro/) 檢查HTTP/2是否更新成功。 Enjoy Your HTTP/2 ! ## 補充參考 - [Apache HTTP/2 guide](https://httpd.apache.org/docs/2.4/howto/http2.html) - [Apache 2.4 Change log](https://www-us.apache.org/dist//httpd/CHANGES_2.4) - [Apache的三种MPM模式比较:prefork,worker,event](http://blog.jobbole.com/91920/) - [Enabling http/2 in Apache 2.4 does not work](https://stackoverflow.com/questions/52714001/enabling-http-2-in-apache-2-4-does-not-work) - [Introduction to HTTP/2](https://developers.google.com/web/fundamentals/performance/http2/) - [HTTP/2 is here, let's optimize!](https://docs.google.com/presentation/d/1r7QXGYOLCh4fcUq0jDdDwKJWNqWK1o4xMtYpKZCJYjM/present?slide=id.p19) (Slide) - [Linux的php-fpm优化心得-php-fpm进程占用内存大和不释放内存问题](https://wzfou.com/php-fpm/) --- #### 個人小雜記 最近因為業務需要,終於花一些時間學習HTTP/2的基礎知識。 看完之後覺得不如用實際行動來加深印象,順便提升網站安全性及載入速度,遂決定動手把原本的HTTP/1.1協定更新上HTTP/2。 經過一番搜尋後,大致了解要修改的範圍,於是開始在虛擬機上"踩雷",經過一番努力之後終於成功把關鍵的軟體部署到伺服器上。 最後,為了讓其他人也順利升級,所以我把的升級流程記錄在這。 EOF