Ubuntu

如何使用 ubuntu 20.04 在 apache2 上啟用 http/2?

  • March 13, 2021

我有執行 ubuntu 20.04 (apache2) 的 VPS 伺服器,並且正在使用 http/1.1,我想升級到 http/2

該域已經使用 v-hosts 進行了配置(並且安裝了 ssl - 讓我們加密)。

測試目前協議:

$ curl -I https://my-domain.com
HTTP/1.1 200 OK
Date: Fri, 12 Mar 2021 17:32:01 GMT
Server: Apache/2.4.41 (Ubuntu)
Content-Type: text/html; charset=UTF-8

我升級到 http/2 的步驟:

1) sudo a2enmod http2

2) add in virtual host (ex: /etc/apache2/sites-enabled/my-domain.com-le-ssl.conf) the line:
Protocols h2 http/1.1     

3) check the config
sudo apache2ctl configtest

4) Restart the web server
sudo systemctl reload apache2

再次測試協議:

$ curl -I https://my-domain.com
HTTP/1.1 200 OK
Date: Fri, 12 Mar 2021 17:57:07 GMT
Server: Apache/2.4.41 (Ubuntu)
Upgrade: h2
Connection: Upgrade
Content-Type: text/html; charset=UTF-8

如您所見,它仍在使用 http/1.1

我錯過了什麼 ???

更新

apache2 載入的模組

$ sudo apachectl -M
Loaded Modules:
core_module (static)
so_module (static)
watchdog_module (static)
http_module (static)
log_config_module (static)
logio_module (static)
version_module (static)
unixd_module (static)
access_compat_module (shared)
alias_module (shared)
auth_basic_module (shared)
authn_core_module (shared)
authn_file_module (shared)
authz_core_module (shared)
authz_host_module (shared)
authz_user_module (shared)
autoindex_module (shared)
deflate_module (shared)
dir_module (shared)
env_module (shared)
expires_module (shared)
filter_module (shared)
headers_module (shared)
http2_module (shared)
mime_module (shared)
mpm_prefork_module (shared)
negotiation_module (shared)
php7_module (shared)
reqtimeout_module (shared)
rewrite_module (shared)
setenvif_module (shared)
socache_shmcb_module (shared)
ssl_module (shared)
status_module (shared)

已安裝 php 7.4.3

php 
libapache2-mod-php 
php-mysql 
php-cli 
php-mbstring 
php-imagick 
php-xml 
php-gd 
php-zip 
php-curl 
php-opcache 
php-soap 
php-bcmath

虛擬主機配置:

<VirtualHost *:80>
   ServerAdmin admin@my-domain.com
   ServerName my-domain.com
   ServerAlias www.my-domain.com
   DocumentRoot /var/www/my-domain.com/public

   Protocols h2 http/1.1 

   <Directory /var/www/my-domain.com/public/>
   Options Indexes FollowSymLinks MultiViews
   AllowOverride All
       Require all granted
   </Directory>

   ErrorLog ${APACHE_LOG_DIR}/error.log
   CustomLog ${APACHE_LOG_DIR}/access.log combined
RewriteEngine on
RewriteCond %{SERVER_NAME} =my-domain.com [OR]
RewriteCond %{SERVER_NAME} =www.my-domain.com
RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]
</VirtualHost>

和 ssl 配置:

<IfModule mod_ssl.c>
<VirtualHost *:443>
   ServerAdmin admin@my-domain.com
   ServerName my-domain.com
   ServerAlias www.my-domain.com
   DocumentRoot /var/www/my-domain.com/public

   Protocols h2 http/1.1 

   <Directory /var/www/my-domain.com/public/>
   Options Indexes FollowSymLinks MultiViews
   AllowOverride All
       Require all granted
   </Directory>

   ErrorLog ${APACHE_LOG_DIR}/error.log
   CustomLog ${APACHE_LOG_DIR}/access.log combined

   Include /etc/letsencrypt/options-ssl-apache.conf
   SSLCertificateFile /etc/letsencrypt/live/my-domain.com/fullchain.pem
   SSLCertificateKeyFile /etc/letsencrypt/live/my-domain.com/privkey.pem
</VirtualHost>
</IfModule>

更新 2

我在error.log(apache)中發現的

[http2:warn] [pid 507] AH10034: The mpm module (prefork.c) is not supported by mod_http2. The mpm determines how things are processed in your server. HTTP/2 has more demands in this regard and the currently selected mpm will just not do. This is an advisory warning. Your server will continue to work, but the HTTP/2 protocol will be inactive.

大概這就是原因。也許使用 mpm_event 而不是 mpm_prefork 會起作用。

我不確定我是否需要 php-fpm …

  1. 用 mpm_event 替換 mpm_prefork
  2. 使用 php-fpm (libapache2-mod-fcgid) 而不是 (libapache2-mod-php)

解決問題。

歸功於@MichaelHampton!

引用自:https://serverfault.com/questions/1056893