apisix源码分析-route的匹配(6)
route 是如何匹配的?
Route 中主要包含三部分内容:匹配规则(比如 uri、host、remote_addr 等),插件配置(限流限速等)和上游信息,通过 init_worker 阶段对 etcd 的监控,route 节点的数据同步到了user_routes的变量中,默认执行 http/router/radixtree_uri.lua
匹配规则 ,还可以使用 radixtree_host_uri
和 radixtree_uri_with_parameter
。通过实现 match(api_ctx) 方法实现查询替换。
在 apisix 中使用了 redixtree 来实现路由匹配、域名证书、admin route 的匹配。 redixtree 相关分析可以看相关的分析。通过存储不同的path,来实现不同的需求。
radixtree_uri
paths = route.value.uris or route.value.uri,
在radixtree_uri 中直接使用了uri,也就是直接使用了请求的路径部分在 redixtree 中做匹配
radixtree_host_uri
建立了两层 redixtree 来做 route 查询,第一层使用域名作为 path 创建 redixtree 和ssl的域名查询相同)。在域名对应的 key 在创建 uri 的 redixtree。形成两层查询。
radixtree_uri_with_parameter (未实现)
access 的执行
当获取到匹配的 route 后,就可以得到 route、plugin、service 等信息。这些信息会存储在变量api_ctx 中
1 | api_ctx.matched_route = route |
对于插件有两种,列表或者通过编排的。
当发现 route.value.script
不为空时,会执行通过编排生成的 lua 脚本。
为空时执行插件列表。在执行插件列表时执行了会执行如下代码:
1 | plugin.run_plugin("rewrite", plugins, api_ctx) |
在这里可以发现,apisix 的插件的 rewrite 和 access 都是在 openresty 的 access 阶段执行的
在配置的时候我们会有默认插件,Consumer 绑定的插件, Route 绑定的插件,Service 绑定的插件。只列出插件 merge 操作,根据插件优先级的说明,同样的插件只会有一份有效,相同的插件会做合并。Plugin
配置可直接绑定在 Route
上,也可以被绑定在 Service
或 Consumer
上。而对于同一 个插件的配置,只能有一份是有效的,配置选择优先级总是 Consumer
> Route
> Service
。在 access 执行过程中可以看到如下的合并过程。
1 | if route.value.plugin_config_id then |
apisix源码分析-route的匹配(6)