{T}

异地容灾与多活架构 学习笔记(第 5 部分)

应用双活实现

javascript
// 应用双活负载均衡
class ApplicationLoadBalancer {
  constructor() {
    this.appInstances = {
      beijing: {
        url: 'http://app-bj.example.com',
        status: 'active',
        weight: 50,
        health: 100
      },
      shanghai: {
        url: 'http://app-sh.example.com',
        status: 'active',
        weight: 50,
        health: 100
      }
    }
  }
  
  // 路由请求
  route(userId) {
    const activeApps = this.getActiveApps()
    
    if (activeApps.length === 0) {
      throw new Error('无可用应用实例')
    }
    
    // 根据权重选择
    const selected = this.selectByWeight(activeApps, userId)
    
    return this.appInstances[selected]
  }
  
  // 获取活跃应用
  getActiveApps() {
    return Object.keys(this.appInstances).filter(
      app => this.appInstances[app].status === 'active' && 
             this.appInstances[app].health > 80
    )
  }
  
  // 按权重选择
  selectByWeight(apps, userId) {
    // 一致性哈希(同一用户路由到同一应用)
    const hash = this.hashUserId(userId)
    
    let totalWeight = 0
    const weightRanges = []
    
    apps.forEach(app => {
      const start = totalWeight
      totalWeight += this.appInstances[app].weight
      weightRanges.push({ app, start, end: totalWeight })
    })
    
    const target = hash % totalWeight
    
    for (const range of weightRanges) {
      if (target >= range.start && target < range.end) {
        return range.app
      }
    }
    
    return apps[0]
  }
  
  // 哈希用户 ID
  hashUserId(userId) {
    let hash = 0
    for (let char of String(userId)) {
      hash = (hash << 5) - hash + char.charCodeAt(0)
    }
    return Math.abs(hash)
  }
  
  // 健康检查
  async healthCheck() {
    for (const app of Object.keys(this.appInstances)) {
      const isHealthy = await this.checkAppHealth(app)
      
      this.appInstances[app].health = isHealthy ? 100 : 0
      
      if (!isHealthy && this.appInstances[app].status === 'active') {
        this.failover(app)
      }
    }
  }
  
  // 检查应用健康
  async checkAppHealth(appName) {
    const app = this.appInstances[appName]
    
    try {
      const response = await fetch(`${app.url}/health`, {
        timeout: 3000
      })
      
      return response.ok
    } catch (error) {
      return false
    }
  }
  
  // 故障转移
  failover(failedApp) {
    console.log(`应用 ${failedApp} 故障,开始转移`)
    
    this.appInstances[failedApp].status = 'failed'
    this.appInstances[failedApp].weight = 0
    
    // 将权重分配给其他应用
    const activeApps = this.getActiveApps()
    const weight = 50 / activeApps.length
    
    activeApps.forEach(app => {
      this.appInstances[app].weight += weight
    })
  }
}

二、容灾技术方案分层架构

2.1 应用层面分层

plaintext
应用层面四层架构:
 
┌─────────────────────────────────┐
│  Layer 4: OS 层                  │  ← 操作系统层
│  (Windows / Linux / Unix)       │
├─────────────────────────────────┤
│  Layer 3: 数据库层               │  ← 数据库层
│  (MySQL / Oracle / MongoDB)     │
├─────────────────────────────────┤
│  Layer 2: 应用层                 │  ← 业务逻辑层
│  (业务代码 / API / 服务)         │
├─────────────────────────────────┤
│  Layer 1: IP 层                  │  ← 网络层
│  (IP 地址 / 路由 / DNS)          │
└─────────────────────────────────┘

各层职责

层次名称职责示例技术
Layer 1IP 层网络通信、路由DNS、BGP、VIP
Layer 2应用层业务逻辑处理Nginx、Tomcat、Node.js
Layer 3数据库层数据存储与查询MySQL、Redis、MongoDB
Layer 4OS 层系统资源管理Linux、Windows Server

2.2 数据层面分层

plaintext
数据层面三层架构:
 
┌─────────────────────────────────┐
│  Layer 3: 存储层                 │  ← 磁盘存储
│  (磁盘阵列 / SAN / NAS)          │
├─────────────────────────────────┤
│  Layer 2: 存储区域网络层         │  ← 数据传输网络
│  (光纤通道 / iSCSI / FCoE)       │
├─────────────────────────────────┤
│  Layer 1: 存储虚拟化层           │  ← 存储池化管理
│  (存储虚拟化 / SDS)              │
└─────────────────────────────────┘

各层职责

层次名称职责示例技术
Layer 1存储虚拟化层存储资源池化VMware vSAN、Ceph、GlusterFS
Layer 2存储区域网络层数据传输网络FC、iSCSI、Fibre Channel
Layer 3存储层物理存储介质RAID、SSD、HDD