![VirtualHost 在重启时默认部署错误](https://linux22.com/image/683772/VirtualHost%20%E5%9C%A8%E9%87%8D%E5%90%AF%E6%97%B6%E9%BB%98%E8%AE%A4%E9%83%A8%E7%BD%B2%E9%94%99%E8%AF%AF.png)
我们的服务器运行着七个域/子域。为了尽量简化,我将列出其中四个。
- 示例.com
- www.example.com
- dwf.example.com
- chris.example.com
服务器 90% 的时间都运行良好,但偶尔我们会收到大量请求,数据库服务器会宕机。这样 Apache 连接就会达到最大值,因为所有数据库连接都在等待超时。一切顺利,我们强制重新启动数据库,连接就会恢复。但是,请求随后会进入 dfw.example.com 配置。该部署没有我们的代码库,这是一个大问题,我不明白为什么会发生这种情况。当这种情况发生时,它也会始终转到该部署,而不会转到我们拥有的其他 5 个部署中的任何一个。
从我读过的文档中,我认为 Apache 读取了 httpd.conf 文件并寻找第一个 NamedVirtualHost 匹配项:
现在,当请求到达时,服务器将首先检查它是否正在使用与 NameVirtualHost 匹配的 IP 地址。如果是,它将查看
<VirtualHost>
具有匹配 IP 地址的每个部分,并尝试找到 ServerName 或 ServerAlias 与请求的主机名匹配的部分。如果找到一个,它将使用该服务器的配置。如果未找到匹配的虚拟主机,则将使用与 IP 地址匹配的第一个列出的虚拟主机。
我们正在运行 Apache 2.2.15。
我认为与 httpd.conf 文件相关的部分是:
Listen 80
Listen 255.255.255.255:443
...
ServerName www.example.com
...(这是确切的顺序,www(https/http)、dfw,然后是所有其他版本)
NameVirtualHost www.example.com:80
<VirtualHost www.example.com:80>
ServerAdmin [email protected]
DocumentRoot /var/www/html/www.example.com
ServerName www.example.com
DirectoryIndex index.html
DirectoryIndex index.php
LogLevel notice
ErrorLog /var/log/httpd/www.example.com/error.log
CustomLog /var/log/httpd/www.example.com/access.log w3c_extended
</VirtualHost>
NameVirtualHost www.example.com:443
<VirtualHost www.example.com:443>
ServerAdmin [email protected]
DocumentRoot /var/www/html/www.example.com
ServerName www.example.com
#certificate stuff
DirectoryIndex index.html
DirectoryIndex index.php
LogLevel notice
ErrorLog /var/log/httpd/www.example.com/error.log
CustomLog /var/log/httpd/www.example.com/access.log w3c_extended
</VirtualHost>
NameVirtualHost dfw.example.com:80
<VirtualHost dfw.example.com:80>
ServerAdmin [email protected]
DocumentRoot /var/www/html/dfw.example.com
ServerName dfw.example.com
DirectoryIndex index.html
DirectoryIndex index.php
LogLevel notice
ErrorLog /var/log/httpd/dfw.example.com/error.log
CustomLog /var/log/httpd/dfw.example.com/access.log w3c_extended
</VirtualHost>
NameVirtualHost chris.example.com:443
<VirtualHost chris.example.com:443>
ServerAdmin [email protected]
DocumentRoot /var/www/html/chris.example.com
#cert stuff
ServerName chris.example.com
DirectoryIndex index.html
DirectoryIndex index.php
LogLevel notice
ErrorLog /var/log/httpd/chris.example.com/error.log
CustomLog /var/log/httpd/chris.example.com/access.log w3c_extended
</VirtualHost>
NameVirtualHost chris.example.com:80
<VirtualHost chris.example.com:80>
ServerAdmin [email protected]
DocumentRoot /var/www/html/chris.example.com
ServerName chris.example.com
DirectoryIndex index.html
DirectoryIndex index.php
LogLevel notice
RewriteLog /home/chris/writinglog.log
RewriteLogLevel 8
ErrorLog /var/log/httpd/chris.example.com/error.log
CustomLog /var/log/httpd/chris.example.com/access.log w3c_extended
CheckSpelling on
</VirtualHost>
执行后将sudo service httpd restart
再次获得正确的部署服务。
输出自apachectl -S
:
VirtualHost configuration:
[IPV6ADDRESS]:443 is a NameVirtualHost
default server chris.example.com (/etc/httpd/conf/httpd.conf:1077)
port 443 namevhost chris.example.com (/etc/httpd/conf/httpd.conf:1077)
[IPV6ADDRESS]:80 is a NameVirtualHost
default server chris.example.com (/etc/httpd/conf/httpd.conf:1095)
port 80 namevhost chris.example.com (/etc/httpd/conf/httpd.conf:1095)
port 80 namevhost cory.example.com (/etc/httpd/conf/httpd.conf:1128)
IPV4Address:80 is a NameVirtualHost
default server www.example.com (/etc/httpd/conf/httpd.conf:1035)
port 80 namevhost dfw.example.com (/etc/httpd/conf/httpd.conf:1065)
port 80 namevhost www.example.com (/etc/httpd/conf/httpd.conf:1035)
port 80 namevhost chris.example.com (/etc/httpd/conf/httpd.conf:1095)
IPV4Address:443 is a NameVirtualHost
default server www.example.com (/etc/httpd/conf/httpd.conf:1047)
port 443 namevhost www.example.com (/etc/httpd/conf/httpd.conf:1047)
port 443 namevhost chris.example.com (/etc/httpd/conf/httpd.conf:1077)
wildcard NameVirtualHosts and _default_ servers:
_default_:443 www.example.com (/etc/httpd/conf.d/ssl.conf:74)
Syntax OK
答案1
我不确定您有多个NameVirtualHost *
指令是否好。据我理解,您只需要一个纯 NAME 虚拟主机,并且您希望所有端口上的所有接口都由 NameVirtual Host 处理。
我建议您创建如下主机:
# Use Virtual hosts for all interfaces on all ports
NameVirtualHost *
<VirtualHost *>
ServerName example.com
# all other settings for this hostname
</VirtualHost>
<VirtualHost *>
ServerName www.example.com
# all other settings for this hostname
</VirtualHost>
<VirtualHost *>
ServerName dfw.example.com
# all other settings for this hostname
</VirtualHost>
<VirtualHost *>
chris.example.com
# all other settings for this hostname
</VirtualHost>
## ssl.conf
<VirtualHost _default_:443>
ServerName www.example.com
# all other settings for this hostname
SSLEngine on
#certificate stuff
</VirtualHost>
如果您想对多个主机名使用相同的设置(例如 example.com 和 www.example.com),您可以简单地添加列出所有主机名的 ServerAlias 指令(也可以使用“*.example.com”等通配符)。
例如,匹配“example.com”和“www.example.com”的虚拟主机可以这样做:
<VirtualHost *>
ServerName example.com
ServerAlias example.com www.example.com
# all other settings for this hostname
</VirtualHost>
DirectoryIndex
ps 类似或的设置 LogLevel
您可以在全局配置中定义一次。您的虚拟主机将采用全局配置,您无需向每个主机添加相同的值。
仅当某个主机需要与全局值不同的配置时,才必须在该主机中添加特殊设置。