Nginx map實現(xiàn)基于客戶端 IP 段的動態(tài)后端路由的幾種方法實現(xiàn)
Nginx 的 map 模塊結合 Geo 模塊可以實現(xiàn)基于客戶端 IP 段的動態(tài)后端路由,常用于灰度發(fā)布、A/B 測試、多租戶隔離等場景。以下是完整的進階配置方案:
基礎原理
客戶端 IP → Geo/Map 匹配 → 變量賦值 → proxy_pass 動態(tài)路由
方案一:基于 IP 段的簡單分流
http {
# 定義 IP 段到后端組的映射
geo $backend_pool {
default backend_default;
192.168.1.0/24 backend_vip; # 內(nèi)網(wǎng) VIP 段
10.0.0.0/8 backend_internal; # 企業(yè)內(nèi)網(wǎng)
172.16.0.0/16 backend_partner; # 合作伙伴
}
upstream backend_default {
server 10.0.1.10:8080;
server 10.0.1.11:8080;
}
upstream backend_vip {
server 10.0.2.10:8080 weight=5; # 高配機器
server 10.0.2.11:8080 weight=5;
}
upstream backend_internal {
server 10.0.3.10:8080;
}
upstream backend_partner {
server 10.0.4.10:8080;
}
server {
listen 80;
location / {
# 直接使用 geo 變量路由
proxy_pass http://$backend_pool;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
}方案二:多級 Map 實現(xiàn)復雜策略
http {
# 第一級:識別 IP 段類型
geo $ip_segment {
default unknown;
192.168.0.0/16 corp;
10.0.0.0/8 dc;
172.16.0.0/12 vpn;
include /etc/nginx/geo_allow.conf; # 外部文件維護白名單
}
# 第二級:基于 IP 段 + 請求特征決定版本
map "$ip_segment:$http_x_feature_flag" $app_version {
# 格式: "段類型:特征標志" → 后端版本
default "v1-stable";
"~^corp:experiment$" "v2-beta"; # 內(nèi)網(wǎng)用戶 + 實驗頭
"~^corp:preview$" "v3-preview"; # 內(nèi)網(wǎng)用戶 + 預覽頭
"dc:" "v1-stable"; # 數(shù)據(jù)中心強制穩(wěn)定版
"vpn:" "v1-stable"; # VPN 用戶安全版本
"unknown:" "v1-stable"; # 未知來源保守策略
}
# 第三級:版本到 upstream 的映射
map $app_version $upstream_group {
v1-stable backend_prod;
v2-beta backend_canary;
v3-preview backend_preview;
}
upstream backend_prod {
server 10.0.1.10:8080 max_fails=3;
server 10.0.1.11:8080 backup;
}
upstream backend_canary {
server 10.0.2.10:8080; # 金絲雀環(huán)境
}
upstream backend_preview {
server 10.0.3.10:8080; # 預覽環(huán)境
}
server {
listen 80;
location / {
proxy_pass http://$upstream_group;
# 透傳版本信息給后端
proxy_set_header X-App-Version $app_version;
proxy_set_header X-IP-Segment $ip_segment;
}
# 調(diào)試端點:查看路由決策
location /_route_debug {
default_type application/json;
return 200 '{
"remote_addr": "$remote_addr",
"ip_segment": "$ip_segment",
"feature_flag": "$http_x_feature_flag",
"app_version": "$app_version",
"upstream": "$upstream_group"
}';
}
}
}方案三:CIDR 精確匹配 + 權重灰度
http {
# 使用 geo 的復雜匹配(支持 CIDR 和范圍)
geo $gray_level {
default 0; # 0 = 穩(wěn)定版
# 辦公網(wǎng)段:10% 流量進入灰度
192.168.10.0/24 10;
# 測試網(wǎng)段:100% 灰度
192.168.50.0/24 100;
# 特定 IP:強制灰度
203.0.113.5 100;
# 排除名單(從文件中加載)
include /etc/nginx/geo_deny.conf;
}
# 基于灰度級別計算實際后端
map $gray_level $target_backend {
0 "stable";
~^1-50$ "weighted"; # 1-50 需要二次計算
~^51-99$ "canary";
100 "canary";
}
# 對加權段進行隨機分流(split_clients 實現(xiàn)百分比)
split_clients "${remote_addr}${http_user_agent}" $canary_decision {
10% canary;
* stable;
}
# 最終 upstream 選擇
map "$target_backend:$canary_decision" $final_upstream {
"stable:" backend_stable;
"stable:stable" backend_stable;
"weighted:canary" backend_canary;
"weighted:stable" backend_stable;
"canary:" backend_canary;
"canary:canary" backend_canary;
}
upstream backend_stable {
server 10.0.1.10:8080;
server 10.0.1.11:8080;
}
upstream backend_canary {
server 10.0.2.10:8080;
}
server {
location / {
proxy_pass http://$final_upstream;
# 設置灰度 Cookie 保持會話一致性
add_header Set-Cookie "gray_route=$final_upstream; Path=/; Max-Age=3600" always;
}
}
}方案四:外部數(shù)據(jù)源動態(tài)更新(Lua 增強)
http {
# 基礎 geo 配置
geo $base_segment {
default unknown;
include /etc/nginx/geo_base.conf;
}
server {
location / {
access_by_lua_block {
local ipmatcher = require "resty.ipmatcher"
-- 1. 從 Redis/Consul 加載動態(tài) IP 段配置
local redis = require "resty.redis"
local red = redis:new()
red:connect("127.0.0.1", 6379)
-- 2. 獲取實時灰度配置
local gray_ips = red:smembers("gray:ip_segments")
local vip_ips = red:smembers("vip:ip_segments")
-- 3. 構建 IP 匹配器
local gray_matcher = ipmatcher.new(gray_ips)
local vip_matcher = ipmatcher.new(vip_ips)
-- 4. 精確匹配決策
local client_ip = ngx.var.remote_addr
if vip_matcher:match(client_ip) then
ngx.var.target_group = "backend_vip"
ngx.var.priority = "100"
elseif gray_matcher:match(client_ip) then
ngx.var.target_group = "backend_gray"
ngx.var.priority = "50"
else
ngx.var.target_group = "backend_default"
ngx.var.priority = "0"
end
}
set $target_group "";
set $priority "";
proxy_pass http://$target_group;
proxy_set_header X-Router-Priority $priority;
}
}
}關鍵配置技巧
1. 外部文件管理 IP 段
# /etc/nginx/geo_segments.conf
geo $segment {
default default;
# 通過 include 分離配置,支持熱更新(nginx -s reload)
include /etc/nginx/ip_segments/*.conf;
}
# /etc/nginx/ip_segments/corp.conf
192.168.0.0/16 corp;
10.0.0.0/8 corp;
# /etc/nginx/ip_segments/whitelist.conf
203.0.113.0/24 trusted;
198.51.100.0/24 trusted;2. 多級回退策略
map "$geo_segment:$cookie_user_tier:$arg_version" $route_target {
# 優(yōu)先級:URL 參數(shù) > Cookie > IP 段 > 默認
default "prod";
"~*:(vip|enterprise):.*" "vip"; # Cookie 標記 VIP
"~*:.*:preview" "preview"; # URL 參數(shù)強制預覽版
"partner:.*:.*" "partner";
"internal:.*:.*" "internal";
}3. 與 DNS 動態(tài)解析結合
http {
resolver 10.0.0.2 valid=10s;
geo $region_code {
default ap;
1.0.0.0/8 us; # Cloudflare 美國段示例
103.21.244.0/22 ap; # Cloudflare 亞太段
}
map $region_code $backend_host {
us "us-west.internal";
ap "ap-southeast.internal";
eu "eu-central.internal";
}
server {
location / {
# 動態(tài)解析 + 地域路由
set $target "http://$backend_host:8080";
proxy_pass $target;
}
}
}性能優(yōu)化要點
| 優(yōu)化項 | 配置 | 說明 |
|---|---|---|
| Geo 數(shù)據(jù)庫 | geoip_module 或 geo | 超過 1000 條 CIDR 使用 geo 模塊的 radix tree |
| 緩存匹配結果 | map 變量持久化 | 同連接復用變量值(HTTP/2 多路復用注意) |
| 異步更新 | lua-resty-core | 避免 reload 頻繁,使用共享內(nèi)存熱更新 |
| 監(jiān)控埋點 | log_format | 記錄 $geo_segment 用于分析路由準確性 |
# 路由決策日志
log_format routing '$remote_addr - $geo_segment -> $route_target '
'[$time_local] "$request" '
'upstream=$upstream_addr '
'decision_time=$request_time';
access_log /var/log/nginx/routing.log routing;核心要點:geo 負責 IP→分類的匹配,map 負責分類→行為的映射,兩者組合實現(xiàn)聲明式路由策略,比 if 指令性能高且可維護性強。
到此這篇關于Nginx map實現(xiàn)基于客戶端 IP 段的動態(tài)后端路由的幾種方法實現(xiàn)的文章就介紹到這了,更多相關Nginx 客戶端 IP動態(tài)后端路由內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
nginx的location配置導致網(wǎng)關返回404問題
這篇文章主要介紹了nginx的location配置導致網(wǎng)關返回404問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-06-06
Nginx出現(xiàn)404 Not Found nginx/1.23.4的完美解決方案
在Nginx配置過程中,404 Not Found錯誤是一個常見問題,本文將詳細解析Nginx 404 Not Found的原因及解決方案,確保您能夠輕松解決這一問題,需要的小伙伴跟著小編一起來學習學習吧2024-07-07
Nginx 代理轉發(fā)阿里云OSS上傳的實現(xiàn)代碼
這篇文章主要介紹了Nginx 代理轉發(fā)阿里云OSS上傳的實現(xiàn)代碼,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-09-09

