多云网络互联:云 OnRamp 与骨干设计
多云架构越来越普遍,但多云网络互联往往是最头疼的部分。这篇文章不谈概念,直接说三种互联方式怎么选、跨云流量怎么省钱、故障怎么切换。基于三个真实项目经验。
多云互联三种方式
方式一:公共互联网(最便宜,性能最差)
特点: - 成本:最低(无需额外费用) - 延迟:高且不稳定(50-200ms) - 带宽:受限(受公网拥塞影响) - 安全性:依赖加密(IPSec/TLS) - 可用性:不可控(运营商网络问题)
适用场景: - 开发测试环境 - 非关键业务数据同步 - 备份复制(可容忍延迟)
配置示例:
# AWS Site-to-Site VPN(公网)
aws ec2 create-vpn-connection \
--transit-gateway-id tgw-xxxxxx \
--type ipsec.1 \
--static-routes-only \
--bgp-asn 65000 \
--amazon-side-asn 64512
# 导出 VPN 配置
aws ec2 export-vpn-connection \
--vpn-connection-id vpc-vpna-xxxxxx \
--region us-east-1
方式二:VPN 隧道(中等成本,中等性能)
特点: - 成本:中等(VPN 网关费用) - 延迟:中等(30-100ms) - 带宽:中等(VPN 网关性能限制) - 安全性:高(IPSec 加密) - 可用性:中等(依赖公网,但加密保护)
适用场景: - 生产环境非核心业务 - 需要加密但不要求极低延迟 - 快速部署场景
配置示例:
# Azure ExpressRoute 私有 peering(VPN over ER)
az network express-route circuit create \
--resource-group my-rg \
--name my-expressroute \
--sku Basic \
--region eastus \
--provider Equinix \
--encapsulation raw-gre \
--bandwidth 50 Mbps
# 阿里云 CEN + 云企业网(类似 ExpressRoute)
aliyun cen CreateCen --CenName my-cen
aliyun cen AttachCenInstance --CenId cen-xxxxxx --InstanceIds "[\"vpc-xxxxxx\",\"vpc-yyyyyy\"]"
aliyun cen CreateCenBandwidthPackage --CenId cen-xxxxxx --Bandwidth 50
方式三:专线 / Direct Connect(最高成本,最佳性能)
特点: - 成本:最高(专线月租费) - 延迟:最低(10-50ms) - 带宽:最高(1Gbps - 100Gbps) - 安全性:高(物理隔离) - 可用性:高(SLA 保障)
适用场景: - 核心生产业务 - 大带宽需求(视频、大数据) - 低延迟敏感应用 - 合规要求(数据不出物理网络)
配置示例:
# AWS Direct Connect
aws dx create-virtual-interface \
--region us-east-1 \
--region us-west-2 \
--type private \
--vlan 100 \
--amazon-side-asn 64512 \
--bgp-authentication-key 'my-auth-key' \
--address-family ipv4
# Azure ExpressRoute(专线)
az network express-route circuit peering create \
--resource-group my-rg \
--circuit-name my-expressroute \
--peering-type azure-peering \
--azure-peering-type primary \
--ip-prefix my-ip-prefix \
--router-recovery \
--sku Premium
# 阿里云 DTS(数据传输服务)+ 专线
aliyun dts CreateDtsJob \
--JobType FORWARD \
--SourceEndpoint.Region "us-east-1" \
--DestinationEndpoint.Region "cn-hangzhou" \
--InstanceClass dts_preinst_mid
选型决策树
你的场景是?
├─ 开发测试 / 备份复制
│ └─ 公共互联网(免费)
│
├─ 生产环境非核心业务
│ ├─ 需要低延迟?
│ │ ├─ 是 → 专线
│ │ └─ 否 → VPN 隧道
│ │
│ └─ 需要高带宽?
│ ├─ 是 → 专线
│ └─ 否 → VPN 隧道
│
└─ 生产环境核心业务
├─ 延迟敏感(<50ms)?
│ └─ 是 → 专线
│
├─ 带宽大(>1Gbps)?
│ └─ 是 → 专线
│
└─ 合规要求(数据不出物理网络)?
└─ 是 → 专线
跨云流量成本优化
优化一:跨云流量走专线不走公网
成本对比(某电商,月流量 50TB):
| 方式 | 单价 | 月成本 | 年成本 |
|---|---|---|---|
| 公网跨云 | $0.09/GB | $4,500 | $54,000 |
| 专线跨云 | $0.05/GB | $2,500 | $30,000 |
| 节省 | - | $2,000 | $24,000 |
优化二:缓存热点数据到本地
# 本地缓存策略(减少跨云请求)
import redis
import hashlib
class CrossCloudCache:
def __init__(self, local_region, remote_regions):
self.local_region = local_region
self.remote_regions = remote_regions
self.cache = redis.Redis(host='localhost', port=6379, db=0)
def get(self, key, remote_client=None):
"""
先从本地缓存取,miss 再跨云请求
"""
# 检查本地缓存
cached_value = self.cache.get(key)
if cached_value:
return cached_value.decode()
# 缓存 miss,从远程区域获取
if remote_client:
value = remote_client.get(key)
if value:
# 写入本地缓存(TTL 5 分钟)
self.cache.setex(key, 300, value)
return value.decode()
return None
def prefetch_hot_keys(self, hot_keys):
"""
预取热点数据到本地(减少跨云延迟)
"""
for key in hot_keys:
# 异步预取到本地缓存
self.cache.setex(key, 600, self.fetch_from_remote(key))
优化三:压缩和去重
# 跨云数据传输压缩
# AWS Transfer Family + Compress
aws transfer create-server \
--protocol SFTP \
--endpoint-type VPC \
--subnet-ids subnet-xxxx subnet-yyyy \
--security-group-ids sg-zzzz \
--role-arn arn:aws:iam::123456789012:role/transfer-role \
--compression-enabled
# 阿里云 DTS 数据去重
aliyun dts ModifyDtsJob \
--JobId dts-job-xxxx \
--DataRedundancy ENABLED \
--CompressEnabled ENABLED
故障转移策略
BGP + 健康检查(推荐)
# BGP 配置示例(AWS Direct Connect)
# 路由器配置
router bgp 64512
neighbor 169.254.33.1 remote-as 64512 # AWS Direct Connect router
neighbor 169.254.33.1 update-source Eth1
neighbor 169.254.33.1 timers bgp 10 30 # 快速检测
neighbor 169.254.33.1 distance 20 200 # 主备优先级
network 10.0.0.0 255.255.0.0
!
! 健康检查(Track)
track 1 ip route 10.0.0.0 255.255.0.0 reachability
interface Eth1
ip address 169.254.33.2 255.255.255.252
ip address 169.254.33.3 255.255.255.252 secondary # 备用链路
ip track 1
主备链路切换
import asyncio
import aiohttp
class MultiCloudFailover:
def __init__(self, primary_cloud, secondary_cloud, health_check_interval=30):
self.primary = primary_cloud
self.secondary = secondary_cloud
self.health_check_interval = health_check_interval
self.is_primary_healthy = True
async def health_check_loop(self):
"""周期性健康检查"""
while True:
await self.check_health()
await asyncio.sleep(self.health_check_interval)
async def check_health(self):
"""检查主云健康状态"""
try:
async with aiohttp.ClientSession() as session:
async with session.get(f'{self.primary}/health', timeout=aiohttp.ClientTimeout(total=5)) as resp:
if resp.status == 200:
if not self.is_primary_healthy:
self.is_primary_healthy = True
print("Primary cloud recovered")
else:
if self.is_primary_healthy:
self.is_primary_healthy = False
print("Primary cloud unhealthy, switching to secondary")
await self.switch_to_secondary()
except:
if self.is_primary_healthy:
self.is_primary_healthy = False
print("Primary cloud unreachable, switching to secondary")
await self.switch_to_secondary()
async def switch_to_secondary(self):
"""切换到备用云"""
# 1. 更新 DNS(TTL 30s)
await self.update_dns('app.example.com', self.secondary.ip)
# 2. 更新 SD-WAN 路由
await self.update_routing(self.secondary)
# 3. 通知运维
await self.notify_ops(f"Switched to secondary cloud: {self.secondary.name}")
async def update_dns(self, hostname, ip):
"""更新 DNS 记录"""
# Cloudflare API
import cloudflare
cf = cloudflare.Cloudflare()
await cf.dns.update(hostname, ip)
async def update_routing(self, target_cloud):
"""更新 SD-WAN 路由"""
# SD-WAN Controller API
async with aiohttp.ClientSession() as session:
async with session.post(
f'{self.sdwan_controller}/api/v1/routes',
headers={'Authorization': f'Bearer {self.token}'},
json={'target': target_cloud.id, 'action': 'route'}
) as resp:
return await resp.json()
真实案例:电商多云互联
背景
某电商公司: - AWS us-east-1:生产环境(核心交易) - AWS ap-southeast-1:东南亚业务 - 阿里云 cn-hangzhou:国内业务 - 月跨云流量:80TB - 跨云延迟:公网 200ms,专线 50ms
架构设计
┌─────────────┐
│ AWS us-east│
│ (生产) │
└──────┬──────┘
│ Direct Connect(1Gbps)
┌──────▼──────┐
│ Transit │
│ Gateway │
└──────┬──────┘
│
┌────────────┼────────────┐
│ │ │
┌─────▼─────┐ ┌───▼───┐ ┌────▼────┐
│AWS ap-southeast│ │阿里云cn│ │Azure eu│
│ (东南亚) │ │ (国内)│ │ (欧洲)│
└───────────┘ └───────┘ └─────────┘
成本优化效果
| 优化项 | 优化前 | 优化后 | 节省 |
|---|---|---|---|
| 跨云流量成本 | $7,200/月 | $3,600/月 | 50% |
| 延迟(国内用户) | 200ms | 50ms | 75% ↓ |
| 延迟(东南亚用户) | 180ms | 45ms | 75% ↓ |
| 故障恢复时间 | 10 分钟 | 30 秒 | 95% ↓ |
故障转移测试
# 模拟主云故障,验证自动切换
# 1. 停止 AWS us-east-1 的健康检查端点
curl -X POST http://localhost:8080/kill-health-check
# 2. 观察 DNS 切换
dig app.example.com +short
# 期望:IP 从 us-east-1 切换到 cn-hangzhou
# 3. 观察应用访问
curl -I https://app.example.com/health
# 期望:200 OK(从 cn-hangzhou 返回)
# 4. 验证时间
time curl -s https://app.example.com/health > /dev/null
# 期望:< 1s(之前是 10 分钟人工恢复)
配置检查清单
# 多云互联配置检查清单
# 1. 链路健康检查
curl -f http://primary-cloud/health || echo "Primary unhealthy"
curl -f http://secondary-cloud/health || echo "Secondary unhealthy"
# 2. 带宽利用率检查
aws cloudwatch get-metric-statistics \
--namespace AWS/DirectConnect \
--metric-name BandwidthUtilization \
--dimensions Name=connectionId,Value dxcon-xxxxxx \
--start-time $(date -Iseconds -d '1 hour ago') \
--end-time $(date -Iseconds) \
--period 300 \
--statistics Average
# 3. 延迟测试
ping -c 10 <remote-cloud-ip>
traceroute -n <remote-cloud-ip>
# 4. BGP 邻居状态
show ip bgp summary
show bgp neighbors
# 5. 跨云流量成本
aws ce get-cost-and-usage \
--time-period Start=$(date -Iseconds -d '7 days ago'),End=$(date -Iseconds) \
--granularity MONTHLY \
--metrics UnblendedCost \
--filter '{"Dimensions":{"Key:SERVICE,"Values":["Transit Gateway"]}}'
总结与判断
多云互联的核心是根据场景选对方式:开发测试用公网(免费),生产非核心用 VPN(平衡),生产核心用专线(性能优先)。跨云流量成本优化靠三个手段:专线替代公网、缓存热点数据、压缩去重。故障转移靠 BGP + 健康检查自动化。
我的判断:对于生产环境,至少要有两条互联链路(主 + 备),一条专线一条 VPN 即可。纯公网互联只适合非关键业务。成本控制的关键是减少跨云流量(缓存+压缩),而不是单纯切换专线/VPN。