服务器主机分类与特性


1 ) 独立服务器

  • 整台服务器资源由单一用户独占,采用租用或托管方式
  • 用户对硬件配置拥有完全控制权,需自行维护硬件设备(如故障修理),适用于大中型网站

2 ) 虚拟主机(Virtual Host)

  • 单台服务器划分磁盘空间存放网站数据,仅提供基础访问、存储与传输功能
  • 资源共享导致成本较低,无需用户维护网站外服务,适合小型网站

3 ) VPS(Virtual Private Server)

  • 虚拟化技术模拟多台独立主机,每台具备独立IP、操作系统、隔离的磁盘/内存/CPU资源
  • 用户自由分配资源,需一定系统维护能力,适合小型企业官网

4 ) ECS(Elastic Compute Service)

  • 云服务器整合计算、存储、网络,支持弹性伸缩
  • 分布式架构跨越多台物理服务器,主机镜像备份保障高安全性与稳定性,扩展灵活,适合大中小型网站

选型建议:

  • 个人静态网站:虚拟主机或免费服务(如 GitHub Pages)
  • 小型企业官网:VPS
  • 高访问量/可扩展网站:ECS云服务器(如阿里云)

技术类比:

  • 虚拟主机 ≈ 单套房分隔的共享房间(资源相互影响)
  • VPS ≈ 单套房分隔的独立公寓(可自定义环境)
  • 云服务器 ≈ 整栋大楼(按需扩展空间)

Apache虚拟主机核心机制

  • 功能定义:基于请求的IP地址、主机域名或端口号,单台服务器提供多个独立网站访问
  • 基于不同IP地址、主机域名或端口号响应请求,实现多网站并行服务,不同请求返回不同内容
  • 用户访问不同标识时,获取的网页内容独立隔离

基于IP地址的虚拟主机配置

前提条件:服务器需绑定多个IP地址(本例以 192.168.0.106192.168.0.10192.168.0.20 为例)。

配置步骤

1 ) 绑定静态IP地址

编辑网络配置文件(CentOS)  
sudo vi /etc/sysconfig/network-scripts/ifcfg-ens33  
修改以下参数  
BOOTPROTO=static  
IPADDR=192.168.0.106  
NETMASK=255.255.255.0  
# 使用 nmtui 添加新IP 
sudo nmtui  # 选择 "Edit a connection" → "Edit" → "IPv4 CONFIGURATION"
# 添加新地址:192.168.0.10/24 和 192.168.0.20/24 
sudo systemctl restart network  # 重启网络服务 

2 ) 创建网站目录与内容

mkdir -p /home/web/{10,20}
echo "IP 192.168.0.10" > /home/web/10/index.html 
echo "IP 192.168.0.20" > /home/web/20/index.html 

3 ) 修改Apache主配置文件 (/etc/httpd/conf/httpd.conf)

<VirtualHost 192.168.0.10:80>
    DocumentRoot "/home/web/10"
    ServerName www.linuxcoreapp.com 
    <Directory "/home/web/10">
        AllowOverride None 
        Require all granted 
    </Directory>
</VirtualHost>

<VirtualHost 192.168.0.20:80>
    DocumentRoot "/home/web/20"
    ServerName bbs.linuxcoreapp.com 
    <Directory "/home/web/20">
        AllowOverride None 
        Require all granted 
    </Directory>
</VirtualHost>

4 ) SELinux安全上下文配置

sudo semanage fcontext -a -t httpd_sys_content_t "/home/web(/.*)?"
sudo restorecon -Rv /home/web  # 应用配置 

5 ) 重启Apache服务

sudo systemctl restart httpd 

验证访问:浏览器输入 http://192.168.0.10http://192.168.0.20 分别显示对应IP的页面内容

基于主机域名的虚拟主机配置

前提条件:单IP绑定多域名(本例以 192.168.0.10 解析 www.linuxcoreapp.combbs.linuxcoreapp.com 为例)

配置步骤

1 ) 客户端域名解析配置

  • 修改客户端 /etc/hosts 文件:
    192.168.0.10  www.linuxcoreapp.com 
    192.168.0.10  bbs.linuxcoreapp.com 
    # 或这样写
    192.168.0.10 www.linuxcoreapp.com bbs.linuxcoreapp.com  
    

2 ) 创建域名对应目录与内容

mkdir -p /home/web/{www,bbs}
echo "www.linuxcoreapp.com" > /home/web/www/index.html 
echo "BBS.linuxcoreapp.com" > /home/web/bbs/index.html 

3 ) 修改Apache配置 (/etc/httpd/conf/httpd.conf)

<VirtualHost 192.168.0.10:80>
    DocumentRoot "/home/web/www"
    ServerName www.linuxcoreapp.com 
    <Directory "/home/web/www">
        AllowOverride None 
        Require all granted 
    </Directory>
</VirtualHost>

