apisix~proxy-rewrite 的 regex_uri 深度解析

APISIX 路由正则与 proxy-rewrite 的 regex_uri 深度解析

在 APISIX 中,proxy-rewrite 插件的 regex_uri 功能是实现复杂路由重写的核心工具。下面我将全面总结各种转发场景的使用方法和技巧。

regex_uri 基础语法

"regex_uri": ["匹配正则", "替换模板"]
  • 匹配正则:PCRE 格式的正则表达式
  • 替换模板:使用 $1, $2 等引用捕获组

常见转发场景总结

场景 1:简单前缀替换

"regex_uri": ["^/api/v1/(.*)", "/backend/$1"]

请求转换:

  • /api/v1/users/backend/users
  • /api/v1/products/123/backend/products/123

场景 2:多段路径重组

"regex_uri": ["^/user/([^/]+)/profile/(.*)", "/profile/$1/$2"]

请求转换:

  • /user/john/profile/settings/profile/john/settings
  • /user/mary/profile/preferences/profile/mary/preferences

场景 3:版本号升级

"regex_uri": ["^/v1/(.*)", "/v2/$1"]

请求转换:

  • /v1/orders/v2/orders
  • /v1/inventory/items/v2/inventory/items

场景 4:路径参数提取

"regex_uri": ["^/product/(\\d+)/detail", "/items/$1"]

请求转换:

  • /product/123/detail/items/123
  • /product/456/detail/items/456

场景 5:多条件组合匹配

"regex_uri": ["^/(user|product)/(create|delete)/([a-z]+)", "/action/$2/$1/$3"]

请求转换:

  • /user/create/account/action/create/user/account
  • /product/delete/item/action/delete/product/item

场景 6:保留查询参数

"regex_uri": ["^/search/(.*)", "/query/$1"]

请求转换:

  • /search/books?category=sci-fi/query/books?category=sci-fi
  • /search/movies?year=2023/query/movies?year=2023

场景 7:路径规范化

"regex_uri": ["^/([a-z]{2})/([a-z]+)/?$", "/$2/$1"]

请求转换:

  • /en/home/home/en
  • /es/about/about/es

场景 8:复杂重写模式

"regex_uri": ["^/(?:api|service)/v(\\d+)/(.*)", "/v$1/$2"]

请求转换:

  • /api/v2/users/v2/users
  • /service/v3/products/v3/products

高级应用场景

场景 9:条件重写(配合 vars)

"plugins": {
    "proxy-rewrite": {
        "regex_uri": ["^/user/(.*)", "/$1"],
        "vars": [
            ["http_x_api_version", "==", "v2"]
        ]
    }
}

仅当请求头 X-API-Version: v2 时生效

场景 10:多重正则组合

"plugins": [
    {
        "proxy-rewrite": {
            "regex_uri": ["^/api/", "/"]
        }
    },
    {
        "proxy-rewrite": {
            "regex_uri": ["^/v1/", "/v2/"]
        }
    }
]

分阶段重写:

  1. /api/v1/users/v1/users
  2. /v1/users/v2/users

场景 11:正则与直接 URI 重写结合

"plugins": {
    "proxy-rewrite": {
        "uri": "/new-base",
        "regex_uri": ["^/old/(.*)", "/$1"]
    }
}

组合效果:

  • /old/path/new-base/path
  • /other/new-base/other

性能优化技巧

  1. 非捕获组优化:使用 (?:) 代替 () 避免不必要的捕获

    "regex_uri": ["^/(?:api|service)/v(\\d+)/(.*)", "/v$1/$2"]
    
  2. 避免贪婪匹配:使用 .*? 代替 .* 防止过度匹配

    "regex_uri": ["^/category/(.*?)/(detail)", "/$2/$1"]
    
  3. 精确锚定:使用 ^$ 限定匹配范围

    "regex_uri": ["^/exact/path$", "/new/exact"]
    

调试与测试方法

1. 使用 curl 测试

curl "http://127.0.0.1:9080/apisix/admin/plugin_metadata/proxy-rewrite" \
-H "X-API-KEY: your-admin-key" -X PUT -d '
{
    "regex_uri_debug": true
}'

