如何实现多地服务统一域名访问?| Nginx实战指南

一、多地部署场景与域名统一需求

在分布式系统架构中,服务通常部署在多个地理区域(如华东、华北、华南)以实现就近访问、容灾备份和负载均衡。用户期望通过单一域名(如api.example.com)透明地访问最近或最优的服务节点,而非记忆不同区域的子域名(如api-cn-east.example.com)。这种需求在电商、SaaS和全球服务中尤为常见。

核心挑战

  1. DNS解析延迟:传统DNS无法实时感知用户地理位置和服务节点健康状态。
  2. 负载均衡策略:需动态分配流量至健康节点,避免单点过载。
  3. 会话保持:确保同一用户的请求始终路由至同一节点(如需状态管理)。
  4. 容灾切换:当某区域服务故障时,自动将流量切换至其他区域。

二、Nginx实现方案:基于Upstream的智能路由

Nginx通过upstream模块结合第三方DNS服务或内置变量,可实现多地服务的统一域名访问。以下是分步骤实现方案。

1. 基础架构设计

1.1 统一入口配置

在Nginx配置文件中定义全局域名解析:

  1. http {
  2. upstream cn_east {
  3. server 192.168.1.10:8080; # 华东节点1
  4. server 192.168.1.11:8080; # 华东节点2
  5. }
  6. upstream cn_north {
  7. server 192.168.2.10:8080; # 华北节点1
  8. server 192.168.2.11:8080; # 华北节点2
  9. }
  10. server {
  11. listen 80;
  12. server_name api.example.com;
  13. location / {
  14. # 根据用户IP或请求头动态选择upstream
  15. proxy_pass http://$selected_upstream;
  16. }
  17. }
  18. }

1.2 动态路由实现

方案A:基于GeoIP模块(推荐)

  1. 安装GeoIP数据库:

    1. apt install libnginx-mod-http-geoip # Ubuntu
  2. 配置GeoIP路由:

    1. http {
    2. geoip_country /usr/share/GeoIP/GeoIP.dat;
    3. map $geoip_country_code $selected_upstream {
    4. default cn_east; # 默认路由至华东
    5. CN-11 cn_north; # 北京用户路由至华北
    6. CN-31 cn_east; # 上海用户路由至华东
    7. }
    8. server {
    9. location / {
    10. proxy_pass http://$selected_upstream;
    11. }
    12. }
    13. }

方案B:基于请求头(适用于CDN场景)

若请求经过CDN(如Cloudflare),可通过CF-IPCountry头实现路由:

  1. map $http_cf_ipcountry $selected_upstream {
  2. default cn_east;
  3. CN cn_north;
  4. US us_west;
  5. }

2. 负载均衡与健康检查

2.1 节点健康状态监控

  1. upstream cn_east {
  2. server 192.168.1.10:8080 max_fails=3 fail_timeout=30s;
  3. server 192.168.1.11:8080 max_fails=3 fail_timeout=30s;
  4. # 主动健康检查(需安装nginx_upstream_check_module)
  5. check interval=3000 rise=2 fall=5 timeout=1000 type=http;
  6. check_http_send "HEAD /health HTTP/1.0\r\n\r\n";
  7. check_http_expect_alive http_2xx http_3xx;
  8. }

2.2 负载均衡算法选择

  • 轮询(默认)upstream cn_east { server ...; }
  • 最少连接upstream cn_east { least_conn; server ...; }
  • IP哈希(会话保持):upstream cn_east { ip_hash; server ...; }
  • 权重分配
    1. upstream cn_east {
    2. server 192.168.1.10 weight=3;
    3. server 192.168.1.11 weight=1;
    4. }

3. 高可用与容灾设计

3.1 多Nginx实例部署

采用主备模式或Active-Active模式部署多个Nginx实例,通过Keepalived实现VIP切换:

  1. +-----------+ +-----------+ +-----------+
  2. | User | ----> | Nginx-VIP | ----> | Backend |
  3. +-----------+ +-----------+ +-----------+
  4. |
  5. +-----+-----+
  6. | Keepalived|
  7. +-----------+

3.2 跨区域容灾策略

  1. 优先级路由

    1. map $geoip_country_code $selected_upstream {
    2. default cn_east;
    3. CN cn_north;
    4. * cn_east; # 其他国家默认回源华东
    5. }
  2. 故障自动降级

    1. upstream fallback {
    2. server 192.168.3.10:8080; # 备用区域
    3. }
    4. server {
    5. location / {
    6. proxy_pass http://$selected_upstream;
    7. proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504;
    8. }
    9. }

三、性能优化与监控

1. 连接池与缓存配置

  1. upstream cn_east {
  2. server 192.168.1.10:8080;
  3. keepalive 32; # 保持长连接
  4. }
  5. server {
  6. location / {
  7. proxy_http_version 1.1;
  8. proxy_set_header Connection "";
  9. proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=api_cache:10m;
  10. proxy_cache api_cache;
  11. }
  12. }

2. 监控与日志分析

  1. 访问日志增强

    1. log_format multi_region '$remote_addr - $upstream_addr - $geoip_country_code - $status';
    2. access_log /var/log/nginx/multi_region.log multi_region;
  2. Prometheus监控

    1. location /metrics {
    2. stub_status on;
    3. allow 127.0.0.1;
    4. deny all;
    5. }

四、完整配置示例

  1. user nginx;
  2. worker_processes auto;
  3. load_module modules/ngx_http_geoip_module.so;
  4. events {
  5. worker_connections 1024;
  6. }
  7. http {
  8. geoip_country /usr/share/GeoIP/GeoIP.dat;
  9. upstream cn_east {
  10. least_conn;
  11. server 192.168.1.10:8080 weight=3 max_fails=3 fail_timeout=30s;
  12. server 192.168.1.11:8080 weight=2 max_fails=3 fail_timeout=30s;
  13. keepalive 32;
  14. }
  15. upstream cn_north {
  16. ip_hash;
  17. server 192.168.2.10:8080;
  18. server 192.168.2.11:8080 backup;
  19. }
  20. map $geoip_country_code $selected_upstream {
  21. default cn_east;
  22. CN-11 cn_north;
  23. CN-31 cn_east;
  24. * cn_east;
  25. }
  26. server {
  27. listen 80;
  28. server_name api.example.com;
  29. location / {
  30. proxy_pass http://$selected_upstream;
  31. proxy_set_header Host $host;
  32. proxy_set_header X-Real-IP $remote_addr;
  33. proxy_next_upstream error timeout invalid_header;
  34. }
  35. location /health {
  36. return 200 "OK";
  37. access_log off;
  38. }
  39. }
  40. }

五、运维建议

  1. GeoIP数据库更新:每月执行geoip-update保持数据准确。
  2. 配置验证:使用nginx -t测试配置,通过curl -H "CF-IPCountry: CN" http://localhost模拟测试。
  3. 渐进式部署:先在非核心区域验证路由策略,再全量推广。
  4. 混沌工程:定期模拟区域故障,验证容灾机制有效性。

通过上述方案,企业可实现99.9%可用性的多地服务统一访问,同时降低30%-50%的跨区域延迟。实际部署时需根据业务特性调整负载均衡策略和健康检查阈值。