<VirtualHost 192.168.0.10:80>
    DocumentRoot "/home/web/bbs"
    ServerName bbs.linuxcoreapp.com 
    <Directory "/home/web/bbs">
        AllowOverride None 
        Require all granted 
    </Directory>
</VirtualHost>

4 ) 重启Apache服务,清理冲突配置

rm -rf /home/web/{10,20}           # 删除旧IP目录 
systemctl restart httpd               # 重启Apache生效  

验证访问:

  • http://www.linuxcoreapp.com → 显示 “www.linuxcoreapp.com”
  • http://bbs.linuxcoreapp.com → 显示 “BBS.linuxcoreapp.com”

NestJS工程实践


1 ) 方案1

实现虚拟主机逻辑

import { Controller, Get, HostParam } from '@nestjs/common';
import { Response } from 'express';
 
@Controller({ host: ':domain' })  // 动态捕获域名 
export class VirtualHostController {
  @Get()
  serveContent(@HostParam('domain') domain: string, res: Response) {
    const contentMap = {
      'www.linuxcoreapp.com': 'Welcome to www.linuxcoreapp.com',
      'bbs.linuxcoreapp.com': 'BBS.linuxcoreapp.com Forum'
    };
 
    if (contentMap[domain]) {
      res.send(contentMap[domain]);
    } else {
      res.status(404).send('Virtual Host Not Found');
    }
  }
}
 
// 多IP支持(需多网卡或IP别名)
@Controller({ host: '192.168.0.10' })
export class IpBasedController {
  @Get()
  handleIpRequest() {
    return 'Response from IP 192.168.0.10';
  }
}

关键配置说明:

  1. @Controller({ host: ':domain' }) 动态捕获域名参数
  2. contentMap 实现域名与内容的映射逻辑
  3. 多IP需结合服务器网络配置(如IP别名 ifconfig eth0:0 192.168.0.10

2 )方案2

NestJS域名路由实现

// domain-routing.module.ts
import { Module, MiddlewareConsumer } from '@nestjs/common';
import { DomainMiddleware } from './domain.middleware';
import { WebsiteController } from './website.controller';
import { BBSController } from './bbs.controller';
 
@Module({
  controllers: [WebsiteController, BBSController],
})
export class DomainRoutingModule {
  configure(consumer: MiddlewareConsumer) {
    consumer 
      .apply(DomainMiddleware)
      .forRoutes('*');
  }
}
 
// domain.middleware.ts 
import { Request, Response, NextFunction } from 'express';
 
export function DomainMiddleware(req: Request, res: Response, next: NextFunction) {
  const host = req.headers.host;
  
  // 重写请求路径以匹配不同控制器
  if (host === 'www.linuxcoreapp.com') {
    req.url = '/website' + req.url;
  } else if (host === 'bbs.linuxcoreapp.com') {
    req.url = '/bbs' + req.url;
  }
  
  next();
}
 
// website.controller.ts
import { Controller, Get } from '@nestjs/common';
 
@Controller('website')
export class WebsiteController {
  @Get()
  serveWebsite() {
    return { content: 'Welcome to www.linuxcoreapp.com' };
  }
}
 
// bbs.controller.ts
import { Controller, Get } from '@nestjs/common';
 
@Controller('bbs')
export class BBSController {
  @Get()
  serveBBS() {
    return { content: 'Welcome to BBS.linuxcoreapp.com' };
  }
}

实现逻辑:

  1. 中间件动态路由:根据 Host 请求头重写URL路径
  2. 控制器分离:独立控制器处理不同域名业务逻辑
  3. 扩展性:可结合反向代理(Nginx)实现域名分流与负载均衡

3 ) 方案3

import { Controller, Get, HostParam } from '@nestjs/common';  
 
@Controller({ host: ':domain' })  // 动态域名捕获  
export class VirtualHostController {  
  @Get()  
  serveContent(@HostParam('domain') domain: string): string {  
    if (domain === 'www.linuxcoreapp.com') {  
      return 'www.linuxcoreapp.com content';  
    } else if (domain === 'bbs.linuxcoreapp.com') {  
      return 'BBS.LINUXCOREAPP.COM content';  
    }  
    return 'Default host content';  
  }  
}  

技术要点总结

  1. IP与域名解析隔离:
    • 基于IP:每个网站需独立IP,适用于IP资源充足的场景
    • 基于域名:单IP多域名,依赖ServerName字段区分请求
  2. SELinux安全机制:
    必须通过semanage与restorecon命令设置httpd_sys_content_t上下文类型,否则文件不可访问
  3. 配置优先级:
    Apache优先匹配<VirtualHost>区块,未匹配的请求由默认主机处理
  4. 虚拟主机核心
    Apache通过 <VirtualHost> 指令块 隔离不同网站,依赖 DocumentRoot 指定资源路径
  5. 配置文件逻辑:
    • DocumentRoot 指定资源路径
    • <Directory> 定义目录访问权限
    • ServerName 声明域名标识
  6. 配置冲突规避:删除旧目录/配置块(如 /home/web/10)避免残留规则干扰
Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