一、什么是虚拟主机虚拟主机Virtual Host是 Apache 的核心功能之一允许在一台物理服务器上托管多个网站。每个网站拥有独立的域名、文档根目录和配置互不干扰。Apache 支持三种虚拟主机方式类型区分依据适用场景基于域名Name-basedHTTP 请求头中的Host字段最常用共享同一个 IP 地址基于 IPIP-based不同的 IP 地址需要独立 IP 的场景基于端口Port-based不同的端口号内部测试、特殊应用本文重点介绍基于域名的虚拟主机这是目前最主流、最实用的方案。二、核心原理基于域名的虚拟主机2.1 工作原理Apache 通过 HTTP 请求头中的Host字段来区分不同的网站。当浏览器访问http://set.charitize.dsz时会在请求头中携带Host: set.charitize.dszApache 根据这个字段匹配对应的VirtualHost块。隐藏子域名 /var/www/set默认站点 /var/www/localhost/htdocsApache 服务器DNS 解析浏览器隐藏子域名 /var/www/set默认站点 /var/www/localhost/htdocsApache 服务器DNS 解析浏览器查询 set.charitize.dsz返回服务器 IPGET / HTTP/1.1Host: set.charitize.dsz匹配 ServerName返回 /var/www/set 内容index.html200 OK 页面内容GET / HTTP/1.1Host: localhost未精确匹配走第一个 VirtualHost默认index.html200 OK 页面内容2.2 与单站点的核心区别方面初始配置单站点修改后配置虚拟主机站点数量只有 1 个站点全局DocumentRoot多个虚拟主机默认 隐藏子域名匹配方式所有请求都去同一个目录根据Host请求头分发到不同目录配置结构全局DocumentRootDirectory多个VirtualHost块关键指令DocumentRoot /var/www/localhost/htdocsNameVirtualHost *:80VirtualHost *:80三、配置步骤详解3.1 启用虚拟主机功能在 Apache 2.2 中需要显式启用NameVirtualHost指令NameVirtualHost *:80作用告诉 Apache 启用基于域名的虚拟主机功能监听所有 IP 的 80 端口。如果没有这个指令Apache 会将所有请求交给第一个VirtualHost处理。在 Apache 2.4 中NameVirtualHost已被废弃默认自动启用基于域名的虚拟主机。3.2 配置默认虚拟主机当使用虚拟主机时全局的DocumentRoot会被忽略必须将站点配置放在VirtualHost块中。VirtualHost *:80 ServerName localhost ServerAlias default DocumentRoot /var/www/localhost/htdocs Directory /var/www/localhost/htdocs Options Indexes FollowSymLinks AllowOverride All Require all granted /Directory ErrorLog ${APACHE_LOG_DIR}/localhost_error.log CustomLog ${APACHE_LOG_DIR}/localhost_access.log combined /VirtualHost作用处理访问localhost的请求作为默认站点处理所有未匹配到的域名请求包括直接 IP 访问、未知域名3.3 配置隐藏子域名虚拟主机VirtualHost *:80 ServerName set.charitize.dsz DocumentRoot /var/www/set Directory /var/www/set Options Indexes FollowSymLinks AllowOverride All Require all granted /Directory ErrorLog ${APACHE_LOG_DIR}/set_error.log CustomLog ${APACHE_LOG_DIR}/set_access.log combined /VirtualHost作用只处理Host: set.charitize.dsz的请求访问其他域名不会看到这个站点。3.4 完整配置示例# 启用基于域名的虚拟主机Apache 2.2 需要 NameVirtualHost *:80 # 默认虚拟主机必须放在第一位作为 fallback VirtualHost *:80 ServerName localhost ServerAlias default DocumentRoot /var/www/localhost/htdocs Directory /var/www/localhost/htdocs Options Indexes FollowSymLinks AllowOverride All Require all granted /Directory ErrorLog ${APACHE_LOG_DIR}/localhost_error.log CustomLog ${APACHE_LOG_DIR}/localhost_access.log combined /VirtualHost # 隐藏子域名虚拟主机 VirtualHost *:80 ServerName set.charitize.dsz DocumentRoot /var/www/set Directory /var/www/set Options Indexes FollowSymLinks AllowOverride All Require all granted /Directory ErrorLog ${APACHE_LOG_DIR}/set_error.log CustomLog ${APACHE_LOG_DIR}/set_access.log combined /VirtualHost四、请求处理流程HTTP 请求Host: set.charitize.dszHost: localhost / IPHost: 其他未知域名浏览器/客户端Apache Web 服务器隐藏子域名站点DocumentRoot: /var/www/set默认站点DocumentRoot: /var/www/localhost/htdocs匹配规则Apache 收到请求后读取 HTTP 头中的Host字段精确匹配ServerName→ 返回对应站点内容未精确匹配 → 走第一个VirtualHost默认站点五、常见问题与解决5.1 为什么配置了 VirtualHost 后原来的站点无法访问原因配置VirtualHost后Apache 进入虚拟主机模式。在这个模式下全局的DocumentRoot被忽略只有VirtualHost块中定义的站点才能被访问如果没有定义处理原来域名如localhost或直接 IP 访问的VirtualHost原来的内容就无法访问解决添加一个默认VirtualHost将原来的配置移入其中。5.2 如何验证虚拟主机配置# 列出所有虚拟主机sudoapachectl-S输出示例VirtualHost configuration: *:80 localhost (/etc/apache2/httpd.conf:162) *:80 set.charitize.dsz (/etc/apache2/httpd.conf:175)5.3 如何添加更多站点只需增加新的VirtualHost *:80块指定不同的ServerName和DocumentRootVirtualHost *:80 ServerName blog.example.com DocumentRoot /var/www/blog ... /VirtualHost5.4 403 Forbidden 错误可能原因目录权限不正确sudo chmod -R 755 /var/www配置中缺少Require all grantedSELinux 未关闭CentOSsudo setenforce 0六、关键指令速查表指令作用NameVirtualHost *:80启用基于域名的虚拟主机Apache 2.2VirtualHost *:80定义一个虚拟主机块ServerName设置虚拟主机的主域名ServerAlias设置虚拟主机的别名域名DocumentRoot设置站点的文档根目录ErrorLog设置错误日志路径CustomLog设置访问日志路径七、总结问题答案为什么要加默认虚拟主机让原来直接访问 IP/localhost 的用户还能看到原来的网站为什么隐藏子域名生效Apache 根据Host请求头精确匹配ServerName访问顺序是什么精确匹配ServerName→ 匹配不到的走第一个VirtualHost默认站点如何添加更多隐藏站点增加新的VirtualHost *:80块指定不同的ServerName和DocumentRoot虚拟主机是 Apache 最实用的功能之一通过基于域名的方式可以在一台服务器上高效托管多个独立站点既节省资源又便于管理。