2. 日志分析

在 error.log 中查看匹配详情:

2023/10/15 14:30:22 [debug] regex_uri match: pattern=^/api/(.*), uri=/api/v1/users, matches=1
2023/10/15 14:30:22 [debug] regex_uri replace: /api/v1/users -> /v1/users

3. 单元测试(Lua)

local rewrite = require("apisix.plugins.proxy-rewrite")
local ctx = {var = {uri = "/old/path"}}

rewrite.rewrite({regex_uri = {"^/old/(.*)", "/new/$1"}}, ctx)
ngx.say(ctx.var.uri) -- 输出: /new/path

常见问题解决方案

问题 1:正则不匹配

解决方案

  1. 使用在线正则测试器验证(如 regex101.com)
  2. 添加调试日志 regex_uri_debug: true
  3. 简化正则表达式,分步测试

问题 2:特殊字符转义

正确写法

"regex_uri": ["^/search\\?q=(.+)", "/query/$1"]

问题 3:保留原始路径

"regex_uri": ["", "$0"] -- 保留完整原始路径

问题 4:大小写敏感问题

"regex_uri": ["(?i)^/api/(.*)", "/$1"] -- 忽略大小写

最佳实践

  1. 路径标准化:在网关层统一路径格式

    "regex_uri": ["^/[A-Z]+/(.*)", "/${lower($1)}"]
    
  2. 版本控制:无缝升级 API 版本

    "regex_uri": ["^/v1/(.*)", "/v2/$1"]
    
  3. 多租户支持

    "regex_uri": ["^/([a-z0-9]+)/api/(.*)", "/tenants/$1/$2"]
    
  4. A/B 测试路由

    "regex_uri": ["^/service/(.*)", "/service-v2/$1"],
    "vars": [["http_x_test_group", "==", "B"]]
    
  5. 协议升级重定向

    "plugins": {
        "proxy-rewrite": {
            "regex_uri": ["^(.*)", "https://new-domain.com$1"],
            "scheme": "https"
        }
    }
    

性能对比表

方法复杂度适用场景性能影响
regex_uri中-高复杂路径转换中(PCRE 编译)
uri 直接替换简单前缀修改
多插件组合分阶段处理中-高
Nginx 原生 rewrite深度定制最低

建议:简单场景使用 uri 直接替换,复杂场景使用 regex_uri

自己项目中的使用

1. 静态改写,不需要正则

 "proxy-rewrite": {
      "uri": "/auth/realms/xx/protocol/openid-connect/token/introspect"
  }

2. 表达url一级路径的文件名,扩展名是.txt,例如:http://www.sina.com/1.txt

"proxy-rewrite": {
      "regex_uri": [
        "^/([^/]+\\.txt)$",
        "/auth/$1"
      ]
    }

3. 按前缀进行替换

"proxy-rewrite": {
    "regex_uri": [
        "^/user-xx(/.*)",
        "$1"
      ]
    }

4. 以某个前缀开头的,在转发时,在前缀前面添加固定字符,下面添加了apim-es到apim-admin的前面

"proxy-rewrite": {
     "regex_uri": [
        "\"^/apim-admin/(.*)\"",
        "/apim-es/$1"
      ]
    }
原创作者: lori 转载于: https://www.cnblogs.com/lori/p/18991485
<think>我们正在使用APISIXDashboard来配置路由规则。目标是创建一个路由,该路由能够匹配指向"bcf-web"服务的请求,并进行相应处理。在APISIX中,路由(Route)是通过定义匹配规则(如URI、主机头、HTTP方法等)来将请求转发到指定上游(Upstream)或直接响应的一种配置。配置步骤:1.登录APISIXDashboard。2.进入“路由”页面,点击“创建”按钮。3.填写路由的基本信息,例如路由名称(例如:bcf-web-route)。4.配置匹配规则:-匹配路径(Path):根据bcf-web服务的访问路径设置。例如,如果所有bcf-web服务的请求都以`/bcf-web`开头,则可以设置路径为`/bcf-web/*`。-其他匹配条件:如主机名(Host)、请求方法(Method)等,根据需求设置。例如,如果请求的Host头为`bcf-web.example.com`,则可以在Host字段中填写该值。5.配置上游(Upstream):选择或创建一个上游,指向bcf-web服务的后端服务器(包括IP和端口)。如果已有上游,可以直接选择;否则,需要先创建上游。6.如果需要,可以配置插件(如限流、认证等)。7.保存并发布路由。示例:创建一个路由,匹配路径为`/bcf-web/*`,且Host为`bcf-web.example.com`的请求,将其转发到上游服务`http://backend-server:8080`。具体操作:1.在路由配置页面,填写名称,例如:bcf-web-route。2.在“请求配置”中:-路径:填写`/bcf-web/*`-域名:填写`bcf-web.example.com`(如果没有域名要求,可以不填)-其他匹配条件按需填写。3.在“上游配置”中,选择已有上游或创建新的上游。创建上游时,填写后端服务器的地址(例如:`http://backend-server:8080`)和负载均衡策略等。4.在“插件配置”中,按需添加插件,例如:代理重写(proxy-rewrite)插件,用于重写请求路径(如果需要的话)。5.点击“提交”完成创建。注意:配置完成后,APISIX网关就会根据该路由规则将匹配的请求转发到指定的bcf-web服务。引用说明:APISIX官方文档提供了路由配置的详细说明[^1]。相关问题:1.如何在APISIX中配置HTTPS路由?2.APISIX路由支持哪些匹配条件?3.如何为路由配置认证插件(如JWT)?4.如何监控APISIX路由的流量?</think>### 在 APISIX Dashboard 中配置路由匹配规则捕获 bcf-web 请求 以下是配置路由匹配规则的核心步骤: 1. **登录 APISIX Dashboard** 访问 Dashboard 地址(如 `http://<apisix-dashboard-ip>:9000`),使用管理员账号登录。 2. **创建新路由** - 导航至 **路由** → **创建路由** - 在 **基本信息** 中填写路由名称(如 `bcf-web-route`) 3. **配置匹配规则** 在 **匹配规则** 区域配置以下关键参数: ```markdown | 匹配类型 | 示例值 | 说明 | |-------------|-------------------|-----------------------------| | 请求路径 | /bcf-web/* | 捕获所有以 /bcf-web 开头的请求 | | 域名/Host | bcf-web.example.com| 按域名过滤请求(可选) | | HTTP 方法 | GET,POST | 指定需要拦截的请求方法(可选) | ``` 4. **设置上游服务** - 在 **上游配置** 中选择目标服务: - 新建上游:填写 bcf-web 服务的实际地址(如 `http://bcf-web-service:8080`) - 或选择已存在的上游服务 - 配置负载均衡策略(默认轮询) 5. **添加处理插件(可选)** 在 **插件配置** 中按需启用: - `proxy-rewrite`:重写请求路径(如移除 `/bcf-web` 前缀) - `limit-count`:限流保护 ```json { "proxy-rewrite": { "regex_uri": ["^/bcf-web/(.*)", "/$1"] } } ``` 6. **保存并测试** - 点击 **提交** 保存配置 - 使用测试工具发送请求验证: ```bash curl http://<APISIX-IP>:9080/bcf-web/api/test -H "Host: bcf-web.example.com" ``` ### 关键配置说明 1. **路径匹配优先级** APISIX 按最长前缀优先匹配路由,确保 `/bcf-web/api` 比 `/bcf-web` 优先级更高[^1] 2. **动态生效机制** 配置通过 etcd 实时同步到 APISIX 节点,无需重启服务[^2] 3. **高级匹配模式** 支持 Nginx 原生变量匹配,如按请求头匹配: ```markdown 匹配条件:请求头包含 `X-Service-Type: bcf-web` ``` ### 常见问题排查 - **匹配失败**:检查 Dashboard 配置的路径规则是否包含多余空格 - **503 错误**:确认上游服务地址可达且端口正确 - **插件冲突**:禁用部分插件进行逐项测试 > 配置截图示例: > ![APISIX Dashboard 路由配置界面](https://example.com/apisix-route-config.png) > _图:路由匹配规则配置界面示意图[^3]_ --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值