mirror of
https://gitee.com/iresty/apisix.git
synced 2024-12-04 21:17:36 +08:00
docs: sync English doc to Chinese (#3796)
Signed-off-by: spacewander <spacewanderlzx@gmail.com>
This commit is contained in:
parent
8dcbe4e00d
commit
8609cd507a
@ -1,824 +0,0 @@
|
||||
---
|
||||
title: 架构设计
|
||||
---
|
||||
|
||||
<!--
|
||||
#
|
||||
# Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
# contributor license agreements. See the NOTICE file distributed with
|
||||
# this work for additional information regarding copyright ownership.
|
||||
# The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
# (the "License"); you may not use this file except in compliance with
|
||||
# the License. You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
-->
|
||||
|
||||
## 目录
|
||||
|
||||
- [目录](#目录)
|
||||
- [APISIX](#apisix)
|
||||
- [插件加载流程](#插件加载流程)
|
||||
- [插件内部结构](#插件内部结构)
|
||||
- [APISIX Config](#apisix-config)
|
||||
- [Route](#route)
|
||||
- [Service](#service)
|
||||
- [Plugin](#plugin)
|
||||
- [Script](#script)
|
||||
- [Upstream](#upstream)
|
||||
- [配置参数](#配置参数)
|
||||
- [Consumer](#consumer)
|
||||
- [Cookie](#cookie)
|
||||
- [Header](#header)
|
||||
- [Router](#router)
|
||||
- [Consumer](#consumer-1)
|
||||
- [Global Rule](#global-rule)
|
||||
- [Plugin Config](#plugin-config)
|
||||
- [Debug mode](#debug-mode)
|
||||
- [基本调试模式](#基本调试模式)
|
||||
- [高级调试模式](#高级调试模式)
|
||||
|
||||
## APISIX
|
||||
|
||||
### 插件加载流程
|
||||
|
||||
![插件加载流程](../../assets/images/flow-load-plugin.png)
|
||||
|
||||
### 插件内部结构
|
||||
|
||||
![插件内部结构](../../assets/images/flow-plugin-internal.png)
|
||||
|
||||
## APISIX Config
|
||||
|
||||
通过修改本地 `conf/config.yaml` 文件,或者在启动 APISIX 时使用 `-c` 或 `--config` 添加文件路径参数 `apisix start -c <path string>`,完成对 APISIX 服务本身的基本配置。
|
||||
|
||||
比如修改 APISIX 默认监听端口为 8000,其他配置保持默认,在 `config.yaml` 中只需这样配置:
|
||||
|
||||
```yaml
|
||||
apisix:
|
||||
node_listen: 8000 # APISIX listening port
|
||||
```
|
||||
|
||||
比如指定 APISIX 默认监听端口为 8000,并且设置 etcd 地址为 `http://foo:2379`,
|
||||
其他配置保持默认。在 `config.yaml` 中只需这样配置:
|
||||
|
||||
```yaml
|
||||
apisix:
|
||||
node_listen: 8000 # APISIX listening port
|
||||
|
||||
etcd:
|
||||
host: "http://foo:2379" # etcd address
|
||||
```
|
||||
|
||||
其他默认配置,可以在 `conf/config-default.yaml` 文件中看到,该文件是与 APISIX 源码强绑定,
|
||||
**永远不要**手工修改 `conf/config-default.yaml` 文件。如果需要自定义任何配置,都应在 `config.yaml` 文件中完成。
|
||||
|
||||
_注意_ 不要手工修改 APISIX 自身的 `conf/nginx.conf` 文件,当服务每次启动时,`apisix`
|
||||
会根据 `config.yaml` 配置自动生成新的 `conf/nginx.conf` 并自动启动服务。
|
||||
|
||||
[返回目录](#目录)
|
||||
|
||||
## Route
|
||||
|
||||
Route 字面意思就是路由,通过定义一些规则来匹配客户端的请求,然后根据匹配结果加载并执行相应的
|
||||
插件,并把请求转发给到指定 Upstream。
|
||||
|
||||
Route 中主要包含三部分内容:匹配规则(比如 uri、host、remote_addr 等),插件配置(限流限速等)和上游信息。
|
||||
请看下图示例,是一些 Route 规则的实例,当某些属性值相同时,图中用相同颜色标识。
|
||||
|
||||
![路由示例](../../assets/images/routes-example.png)
|
||||
|
||||
我们直接在 Route 中完成所有参数的配置,优点是容易设置,每个 Route 都相对独立自由度比较高。但当我们的 Route 有比较多的重复配置(比如启用相同的插件配置或上游信息),一旦我们要更新这些相同属性时,就需要遍历所有 Route 并进行修改,给后期管理维护增加不少复杂度。
|
||||
|
||||
上面提及重复的缺点在 APISIX 中独立抽象了 [Service](#service) 和 [Upstream](#upstream) 两个概念来解决。
|
||||
|
||||
下面创建的 Route 示例,是把 URL 为 "/index.html" 的请求代理到地址为 "39.97.63.215:80" 的 Upstream 服务:
|
||||
|
||||
```shell
|
||||
$ curl http://127.0.0.1:9080/apisix/admin/routes/1 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -i -d '
|
||||
{
|
||||
"uri": "/index.html",
|
||||
"upstream": {
|
||||
"type": "roundrobin",
|
||||
"nodes": {
|
||||
"39.97.63.215:80": 1
|
||||
}
|
||||
}
|
||||
}'
|
||||
|
||||
HTTP/1.1 201 Created
|
||||
Date: Sat, 31 Aug 2019 01:17:15 GMT
|
||||
Content-Type: text/plain
|
||||
Transfer-Encoding: chunked
|
||||
Connection: keep-alive
|
||||
Server: APISIX web server
|
||||
|
||||
{"node":{"value":{"uri":"\/index.html","upstream":{"nodes":{"39.97.63.215:80":1},"type":"roundrobin"}},"createdIndex":61925,"key":"\/apisix\/routes\/1","modifiedIndex":61925},"action":"create"}
|
||||
```
|
||||
|
||||
当我们接收到成功应答,表示该 Route 已成功创建。
|
||||
|
||||
有关 Route 的具体选项,可具体查阅 [Admin API 之 Route](admin-api.md#route)。
|
||||
|
||||
[返回目录](#目录)
|
||||
|
||||
## Service
|
||||
|
||||
`Service` 是某类 API 的抽象(也可以理解为一组 Route 的抽象)。它通常与上游服务抽象是一一对应的,`Route`
|
||||
与 `Service` 之间,通常是 N:1 的关系,参看下图。
|
||||
|
||||
![服务示例](../../assets/images/service-example.png)
|
||||
|
||||
不同 Route 规则同时绑定到一个 Service 上,这些 Route 将具有相同的上游和插件配置,减少冗余配置。
|
||||
|
||||
比如下面的例子,创建了一个启用限流插件的 Service,然后把 id 为 `100`、`101` 的 Route 都绑定在这个 Service 上。
|
||||
|
||||
```shell
|
||||
# create new Service
|
||||
$ curl http://127.0.0.1:9080/apisix/admin/services/200 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
|
||||
{
|
||||
"plugins": {
|
||||
"limit-count": {
|
||||
"count": 2,
|
||||
"time_window": 60,
|
||||
"rejected_code": 503,
|
||||
"key": "remote_addr"
|
||||
}
|
||||
},
|
||||
"upstream": {
|
||||
"type": "roundrobin",
|
||||
"nodes": {
|
||||
"39.97.63.215:80": 1
|
||||
}
|
||||
}
|
||||
}'
|
||||
|
||||
# create new Route and reference the service by id `200`
|
||||
curl http://127.0.0.1:9080/apisix/admin/routes/100 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
|
||||
{
|
||||
"methods": ["GET"],
|
||||
"uri": "/index.html",
|
||||
"service_id": "200"
|
||||
}'
|
||||
|
||||
curl http://127.0.0.1:9080/apisix/admin/routes/101 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
|
||||
{
|
||||
"methods": ["GET"],
|
||||
"uri": "/foo/index.html",
|
||||
"service_id": "200"
|
||||
}'
|
||||
```
|
||||
|
||||
当然我们也可以为 Route 指定不同的插件参数或上游,比如下面这个 Route 设置了不同的限流参数,其他部分(比如上游)则继续使用 Service 中的配置参数。
|
||||
|
||||
```shell
|
||||
curl http://127.0.0.1:9080/apisix/admin/routes/102 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
|
||||
{
|
||||
"uri": "/bar/index.html",
|
||||
"id": "102",
|
||||
"service_id": "200",
|
||||
"plugins": {
|
||||
"limit-count": {
|
||||
"count": 2000,
|
||||
"time_window": 60,
|
||||
"rejected_code": 503,
|
||||
"key": "remote_addr"
|
||||
}
|
||||
}
|
||||
}'
|
||||
```
|
||||
|
||||
注意:当 Route 和 Service 都开启同一个插件时,Route 参数的优先级是高于 Service 的。
|
||||
|
||||
[返回目录](#目录)
|
||||
|
||||
## Plugin
|
||||
|
||||
`Plugin` 表示将在 `HTTP` 请求/响应生命周期期间执行的插件配置。
|
||||
|
||||
`Plugin` 配置可直接绑定在 `Route` 上,也可以被绑定在 `Service` 或 `Consumer`上。而对于同一
|
||||
个插件的配置,只能有一份是有效的,配置选择优先级总是 `Consumer` > `Route` > `Service`。
|
||||
|
||||
在 `conf/config.yaml` 中,可以声明本地 APISIX 节点都支持哪些插件。这是个白名单机制,不在该
|
||||
白名单的插件配置,都将会被自动忽略。这个特性可用于临时关闭或打开特定插件,应对突发情况非常有效。
|
||||
如果你想在现有插件的基础上新增插件,注意需要拷贝 `conf/config-default.yaml` 的插件节点内容到 `conf/config.yaml` 的插件节点中。
|
||||
|
||||
插件的配置可以被直接绑定在指定 Route 中,也可以被绑定在 Service 中,不过 Route 中的插件配置
|
||||
优先级更高。
|
||||
|
||||
一个插件在一次请求中只会执行一次,即使被同时绑定到多个不同对象中(比如 Route 或 Service)。
|
||||
插件运行先后顺序是根据插件自身的优先级来决定的,例如:
|
||||
|
||||
```lua
|
||||
local _M = {
|
||||
version = 0.1,
|
||||
priority = 0, -- 这个插件的优先级为 0
|
||||
name = plugin_name,
|
||||
schema = schema,
|
||||
metadata_schema = metadata_schema,
|
||||
}
|
||||
```
|
||||
|
||||
插件配置作为 Route 或 Service 的一部分提交的,放到 `plugins` 下。它内部是使用插件
|
||||
名字作为哈希的 key 来保存不同插件的配置项。
|
||||
|
||||
```json
|
||||
{
|
||||
...
|
||||
"plugins": {
|
||||
"limit-count": {
|
||||
"count": 2,
|
||||
"time_window": 60,
|
||||
"rejected_code": 503,
|
||||
"key": "remote_addr"
|
||||
},
|
||||
"prometheus": {}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
并不是所有插件都有具体配置项,比如 `prometheus` 下是没有任何具体配置项,这时候用一个空的对象
|
||||
标识即可。
|
||||
|
||||
如果一个请求因为某个插件而被拒绝,会有类似这样的 warn 日志:`ip-restriction exits with http status code 403`。
|
||||
|
||||
[查看 APISIX 已支持插件列表](plugins.md)
|
||||
|
||||
[返回目录](#目录)
|
||||
|
||||
## Script
|
||||
|
||||
`Script` 表示将在 `HTTP` 请求/响应生命周期期间执行的脚本。
|
||||
|
||||
`Script` 配置可直接绑定在 `Route` 上。
|
||||
|
||||
`Script` 与 `Plugin` 互斥,且优先执行 `Script` ,这意味着配置 `Script` 后,`Route` 上配置的 `Plugin` 将不被执行。
|
||||
|
||||
理论上,在 `Script` 中可以写任意 lua 代码,也可以直接调用已有插件以重用已有的代码。
|
||||
|
||||
`Script` 也有执行阶段概念,支持 `access`、`header_filter`、`body_filter` 和 `log` 阶段。系统会在相应阶段中自动执行 `Script` 脚本中对应阶段的代码。
|
||||
|
||||
```json
|
||||
{
|
||||
...
|
||||
"script": "local _M = {} \n function _M.access(api_ctx) \n ngx.log(ngx.INFO,\"hit access phase\") \n end \nreturn _M"
|
||||
}
|
||||
```
|
||||
|
||||
[返回目录](#目录)
|
||||
|
||||
## Upstream
|
||||
|
||||
Upstream 是虚拟主机抽象,对给定的多个服务节点按照配置规则进行负载均衡。Upstream 的地址信息可以直接配置到 `Route`(或 `Service`) 上,当 Upstream 有重复时,就需要用“引用”方式避免重复了。
|
||||
|
||||
![Upstream 示例](../../assets/images/upstream-example.png)
|
||||
|
||||
如上图所示,通过创建 Upstream 对象,在 `Route` 用 ID 方式引用,就可以确保只维护一个对象的值了。
|
||||
|
||||
Upstream 的配置可以被直接绑定在指定 `Route` 中,也可以被绑定在 `Service` 中,不过 `Route` 中的配置
|
||||
优先级更高。这里的优先级行为与 `Plugin` 非常相似
|
||||
|
||||
### 配置参数
|
||||
|
||||
APISIX 的 Upstream 除了基本的复杂均衡算法选择外,还支持对上游做主被动健康检查、重试等逻辑,具体看下面的链接。
|
||||
|
||||
https://github.com/apache/apisix/blob/master/docs/zh/latest/admin-api.md#upstream
|
||||
|
||||
创建上游对象用例:
|
||||
|
||||
```json
|
||||
curl http://127.0.0.1:9080/apisix/admin/upstreams/1 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
|
||||
{
|
||||
"type": "chash",
|
||||
"key": "remote_addr",
|
||||
"nodes": {
|
||||
"127.0.0.1:80": 1,
|
||||
"foo.com:80": 2
|
||||
}
|
||||
}'
|
||||
```
|
||||
|
||||
上游对象创建后,均可以被具体 `Route` 或 `Service` 引用,例如:
|
||||
|
||||
```shell
|
||||
curl http://127.0.0.1:9080/apisix/admin/routes/1 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
|
||||
{
|
||||
"uri": "/index.html",
|
||||
"upstream_id": 2
|
||||
}'
|
||||
```
|
||||
|
||||
为了方便使用,也可以直接把上游地址直接绑到某个 `Route` 或 `Service` ,例如:
|
||||
|
||||
```shell
|
||||
curl http://127.0.0.1:9080/apisix/admin/routes/1 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
|
||||
{
|
||||
"uri": "/index.html",
|
||||
"plugins": {
|
||||
"limit-count": {
|
||||
"count": 2,
|
||||
"time_window": 60,
|
||||
"rejected_code": 503,
|
||||
"key": "remote_addr"
|
||||
}
|
||||
},
|
||||
"upstream": {
|
||||
"type": "roundrobin",
|
||||
"nodes": {
|
||||
"39.97.63.215:80": 1
|
||||
}
|
||||
}
|
||||
}'
|
||||
```
|
||||
|
||||
下面是一个配置了健康检查的示例:
|
||||
|
||||
```shell
|
||||
curl http://127.0.0.1:9080/apisix/admin/routes/1 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
|
||||
{
|
||||
"uri": "/index.html",
|
||||
"plugins": {
|
||||
"limit-count": {
|
||||
"count": 2,
|
||||
"time_window": 60,
|
||||
"rejected_code": 503,
|
||||
"key": "remote_addr"
|
||||
}
|
||||
},
|
||||
"upstream": {
|
||||
"nodes": {
|
||||
"39.97.63.215:80": 1
|
||||
}
|
||||
"type": "roundrobin",
|
||||
"retries": 2,
|
||||
"checks": {
|
||||
"active": {
|
||||
"http_path": "/status",
|
||||
"host": "foo.com",
|
||||
"healthy": {
|
||||
"interval": 2,
|
||||
"successes": 1
|
||||
},
|
||||
"unhealthy": {
|
||||
"interval": 1,
|
||||
"http_failures": 2
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}'
|
||||
```
|
||||
|
||||
更多细节可以参考[健康检查的文档](./health-check.md)。
|
||||
|
||||
下面是几个使用不同`hash_on`类型的配置示例:
|
||||
|
||||
#### Consumer
|
||||
|
||||
创建一个 consumer 对象:
|
||||
|
||||
```shell
|
||||
curl http://127.0.0.1:9080/apisix/admin/consumers -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
|
||||
{
|
||||
"username": "jack",
|
||||
"plugins": {
|
||||
"key-auth": {
|
||||
"key": "auth-jack"
|
||||
}
|
||||
}
|
||||
}'
|
||||
```
|
||||
|
||||
新建路由,打开`key-auth`插件认证,`upstream`的`hash_on`类型为`consumer`:
|
||||
|
||||
```shell
|
||||
curl http://127.0.0.1:9080/apisix/admin/routes/1 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
|
||||
{
|
||||
"plugins": {
|
||||
"key-auth": {}
|
||||
},
|
||||
"upstream": {
|
||||
"nodes": {
|
||||
"127.0.0.1:1980": 1,
|
||||
"127.0.0.1:1981": 1
|
||||
},
|
||||
"type": "chash",
|
||||
"hash_on": "consumer"
|
||||
},
|
||||
"uri": "/server_port"
|
||||
}'
|
||||
```
|
||||
|
||||
测试请求,认证通过后的`consumer_name`将作为负载均衡哈希算法的哈希值:
|
||||
|
||||
```shell
|
||||
curl http://127.0.0.1:9080/server_port -H "apikey: auth-jack"
|
||||
```
|
||||
|
||||
##### Cookie
|
||||
|
||||
新建路由和`Upstream`,`hash_on`类型为`cookie`:
|
||||
|
||||
```shell
|
||||
curl http://127.0.0.1:9080/apisix/admin/routes/1 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
|
||||
{
|
||||
"uri": "/hash_on_cookie",
|
||||
"upstream": {
|
||||
"key": "sid",
|
||||
"type ": "chash",
|
||||
"hash_on ": "cookie",
|
||||
"nodes ": {
|
||||
"127.0.0.1:1980": 1,
|
||||
"127.0.0.1:1981": 1
|
||||
}
|
||||
}
|
||||
}'
|
||||
```
|
||||
|
||||
客户端请求携带`Cookie`:
|
||||
|
||||
```shell
|
||||
curl http://127.0.0.1:9080/hash_on_cookie -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -H "Cookie: sid=3c183a30cffcda1408daf1c61d47b274"
|
||||
```
|
||||
|
||||
##### Header
|
||||
|
||||
新建路由和`Upstream`,`hash_on`类型为`header`, `key`为`content-type`:
|
||||
|
||||
```shell
|
||||
curl http://127.0.0.1:9080/apisix/admin/routes/1 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
|
||||
{
|
||||
"uri": "/hash_on_header",
|
||||
"upstream": {
|
||||
"key": "content-type",
|
||||
"type ": "chash",
|
||||
"hash_on ": "header",
|
||||
"nodes ": {
|
||||
"127.0.0.1:1980": 1,
|
||||
"127.0.0.1:1981": 1
|
||||
}
|
||||
}
|
||||
}'
|
||||
```
|
||||
|
||||
客户端请求携带`content-type`的`header`:
|
||||
|
||||
```shell
|
||||
curl http://127.0.0.1:9080/hash_on_header -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -H "Content-Type: application/json"
|
||||
```
|
||||
|
||||
[返回目录](#目录)
|
||||
|
||||
## Router
|
||||
|
||||
APISIX 区别于其他 API 网关的一大特点是允许用户选择不同 Router 来更好匹配自由业务,在性能、自由之间做最适合选择。
|
||||
|
||||
在本地配置 `conf/config.yaml` 中设置最符合自身业务需求的路由。
|
||||
|
||||
- `apisix.router.http`: HTTP 请求路由。
|
||||
|
||||
- `radixtree_uri`: (默认)只使用 `uri` 作为主索引。基于 `radixtree` 引擎,支持全量和深前缀匹配,更多见 [如何使用 router-radixtree](../../en/latest/router-radixtree.md)。
|
||||
- `绝对匹配`:完整匹配给定的 `uri` ,比如 `/foo/bar`,`/foo/glo`。
|
||||
- `前缀匹配`:末尾使用 `*` 代表给定的 `uri` 是前缀匹配。比如 `/foo*`,则允许匹配 `/foo/`、`/foo/a`和`/foo/b`等。
|
||||
- `匹配优先级`:优先尝试绝对匹配,若无法命中绝对匹配,再尝试前缀匹配。
|
||||
- `任意过滤属性`:允许指定任何 Nginx 内置变量作为过滤条件,比如 URL 请求参数、请求头、cookie 等。
|
||||
- `radixtree_uri_with_parameter`: 同 `radixtree_uri` 但额外有参数匹配的功能。
|
||||
- `radixtree_host_uri`: 使用 `host + uri` 作为主索引(基于 `radixtree` 引擎),对当前请求会同时匹配 host 和 uri,支持的匹配条件与 `radixtree_uri` 基本一致。
|
||||
|
||||
- `apisix.router.ssl`: SSL 加载匹配路由。
|
||||
- `radixtree_sni`: (默认)使用 `SNI` (Server Name Indication) 作为主索引(基于 radixtree 引擎)。
|
||||
|
||||
[返回目录](#目录)
|
||||
|
||||
## Consumer
|
||||
|
||||
对于 API 网关通常可以用请求域名、客户端 IP 地址等字段识别到某类请求方,
|
||||
然后进行插件过滤并转发请求到指定上游,但有时候这个深度不够。
|
||||
|
||||
![Consumer](../../assets/images/consumer-who.png)
|
||||
|
||||
如上图所示,作为 API 网关,需要知道 API Consumer(消费方)具体是谁,这样就可以对不同 API Consumer 配置不同规则。
|
||||
|
||||
| 字段 | 必选 | 说明 |
|
||||
| -------- | ---- | -------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| username | 是 | Consumer 名称。 |
|
||||
| plugins | 否 | 该 Consumer 对应的插件配置,它的优先级是最高的:Consumer > Route > Service。对于具体插件配置,可以参考 [Plugins](#plugin) 章节。 |
|
||||
|
||||
在 APISIX 中,识别 Consumer 的过程如下图:
|
||||
|
||||
![Consumer Internal](../../assets/images/consumer-internal.png)
|
||||
|
||||
1. 授权认证:比如有 [key-auth](plugins/key-auth.md)、[JWT](plugins/jwt-auth.md) 等。
|
||||
2. 获取 consumer_name:通过授权认证,即可自然获取到对应的 Consumer name,它是 Consumer 对象的唯一识别标识。
|
||||
3. 获取 Consumer 上绑定的 Plugin 或 Upstream 信息:完成对不同 Consumer 做不同配置的效果。
|
||||
|
||||
概括一下,Consumer 是某类服务的消费者,需与用户认证体系配合才能使用。
|
||||
比如不同的 Consumer 请求同一个 API,网关服务根据当前请求用户信息,对应不同的 Plugin 或 Upstream 配置。
|
||||
|
||||
此外,大家也可以参考 [key-auth](plugins/key-auth.md) 认证授权插件的调用逻辑,辅助大家来进一步理解 Consumer 概念和使用。
|
||||
|
||||
如何对某个 Consumer 开启指定插件,可以看下面例子:
|
||||
|
||||
```shell
|
||||
# 创建 Consumer ,指定认证插件 key-auth ,并开启特定插件 limit-count
|
||||
$ curl http://127.0.0.1:9080/apisix/admin/consumers -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
|
||||
{
|
||||
"username": "jack",
|
||||
"plugins": {
|
||||
"key-auth": {
|
||||
"key": "auth-one"
|
||||
},
|
||||
"limit-count": {
|
||||
"count": 2,
|
||||
"time_window": 60,
|
||||
"rejected_code": 503,
|
||||
"key": "remote_addr"
|
||||
}
|
||||
}
|
||||
}'
|
||||
|
||||
# 创建 Router,设置路由规则和启用插件配置
|
||||
$ curl http://127.0.0.1:9080/apisix/admin/routes/1 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
|
||||
{
|
||||
"plugins": {
|
||||
"key-auth": {}
|
||||
},
|
||||
"upstream": {
|
||||
"nodes": {
|
||||
"127.0.0.1:1980": 1
|
||||
},
|
||||
"type": "roundrobin"
|
||||
},
|
||||
"uri": "/hello"
|
||||
}'
|
||||
|
||||
# 发测试请求,前两次返回正常,没达到限速阈值
|
||||
$ curl http://127.0.0.1:9080/hello -H 'apikey: auth-one' -I
|
||||
...
|
||||
|
||||
$ curl http://127.0.0.1:9080/hello -H 'apikey: auth-one' -I
|
||||
...
|
||||
|
||||
# 第三次测试返回 503,请求被限制
|
||||
$ curl http://127.0.0.1:9080/hello -H 'apikey: auth-one' -I
|
||||
HTTP/1.1 503 Service Temporarily Unavailable
|
||||
...
|
||||
|
||||
```
|
||||
|
||||
结合 [consumer-restriction](plugins/consumer-restriction.md) 插件,限制 jack 对该 route 的访问
|
||||
|
||||
```shell
|
||||
# 设置黑名单,禁止jack访问该API
|
||||
|
||||
$ curl http://127.0.0.1:9080/apisix/admin/routes/1 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
|
||||
{
|
||||
"plugins": {
|
||||
"key-auth": {},
|
||||
"consumer-restriction": {
|
||||
"blacklist": [
|
||||
"jack"
|
||||
]
|
||||
}
|
||||
},
|
||||
"upstream": {
|
||||
"nodes": {
|
||||
"127.0.0.1:1980": 1
|
||||
},
|
||||
"type": "roundrobin"
|
||||
},
|
||||
"uri": "/hello"
|
||||
}'
|
||||
|
||||
# 反复测试,均返回 403,jack被禁止访问
|
||||
$ curl http://127.0.0.1:9080/hello -H 'apikey: auth-one' -I
|
||||
HTTP/1.1 403
|
||||
...
|
||||
|
||||
```
|
||||
|
||||
[返回目录](#目录)
|
||||
|
||||
## Global Rule
|
||||
|
||||
[Plugin](#plugin) 只能绑定在 [Service](#service) 或者 [Route](#route) 上,如果我们需要一个能作用于所有请求的 [Plugin](#plugin) 该怎么办呢?
|
||||
这时候我们可以使用 `GlobalRule` 来注册一个全局的 [Plugin](#plugin):
|
||||
|
||||
```shell
|
||||
curl -X PUT \
|
||||
https://{apisix_listen_address}/apisix/admin/global_rules/1 \
|
||||
-H 'Content-Type: application/json' \
|
||||
-H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' \
|
||||
-d '{
|
||||
"plugins": {
|
||||
"limit-count": {
|
||||
"time_window": 60,
|
||||
"policy": "local",
|
||||
"count": 2,
|
||||
"key": "remote_addr",
|
||||
"rejected_code": 503
|
||||
}
|
||||
}
|
||||
}'
|
||||
```
|
||||
|
||||
如上所注册的 `limit-count` 插件将会作用于所有的请求。
|
||||
|
||||
我们可以通过以下接口查看所有的 `GlobalRule`:
|
||||
|
||||
```shell
|
||||
curl https://{apisix_listen_address}/apisix/admin/global_rules -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1'
|
||||
```
|
||||
|
||||
[返回目录](#目录)
|
||||
|
||||
## Plugin Config
|
||||
|
||||
如果你想要复用一组通用的插件配置,你可以把它们提取成一个 Plugin config,并绑定到对应的路由上。
|
||||
|
||||
举个例子,你可以这么做:
|
||||
|
||||
```shell
|
||||
# 创建 Plugin config
|
||||
$ curl http://127.0.0.1:9080/apisix/admin/plugin_configs/1 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -i -d '
|
||||
{
|
||||
"desc": "吾乃插件配置1",
|
||||
"plugins": {
|
||||
"limit-count": {
|
||||
"count": 2,
|
||||
"time_window": 60,
|
||||
"rejected_code": 503
|
||||
}
|
||||
}
|
||||
}'
|
||||
|
||||
# 绑定到路由上
|
||||
$ curl http://127.0.0.1:9080/apisix/admin/routes/1 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -i -d '
|
||||
{
|
||||
"uris": ["/index.html"],
|
||||
"plugin_config_id": 1,
|
||||
"upstream": {
|
||||
"type": "roundrobin",
|
||||
"nodes": {
|
||||
"39.97.63.215:80": 1
|
||||
}
|
||||
}
|
||||
}'
|
||||
```
|
||||
|
||||
如果找不到对应的 Plugin config,该路由上的请求会报 503 错误。
|
||||
|
||||
如果这个路由已经配置了 `plugins`,那么 Plugin config 里面的插件配置会合并进去。
|
||||
相同的插件会覆盖掉 `plugins` 原有的插件。
|
||||
|
||||
举个例子:
|
||||
|
||||
```
|
||||
{
|
||||
"desc": "吾乃插件配置1",
|
||||
"plugins": {
|
||||
"ip-restriction": {
|
||||
"whitelist": [
|
||||
"127.0.0.0/24",
|
||||
"113.74.26.106"
|
||||
]
|
||||
},
|
||||
"limit-count": {
|
||||
"count": 2,
|
||||
"time_window": 60,
|
||||
"rejected_code": 503
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
-
|
||||
|
||||
```
|
||||
{
|
||||
"uris": ["/index.html"],
|
||||
"plugin_config_id": 1,
|
||||
"upstream": {
|
||||
"type": "roundrobin",
|
||||
"nodes": {
|
||||
"39.97.63.215:80": 1
|
||||
}
|
||||
}
|
||||
"plugins": {
|
||||
"proxy-rewrite": {
|
||||
"uri": "/test/add",
|
||||
"scheme": "https",
|
||||
"host": "apisix.iresty.com"
|
||||
},
|
||||
"limit-count": {
|
||||
"count": 20,
|
||||
"time_window": 60,
|
||||
"rejected_code": 503,
|
||||
"key": "remote_addr"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
=
|
||||
|
||||
```
|
||||
{
|
||||
"uris": ["/index.html"],
|
||||
"upstream": {
|
||||
"type": "roundrobin",
|
||||
"nodes": {
|
||||
"39.97.63.215:80": 1
|
||||
}
|
||||
}
|
||||
"plugins": {
|
||||
"ip-restriction": {
|
||||
"whitelist": [
|
||||
"127.0.0.0/24",
|
||||
"113.74.26.106"
|
||||
]
|
||||
},
|
||||
"proxy-rewrite": {
|
||||
"uri": "/test/add",
|
||||
"scheme": "https",
|
||||
"host": "apisix.iresty.com"
|
||||
},
|
||||
"limit-count": {
|
||||
"count": 2,
|
||||
"time_window": 60,
|
||||
"rejected_code": 503
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
[返回目录](#目录)
|
||||
|
||||
## Debug mode
|
||||
|
||||
### 基本调试模式
|
||||
|
||||
设置 `conf/config.yaml` 中的 `apisix.enable_debug` 为 `true`,即可开启基本调试模式。
|
||||
|
||||
比如对 `/hello` 开启了 `limit-conn`和`limit-count`插件,这时候应答头中会有 `Apisix-Plugins: limit-conn, limit-count`。
|
||||
|
||||
```shell
|
||||
$ curl http://127.0.0.1:1984/hello -i
|
||||
HTTP/1.1 200 OK
|
||||
Content-Type: text/plain
|
||||
Transfer-Encoding: chunked
|
||||
Connection: keep-alive
|
||||
Apisix-Plugins: limit-conn, limit-count
|
||||
X-RateLimit-Limit: 2
|
||||
X-RateLimit-Remaining: 1
|
||||
Server: openresty
|
||||
|
||||
hello world
|
||||
```
|
||||
|
||||
如果这个信息无法通过 HTTP 应答头传递,比如插件在 stream 子系统里面执行,
|
||||
那么这个信息会以 warn 等级日志写入到错误日志中。
|
||||
|
||||
### 高级调试模式
|
||||
|
||||
设置 `conf/debug.yaml` 中的选项,开启高级调试模式。由于 APISIX 服务启动后是每秒定期检查该文件,
|
||||
当可以正常读取到 `#END` 结尾时,才认为文件处于写完关闭状态。
|
||||
|
||||
根据文件最后修改时间判断文件内容是否有变化,如有变化则重新加载,如没变化则跳过本次检查。
|
||||
所以高级调试模式的开启、关闭都是热更新方式完成。
|
||||
|
||||
| 名字 | 可选项 | 说明 | 默认值 |
|
||||
| ------------------------------- | ------ | ------------------------------------------------------------------ | ------ |
|
||||
| hook_conf.enable | 必选项 | 是否开启 hook 追踪调试。开启后将打印指定模块方法的请求参数或返回值 | false |
|
||||
| hook_conf.name | 必选项 | 开启 hook 追踪调试的模块列表名称 | |
|
||||
| hook_conf.log_level | 必选项 | 打印请求参数和返回值的日志级别 | warn |
|
||||
| hook_conf.is_print_input_args | 必选项 | 是否打印输入参数 | true |
|
||||
| hook_conf.is_print_return_value | 必选项 | 是否打印返回值 | true |
|
||||
|
||||
请看下面示例:
|
||||
|
||||
```yaml
|
||||
hook_conf:
|
||||
enable: false # 是否开启 hook 追踪调试
|
||||
name: hook_phase # 开启 hook 追踪调试的模块列表名称
|
||||
log_level: warn # 日志级别
|
||||
is_print_input_args: true # 是否打印输入参数
|
||||
is_print_return_value: true # 是否打印返回值
|
||||
|
||||
hook_phase: # 模块函数列表,名字:hook_phase
|
||||
apisix: # 引用的模块名称
|
||||
- http_access_phase # 函数名:数组
|
||||
- http_header_filter_phase
|
||||
- http_body_filter_phase
|
||||
- http_log_phase
|
||||
#END
|
||||
```
|
||||
|
||||
[返回目录](#目录)
|
58
docs/zh/latest/architecture-design/apisix.md
Normal file
58
docs/zh/latest/architecture-design/apisix.md
Normal file
@ -0,0 +1,58 @@
|
||||
---
|
||||
title: APISIX
|
||||
---
|
||||
|
||||
<!--
|
||||
#
|
||||
# Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
# contributor license agreements. See the NOTICE file distributed with
|
||||
# this work for additional information regarding copyright ownership.
|
||||
# The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
# (the "License"); you may not use this file except in compliance with
|
||||
# the License. You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
-->
|
||||
|
||||
## 插件加载流程
|
||||
|
||||
![插件加载流程](../../../assets/images/flow-load-plugin.png)
|
||||
|
||||
## 插件内部结构
|
||||
|
||||
![插件内部结构](../../../assets/images/flow-plugin-internal.png)
|
||||
|
||||
## 配置 APISIX
|
||||
|
||||
通过修改本地 `conf/config.yaml` 文件,或者在启动 APISIX 时使用 `-c` 或 `--config` 添加文件路径参数 `apisix start -c <path string>`,完成对 APISIX 服务本身的基本配置。
|
||||
|
||||
比如修改 APISIX 默认监听端口为 8000,其他配置保持默认,在 `config.yaml` 中只需这样配置:
|
||||
|
||||
```yaml
|
||||
apisix:
|
||||
node_listen: 8000 # APISIX listening port
|
||||
```
|
||||
|
||||
比如指定 APISIX 默认监听端口为 8000,并且设置 etcd 地址为 `http://foo:2379`,
|
||||
其他配置保持默认。在 `config.yaml` 中只需这样配置:
|
||||
|
||||
```yaml
|
||||
apisix:
|
||||
node_listen: 8000 # APISIX listening port
|
||||
|
||||
etcd:
|
||||
host: "http://foo:2379" # etcd address
|
||||
```
|
||||
|
||||
其他默认配置,可以在 `conf/config-default.yaml` 文件中看到,该文件是与 APISIX 源码强绑定,
|
||||
**永远不要**手工修改 `conf/config-default.yaml` 文件。如果需要自定义任何配置,都应在 `config.yaml` 文件中完成。
|
||||
|
||||
_注意_ 不要手工修改 APISIX 自身的 `conf/nginx.conf` 文件,当服务每次启动时,`apisix`
|
||||
会根据 `config.yaml` 配置自动生成新的 `conf/nginx.conf` 并自动启动服务。
|
127
docs/zh/latest/architecture-design/consumer.md
Normal file
127
docs/zh/latest/architecture-design/consumer.md
Normal file
@ -0,0 +1,127 @@
|
||||
---
|
||||
title: Consumer
|
||||
---
|
||||
|
||||
<!--
|
||||
#
|
||||
# Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
# contributor license agreements. See the NOTICE file distributed with
|
||||
# this work for additional information regarding copyright ownership.
|
||||
# The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
# (the "License"); you may not use this file except in compliance with
|
||||
# the License. You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
-->
|
||||
|
||||
对于 API 网关通常可以用请求域名、客户端 IP 地址等字段识别到某类请求方,
|
||||
然后进行插件过滤并转发请求到指定上游,但有时候这个深度不够。
|
||||
|
||||
![Consumer](../../../assets/images/consumer-who.png)
|
||||
|
||||
如上图所示,作为 API 网关,需要知道 API Consumer(消费方)具体是谁,这样就可以对不同 API Consumer 配置不同规则。
|
||||
|
||||
| 字段 | 必选 | 说明 |
|
||||
| -------- | ---- | -------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| username | 是 | Consumer 名称。 |
|
||||
| plugins | 否 | 该 Consumer 对应的插件配置,它的优先级是最高的:Consumer > Route > Service。对于具体插件配置,可以参考 [Plugins](plugin.md) 章节。 |
|
||||
|
||||
在 APISIX 中,识别 Consumer 的过程如下图:
|
||||
|
||||
![Consumer Internal](../../../assets/images/consumer-internal.png)
|
||||
|
||||
1. 授权认证:比如有 [key-auth](../plugins/key-auth.md)、[JWT](../plugins/jwt-auth.md) 等。
|
||||
2. 获取 consumer_name:通过授权认证,即可自然获取到对应的 Consumer name,它是 Consumer 对象的唯一识别标识。
|
||||
3. 获取 Consumer 上绑定的 Plugin 或 Upstream 信息:完成对不同 Consumer 做不同配置的效果。
|
||||
|
||||
概括一下,Consumer 是某类服务的消费者,需与用户认证体系配合才能使用。
|
||||
比如不同的 Consumer 请求同一个 API,网关服务根据当前请求用户信息,对应不同的 Plugin 或 Upstream 配置。
|
||||
|
||||
此外,大家也可以参考 [key-auth](../plugins/key-auth.md) 认证授权插件的调用逻辑,辅助大家来进一步理解 Consumer 概念和使用。
|
||||
|
||||
如何对某个 Consumer 开启指定插件,可以看下面例子:
|
||||
|
||||
```shell
|
||||
# 创建 Consumer ,指定认证插件 key-auth ,并开启特定插件 limit-count
|
||||
$ curl http://127.0.0.1:9080/apisix/admin/consumers -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
|
||||
{
|
||||
"username": "jack",
|
||||
"plugins": {
|
||||
"key-auth": {
|
||||
"key": "auth-one"
|
||||
},
|
||||
"limit-count": {
|
||||
"count": 2,
|
||||
"time_window": 60,
|
||||
"rejected_code": 503,
|
||||
"key": "remote_addr"
|
||||
}
|
||||
}
|
||||
}'
|
||||
|
||||
# 创建 Router,设置路由规则和启用插件配置
|
||||
$ curl http://127.0.0.1:9080/apisix/admin/routes/1 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
|
||||
{
|
||||
"plugins": {
|
||||
"key-auth": {}
|
||||
},
|
||||
"upstream": {
|
||||
"nodes": {
|
||||
"127.0.0.1:1980": 1
|
||||
},
|
||||
"type": "roundrobin"
|
||||
},
|
||||
"uri": "/hello"
|
||||
}'
|
||||
|
||||
# 发测试请求,前两次返回正常,没达到限速阈值
|
||||
$ curl http://127.0.0.1:9080/hello -H 'apikey: auth-one' -I
|
||||
...
|
||||
|
||||
$ curl http://127.0.0.1:9080/hello -H 'apikey: auth-one' -I
|
||||
...
|
||||
|
||||
# 第三次测试返回 503,请求被限制
|
||||
$ curl http://127.0.0.1:9080/hello -H 'apikey: auth-one' -I
|
||||
HTTP/1.1 503 Service Temporarily Unavailable
|
||||
...
|
||||
|
||||
```
|
||||
|
||||
结合 [consumer-restriction](../plugins/consumer-restriction.md) 插件,限制 jack 对该 route 的访问
|
||||
|
||||
```shell
|
||||
# 设置黑名单,禁止jack访问该API
|
||||
|
||||
$ curl http://127.0.0.1:9080/apisix/admin/routes/1 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
|
||||
{
|
||||
"plugins": {
|
||||
"key-auth": {},
|
||||
"consumer-restriction": {
|
||||
"blacklist": [
|
||||
"jack"
|
||||
]
|
||||
}
|
||||
},
|
||||
"upstream": {
|
||||
"nodes": {
|
||||
"127.0.0.1:1980": 1
|
||||
},
|
||||
"type": "roundrobin"
|
||||
},
|
||||
"uri": "/hello"
|
||||
}'
|
||||
|
||||
# 反复测试,均返回 403,jack被禁止访问
|
||||
$ curl http://127.0.0.1:9080/hello -H 'apikey: auth-one' -I
|
||||
HTTP/1.1 403
|
||||
...
|
||||
|
||||
```
|
80
docs/zh/latest/architecture-design/debug-mode.md
Normal file
80
docs/zh/latest/architecture-design/debug-mode.md
Normal file
@ -0,0 +1,80 @@
|
||||
---
|
||||
title: Debug Mode
|
||||
---
|
||||
|
||||
<!--
|
||||
#
|
||||
# Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
# contributor license agreements. See the NOTICE file distributed with
|
||||
# this work for additional information regarding copyright ownership.
|
||||
# The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
# (the "License"); you may not use this file except in compliance with
|
||||
# the License. You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
-->
|
||||
|
||||
### 基本调试模式
|
||||
|
||||
设置 `conf/config.yaml` 中的 `apisix.enable_debug` 为 `true`,即可开启基本调试模式。
|
||||
|
||||
比如对 `/hello` 开启了 `limit-conn`和`limit-count`插件,这时候应答头中会有 `Apisix-Plugins: limit-conn, limit-count`。
|
||||
|
||||
```shell
|
||||
$ curl http://127.0.0.1:1984/hello -i
|
||||
HTTP/1.1 200 OK
|
||||
Content-Type: text/plain
|
||||
Transfer-Encoding: chunked
|
||||
Connection: keep-alive
|
||||
Apisix-Plugins: limit-conn, limit-count
|
||||
X-RateLimit-Limit: 2
|
||||
X-RateLimit-Remaining: 1
|
||||
Server: openresty
|
||||
|
||||
hello world
|
||||
```
|
||||
|
||||
如果这个信息无法通过 HTTP 应答头传递,比如插件在 stream 子系统里面执行,
|
||||
那么这个信息会以 warn 等级日志写入到错误日志中。
|
||||
|
||||
### 高级调试模式
|
||||
|
||||
设置 `conf/debug.yaml` 中的选项,开启高级调试模式。由于 APISIX 服务启动后是每秒定期检查该文件,
|
||||
当可以正常读取到 `#END` 结尾时,才认为文件处于写完关闭状态。
|
||||
|
||||
根据文件最后修改时间判断文件内容是否有变化,如有变化则重新加载,如没变化则跳过本次检查。
|
||||
所以高级调试模式的开启、关闭都是热更新方式完成。
|
||||
|
||||
| 名字 | 可选项 | 说明 | 默认值 |
|
||||
| ------------------------------- | ------ | ------------------------------------------------------------------ | ------ |
|
||||
| hook_conf.enable | 必选项 | 是否开启 hook 追踪调试。开启后将打印指定模块方法的请求参数或返回值 | false |
|
||||
| hook_conf.name | 必选项 | 开启 hook 追踪调试的模块列表名称 | |
|
||||
| hook_conf.log_level | 必选项 | 打印请求参数和返回值的日志级别 | warn |
|
||||
| hook_conf.is_print_input_args | 必选项 | 是否打印输入参数 | true |
|
||||
| hook_conf.is_print_return_value | 必选项 | 是否打印返回值 | true |
|
||||
|
||||
请看下面示例:
|
||||
|
||||
```yaml
|
||||
hook_conf:
|
||||
enable: false # 是否开启 hook 追踪调试
|
||||
name: hook_phase # 开启 hook 追踪调试的模块列表名称
|
||||
log_level: warn # 日志级别
|
||||
is_print_input_args: true # 是否打印输入参数
|
||||
is_print_return_value: true # 是否打印返回值
|
||||
|
||||
hook_phase: # 模块函数列表,名字:hook_phase
|
||||
apisix: # 引用的模块名称
|
||||
- http_access_phase # 函数名:数组
|
||||
- http_header_filter_phase
|
||||
- http_body_filter_phase
|
||||
- http_log_phase
|
||||
#END
|
||||
```
|
51
docs/zh/latest/architecture-design/global-rule.md
Normal file
51
docs/zh/latest/architecture-design/global-rule.md
Normal file
@ -0,0 +1,51 @@
|
||||
---
|
||||
title: Global rule
|
||||
---
|
||||
|
||||
<!--
|
||||
#
|
||||
# Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
# contributor license agreements. See the NOTICE file distributed with
|
||||
# this work for additional information regarding copyright ownership.
|
||||
# The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
# (the "License"); you may not use this file except in compliance with
|
||||
# the License. You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
-->
|
||||
|
||||
[Plugin](plugin.md) 只能绑定在 [Service](service.md) 或者 [Route](route.md) 上,如果我们需要一个能作用于所有请求的 [Plugin](plugin.md) 该怎么办呢?
|
||||
这时候我们可以使用 `GlobalRule` 来注册一个全局的 [Plugin](plugin.md):
|
||||
|
||||
```shell
|
||||
curl -X PUT \
|
||||
https://{apisix_listen_address}/apisix/admin/global_rules/1 \
|
||||
-H 'Content-Type: application/json' \
|
||||
-H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' \
|
||||
-d '{
|
||||
"plugins": {
|
||||
"limit-count": {
|
||||
"time_window": 60,
|
||||
"policy": "local",
|
||||
"count": 2,
|
||||
"key": "remote_addr",
|
||||
"rejected_code": 503
|
||||
}
|
||||
}
|
||||
}'
|
||||
```
|
||||
|
||||
如上所注册的 `limit-count` 插件将会作用于所有的请求。
|
||||
|
||||
我们可以通过以下接口查看所有的 `GlobalRule`:
|
||||
|
||||
```shell
|
||||
curl https://{apisix_listen_address}/apisix/admin/global_rules -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1'
|
||||
```
|
140
docs/zh/latest/architecture-design/plugin-config.md
Normal file
140
docs/zh/latest/architecture-design/plugin-config.md
Normal file
@ -0,0 +1,140 @@
|
||||
---
|
||||
title: Plugin Config
|
||||
---
|
||||
|
||||
<!--
|
||||
#
|
||||
# Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
# contributor license agreements. See the NOTICE file distributed with
|
||||
# this work for additional information regarding copyright ownership.
|
||||
# The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
# (the "License"); you may not use this file except in compliance with
|
||||
# the License. You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
-->
|
||||
|
||||
如果你想要复用一组通用的插件配置,你可以把它们提取成一个 Plugin config,并绑定到对应的路由上。
|
||||
|
||||
举个例子,你可以这么做:
|
||||
|
||||
```shell
|
||||
# 创建 Plugin config
|
||||
$ curl http://127.0.0.1:9080/apisix/admin/plugin_configs/1 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -i -d '
|
||||
{
|
||||
"desc": "吾乃插件配置1",
|
||||
"plugins": {
|
||||
"limit-count": {
|
||||
"count": 2,
|
||||
"time_window": 60,
|
||||
"rejected_code": 503
|
||||
}
|
||||
}
|
||||
}'
|
||||
|
||||
# 绑定到路由上
|
||||
$ curl http://127.0.0.1:9080/apisix/admin/routes/1 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -i -d '
|
||||
{
|
||||
"uris": ["/index.html"],
|
||||
"plugin_config_id": 1,
|
||||
"upstream": {
|
||||
"type": "roundrobin",
|
||||
"nodes": {
|
||||
"39.97.63.215:80": 1
|
||||
}
|
||||
}
|
||||
}'
|
||||
```
|
||||
|
||||
如果找不到对应的 Plugin config,该路由上的请求会报 503 错误。
|
||||
|
||||
如果这个路由已经配置了 `plugins`,那么 Plugin config 里面的插件配置会合并进去。
|
||||
相同的插件会覆盖掉 `plugins` 原有的插件。
|
||||
|
||||
举个例子:
|
||||
|
||||
```
|
||||
{
|
||||
"desc": "吾乃插件配置1",
|
||||
"plugins": {
|
||||
"ip-restriction": {
|
||||
"whitelist": [
|
||||
"127.0.0.0/24",
|
||||
"113.74.26.106"
|
||||
]
|
||||
},
|
||||
"limit-count": {
|
||||
"count": 2,
|
||||
"time_window": 60,
|
||||
"rejected_code": 503
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
加上
|
||||
|
||||
```
|
||||
{
|
||||
"uris": ["/index.html"],
|
||||
"plugin_config_id": 1,
|
||||
"upstream": {
|
||||
"type": "roundrobin",
|
||||
"nodes": {
|
||||
"39.97.63.215:80": 1
|
||||
}
|
||||
}
|
||||
"plugins": {
|
||||
"proxy-rewrite": {
|
||||
"uri": "/test/add",
|
||||
"scheme": "https",
|
||||
"host": "apisix.iresty.com"
|
||||
},
|
||||
"limit-count": {
|
||||
"count": 20,
|
||||
"time_window": 60,
|
||||
"rejected_code": 503,
|
||||
"key": "remote_addr"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
等于
|
||||
|
||||
```
|
||||
{
|
||||
"uris": ["/index.html"],
|
||||
"upstream": {
|
||||
"type": "roundrobin",
|
||||
"nodes": {
|
||||
"39.97.63.215:80": 1
|
||||
}
|
||||
}
|
||||
"plugins": {
|
||||
"ip-restriction": {
|
||||
"whitelist": [
|
||||
"127.0.0.0/24",
|
||||
"113.74.26.106"
|
||||
]
|
||||
},
|
||||
"proxy-rewrite": {
|
||||
"uri": "/test/add",
|
||||
"scheme": "https",
|
||||
"host": "apisix.iresty.com"
|
||||
},
|
||||
"limit-count": {
|
||||
"count": 2,
|
||||
"time_window": 60,
|
||||
"rejected_code": 503
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
70
docs/zh/latest/architecture-design/plugin.md
Normal file
70
docs/zh/latest/architecture-design/plugin.md
Normal file
@ -0,0 +1,70 @@
|
||||
---
|
||||
title: Plugin
|
||||
---
|
||||
|
||||
<!--
|
||||
#
|
||||
# Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
# contributor license agreements. See the NOTICE file distributed with
|
||||
# this work for additional information regarding copyright ownership.
|
||||
# The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
# (the "License"); you may not use this file except in compliance with
|
||||
# the License. You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
-->
|
||||
|
||||
`Plugin` 表示将在 `HTTP` 请求/响应生命周期期间执行的插件配置。
|
||||
|
||||
`Plugin` 配置可直接绑定在 `Route` 上,也可以被绑定在 `Service` 或 `Consumer`上。而对于同一
|
||||
个插件的配置,只能有一份是有效的,配置选择优先级总是 `Consumer` > `Route` > `Service`。
|
||||
|
||||
在 `conf/config.yaml` 中,可以声明本地 APISIX 节点都支持哪些插件。这是个白名单机制,不在该
|
||||
白名单的插件配置,都将会被自动忽略。这个特性可用于临时关闭或打开特定插件,应对突发情况非常有效。
|
||||
如果你想在现有插件的基础上新增插件,注意需要拷贝 `conf/config-default.yaml` 的插件节点内容到 `conf/config.yaml` 的插件节点中。
|
||||
|
||||
插件的配置可以被直接绑定在指定 Route 中,也可以被绑定在 Service 中,不过 Route 中的插件配置
|
||||
优先级更高。
|
||||
|
||||
一个插件在一次请求中只会执行一次,即使被同时绑定到多个不同对象中(比如 Route 或 Service)。
|
||||
插件运行先后顺序是根据插件自身的优先级来决定的,例如:
|
||||
|
||||
```lua
|
||||
local _M = {
|
||||
version = 0.1,
|
||||
priority = 0, -- 这个插件的优先级为 0
|
||||
name = plugin_name,
|
||||
schema = schema,
|
||||
metadata_schema = metadata_schema,
|
||||
}
|
||||
```
|
||||
|
||||
插件配置作为 Route 或 Service 的一部分提交的,放到 `plugins` 下。它内部是使用插件
|
||||
名字作为哈希的 key 来保存不同插件的配置项。
|
||||
|
||||
```json
|
||||
{
|
||||
...
|
||||
"plugins": {
|
||||
"limit-count": {
|
||||
"count": 2,
|
||||
"time_window": 60,
|
||||
"rejected_code": 503,
|
||||
"key": "remote_addr"
|
||||
},
|
||||
"prometheus": {}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
并不是所有插件都有具体配置项,比如 `prometheus` 下是没有任何具体配置项,这时候用一个空的对象
|
||||
标识即可。
|
||||
|
||||
如果一个请求因为某个插件而被拒绝,会有类似这样的 warn 日志:`ip-restriction exits with http status code 403`。
|
62
docs/zh/latest/architecture-design/route.md
Normal file
62
docs/zh/latest/architecture-design/route.md
Normal file
@ -0,0 +1,62 @@
|
||||
---
|
||||
title: Route
|
||||
---
|
||||
|
||||
<!--
|
||||
#
|
||||
# Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
# contributor license agreements. See the NOTICE file distributed with
|
||||
# this work for additional information regarding copyright ownership.
|
||||
# The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
# (the "License"); you may not use this file except in compliance with
|
||||
# the License. You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
-->
|
||||
|
||||
Route 字面意思就是路由,通过定义一些规则来匹配客户端的请求,然后根据匹配结果加载并执行相应的
|
||||
插件,并把请求转发给到指定 Upstream。
|
||||
|
||||
Route 中主要包含三部分内容:匹配规则(比如 uri、host、remote_addr 等),插件配置(限流限速等)和上游信息。
|
||||
请看下图示例,是一些 Route 规则的实例,当某些属性值相同时,图中用相同颜色标识。
|
||||
|
||||
![路由示例](../../../assets/images/routes-example.png)
|
||||
|
||||
我们直接在 Route 中完成所有参数的配置,优点是容易设置,每个 Route 都相对独立自由度比较高。但当我们的 Route 有比较多的重复配置(比如启用相同的插件配置或上游信息),一旦我们要更新这些相同属性时,就需要遍历所有 Route 并进行修改,给后期管理维护增加不少复杂度。
|
||||
|
||||
上面提及重复的缺点在 APISIX 中独立抽象了 [Service](service.md) 和 [Upstream](upstream.md) 两个概念来解决。
|
||||
|
||||
下面创建的 Route 示例,是把 URL 为 "/index.html" 的请求代理到地址为 "39.97.63.215:80" 的 Upstream 服务:
|
||||
|
||||
```shell
|
||||
$ curl http://127.0.0.1:9080/apisix/admin/routes/1 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -i -d '
|
||||
{
|
||||
"uri": "/index.html",
|
||||
"upstream": {
|
||||
"type": "roundrobin",
|
||||
"nodes": {
|
||||
"39.97.63.215:80": 1
|
||||
}
|
||||
}
|
||||
}'
|
||||
|
||||
HTTP/1.1 201 Created
|
||||
Date: Sat, 31 Aug 2019 01:17:15 GMT
|
||||
Content-Type: text/plain
|
||||
Transfer-Encoding: chunked
|
||||
Connection: keep-alive
|
||||
Server: APISIX web server
|
||||
|
||||
{"node":{"value":{"uri":"\/index.html","upstream":{"nodes":{"39.97.63.215:80":1},"type":"roundrobin"}},"createdIndex":61925,"key":"\/apisix\/routes\/1","modifiedIndex":61925},"action":"create"}
|
||||
```
|
||||
|
||||
当我们接收到成功应答,表示该 Route 已成功创建。
|
||||
|
||||
有关 Route 的具体选项,可具体查阅 [Admin API 之 Route](../admin-api.md#route)。
|
39
docs/zh/latest/architecture-design/router.md
Normal file
39
docs/zh/latest/architecture-design/router.md
Normal file
@ -0,0 +1,39 @@
|
||||
---
|
||||
title: Router
|
||||
---
|
||||
|
||||
<!--
|
||||
#
|
||||
# Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
# contributor license agreements. See the NOTICE file distributed with
|
||||
# this work for additional information regarding copyright ownership.
|
||||
# The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
# (the "License"); you may not use this file except in compliance with
|
||||
# the License. You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
-->
|
||||
|
||||
APISIX 区别于其他 API 网关的一大特点是允许用户选择不同 Router 来更好匹配自由业务,在性能、自由之间做最适合选择。
|
||||
|
||||
在本地配置 `conf/config.yaml` 中设置最符合自身业务需求的路由。
|
||||
|
||||
- `apisix.router.http`: HTTP 请求路由。
|
||||
|
||||
- `radixtree_uri`: (默认)只使用 `uri` 作为主索引。基于 `radixtree` 引擎,支持全量和深前缀匹配,更多见 [如何使用 router-radixtree](../../../zh/latest/router-radixtree.md)。
|
||||
- `绝对匹配`:完整匹配给定的 `uri` ,比如 `/foo/bar`,`/foo/glo`。
|
||||
- `前缀匹配`:末尾使用 `*` 代表给定的 `uri` 是前缀匹配。比如 `/foo*`,则允许匹配 `/foo/`、`/foo/a`和`/foo/b`等。
|
||||
- `匹配优先级`:优先尝试绝对匹配,若无法命中绝对匹配,再尝试前缀匹配。
|
||||
- `任意过滤属性`:允许指定任何 Nginx 内置变量作为过滤条件,比如 URL 请求参数、请求头、cookie 等。
|
||||
- `radixtree_uri_with_parameter`: 同 `radixtree_uri` 但额外有参数匹配的功能。
|
||||
- `radixtree_host_uri`: 使用 `host + uri` 作为主索引(基于 `radixtree` 引擎),对当前请求会同时匹配 host 和 uri,支持的匹配条件与 `radixtree_uri` 基本一致。
|
||||
|
||||
- `apisix.router.ssl`: SSL 加载匹配路由。
|
||||
- `radixtree_sni`: (默认)使用 `SNI` (Server Name Indication) 作为主索引(基于 radixtree 引擎)。
|
39
docs/zh/latest/architecture-design/script.md
Normal file
39
docs/zh/latest/architecture-design/script.md
Normal file
@ -0,0 +1,39 @@
|
||||
---
|
||||
title: Script
|
||||
---
|
||||
|
||||
<!--
|
||||
#
|
||||
# Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
# contributor license agreements. See the NOTICE file distributed with
|
||||
# this work for additional information regarding copyright ownership.
|
||||
# The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
# (the "License"); you may not use this file except in compliance with
|
||||
# the License. You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
-->
|
||||
|
||||
`Script` 表示将在 `HTTP` 请求/响应生命周期期间执行的脚本。
|
||||
|
||||
`Script` 配置可直接绑定在 `Route` 上。
|
||||
|
||||
`Script` 与 `Plugin` 互斥,且优先执行 `Script` ,这意味着配置 `Script` 后,`Route` 上配置的 `Plugin` 将不被执行。
|
||||
|
||||
理论上,在 `Script` 中可以写任意 lua 代码,也可以直接调用已有插件以重用已有的代码。
|
||||
|
||||
`Script` 也有执行阶段概念,支持 `access`、`header_filter`、`body_filter` 和 `log` 阶段。系统会在相应阶段中自动执行 `Script` 脚本中对应阶段的代码。
|
||||
|
||||
```json
|
||||
{
|
||||
...
|
||||
"script": "local _M = {} \n function _M.access(api_ctx) \n ngx.log(ngx.INFO,\"hit access phase\") \n end \nreturn _M"
|
||||
}
|
||||
```
|
88
docs/zh/latest/architecture-design/service.md
Normal file
88
docs/zh/latest/architecture-design/service.md
Normal file
@ -0,0 +1,88 @@
|
||||
---
|
||||
title: Service
|
||||
---
|
||||
|
||||
<!--
|
||||
#
|
||||
# Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
# contributor license agreements. See the NOTICE file distributed with
|
||||
# this work for additional information regarding copyright ownership.
|
||||
# The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
# (the "License"); you may not use this file except in compliance with
|
||||
# the License. You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
-->
|
||||
|
||||
`Service` 是某类 API 的抽象(也可以理解为一组 Route 的抽象)。它通常与上游服务抽象是一一对应的,`Route`
|
||||
与 `Service` 之间,通常是 N:1 的关系,参看下图。
|
||||
|
||||
![服务示例](../../../assets/images/service-example.png)
|
||||
|
||||
不同 Route 规则同时绑定到一个 Service 上,这些 Route 将具有相同的上游和插件配置,减少冗余配置。
|
||||
|
||||
比如下面的例子,创建了一个启用限流插件的 Service,然后把 id 为 `100`、`101` 的 Route 都绑定在这个 Service 上。
|
||||
|
||||
```shell
|
||||
# create new Service
|
||||
$ curl http://127.0.0.1:9080/apisix/admin/services/200 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
|
||||
{
|
||||
"plugins": {
|
||||
"limit-count": {
|
||||
"count": 2,
|
||||
"time_window": 60,
|
||||
"rejected_code": 503,
|
||||
"key": "remote_addr"
|
||||
}
|
||||
},
|
||||
"upstream": {
|
||||
"type": "roundrobin",
|
||||
"nodes": {
|
||||
"39.97.63.215:80": 1
|
||||
}
|
||||
}
|
||||
}'
|
||||
|
||||
# create new Route and reference the service by id `200`
|
||||
curl http://127.0.0.1:9080/apisix/admin/routes/100 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
|
||||
{
|
||||
"methods": ["GET"],
|
||||
"uri": "/index.html",
|
||||
"service_id": "200"
|
||||
}'
|
||||
|
||||
curl http://127.0.0.1:9080/apisix/admin/routes/101 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
|
||||
{
|
||||
"methods": ["GET"],
|
||||
"uri": "/foo/index.html",
|
||||
"service_id": "200"
|
||||
}'
|
||||
```
|
||||
|
||||
当然我们也可以为 Route 指定不同的插件参数或上游,比如下面这个 Route 设置了不同的限流参数,其他部分(比如上游)则继续使用 Service 中的配置参数。
|
||||
|
||||
```shell
|
||||
curl http://127.0.0.1:9080/apisix/admin/routes/102 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
|
||||
{
|
||||
"uri": "/bar/index.html",
|
||||
"id": "102",
|
||||
"service_id": "200",
|
||||
"plugins": {
|
||||
"limit-count": {
|
||||
"count": 2000,
|
||||
"time_window": 60,
|
||||
"rejected_code": 503,
|
||||
"key": "remote_addr"
|
||||
}
|
||||
}
|
||||
}'
|
||||
```
|
||||
|
||||
注意:当 Route 和 Service 都开启同一个插件时,Route 参数的优先级是高于 Service 的。
|
218
docs/zh/latest/architecture-design/upstream.md
Normal file
218
docs/zh/latest/architecture-design/upstream.md
Normal file
@ -0,0 +1,218 @@
|
||||
---
|
||||
title: Upstream
|
||||
---
|
||||
|
||||
<!--
|
||||
#
|
||||
# Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
# contributor license agreements. See the NOTICE file distributed with
|
||||
# this work for additional information regarding copyright ownership.
|
||||
# The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
# (the "License"); you may not use this file except in compliance with
|
||||
# the License. You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
-->
|
||||
|
||||
Upstream 是虚拟主机抽象,对给定的多个服务节点按照配置规则进行负载均衡。Upstream 的地址信息可以直接配置到 `Route`(或 `Service`) 上,当 Upstream 有重复时,就需要用“引用”方式避免重复了。
|
||||
|
||||
![Upstream 示例](../../../assets/images/upstream-example.png)
|
||||
|
||||
如上图所示,通过创建 Upstream 对象,在 `Route` 用 ID 方式引用,就可以确保只维护一个对象的值了。
|
||||
|
||||
Upstream 的配置可以被直接绑定在指定 `Route` 中,也可以被绑定在 `Service` 中,不过 `Route` 中的配置
|
||||
优先级更高。这里的优先级行为与 `Plugin` 非常相似
|
||||
|
||||
### 配置参数
|
||||
|
||||
APISIX 的 Upstream 除了基本的复杂均衡算法选择外,还支持对上游做主被动健康检查、重试等逻辑,具体看这个[链接](../admin-api.md#upstram)。
|
||||
|
||||
创建上游对象用例:
|
||||
|
||||
```json
|
||||
curl http://127.0.0.1:9080/apisix/admin/upstreams/1 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
|
||||
{
|
||||
"type": "chash",
|
||||
"key": "remote_addr",
|
||||
"nodes": {
|
||||
"127.0.0.1:80": 1,
|
||||
"foo.com:80": 2
|
||||
}
|
||||
}'
|
||||
```
|
||||
|
||||
上游对象创建后,均可以被具体 `Route` 或 `Service` 引用,例如:
|
||||
|
||||
```shell
|
||||
curl http://127.0.0.1:9080/apisix/admin/routes/1 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
|
||||
{
|
||||
"uri": "/index.html",
|
||||
"upstream_id": 2
|
||||
}'
|
||||
```
|
||||
|
||||
为了方便使用,也可以直接把上游地址直接绑到某个 `Route` 或 `Service` ,例如:
|
||||
|
||||
```shell
|
||||
curl http://127.0.0.1:9080/apisix/admin/routes/1 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
|
||||
{
|
||||
"uri": "/index.html",
|
||||
"plugins": {
|
||||
"limit-count": {
|
||||
"count": 2,
|
||||
"time_window": 60,
|
||||
"rejected_code": 503,
|
||||
"key": "remote_addr"
|
||||
}
|
||||
},
|
||||
"upstream": {
|
||||
"type": "roundrobin",
|
||||
"nodes": {
|
||||
"39.97.63.215:80": 1
|
||||
}
|
||||
}
|
||||
}'
|
||||
```
|
||||
|
||||
下面是一个配置了健康检查的示例:
|
||||
|
||||
```shell
|
||||
curl http://127.0.0.1:9080/apisix/admin/routes/1 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
|
||||
{
|
||||
"uri": "/index.html",
|
||||
"plugins": {
|
||||
"limit-count": {
|
||||
"count": 2,
|
||||
"time_window": 60,
|
||||
"rejected_code": 503,
|
||||
"key": "remote_addr"
|
||||
}
|
||||
},
|
||||
"upstream": {
|
||||
"nodes": {
|
||||
"39.97.63.215:80": 1
|
||||
}
|
||||
"type": "roundrobin",
|
||||
"retries": 2,
|
||||
"checks": {
|
||||
"active": {
|
||||
"http_path": "/status",
|
||||
"host": "foo.com",
|
||||
"healthy": {
|
||||
"interval": 2,
|
||||
"successes": 1
|
||||
},
|
||||
"unhealthy": {
|
||||
"interval": 1,
|
||||
"http_failures": 2
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}'
|
||||
```
|
||||
|
||||
更多细节可以参考[健康检查的文档](../health-check.md)。
|
||||
|
||||
下面是几个使用不同`hash_on`类型的配置示例:
|
||||
|
||||
#### Consumer
|
||||
|
||||
创建一个 consumer 对象:
|
||||
|
||||
```shell
|
||||
curl http://127.0.0.1:9080/apisix/admin/consumers -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
|
||||
{
|
||||
"username": "jack",
|
||||
"plugins": {
|
||||
"key-auth": {
|
||||
"key": "auth-jack"
|
||||
}
|
||||
}
|
||||
}'
|
||||
```
|
||||
|
||||
新建路由,打开`key-auth`插件认证,`upstream`的`hash_on`类型为`consumer`:
|
||||
|
||||
```shell
|
||||
curl http://127.0.0.1:9080/apisix/admin/routes/1 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
|
||||
{
|
||||
"plugins": {
|
||||
"key-auth": {}
|
||||
},
|
||||
"upstream": {
|
||||
"nodes": {
|
||||
"127.0.0.1:1980": 1,
|
||||
"127.0.0.1:1981": 1
|
||||
},
|
||||
"type": "chash",
|
||||
"hash_on": "consumer"
|
||||
},
|
||||
"uri": "/server_port"
|
||||
}'
|
||||
```
|
||||
|
||||
测试请求,认证通过后的`consumer_name`将作为负载均衡哈希算法的哈希值:
|
||||
|
||||
```shell
|
||||
curl http://127.0.0.1:9080/server_port -H "apikey: auth-jack"
|
||||
```
|
||||
|
||||
##### Cookie
|
||||
|
||||
新建路由和`Upstream`,`hash_on`类型为`cookie`:
|
||||
|
||||
```shell
|
||||
curl http://127.0.0.1:9080/apisix/admin/routes/1 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
|
||||
{
|
||||
"uri": "/hash_on_cookie",
|
||||
"upstream": {
|
||||
"key": "sid",
|
||||
"type ": "chash",
|
||||
"hash_on ": "cookie",
|
||||
"nodes ": {
|
||||
"127.0.0.1:1980": 1,
|
||||
"127.0.0.1:1981": 1
|
||||
}
|
||||
}
|
||||
}'
|
||||
```
|
||||
|
||||
客户端请求携带`Cookie`:
|
||||
|
||||
```shell
|
||||
curl http://127.0.0.1:9080/hash_on_cookie -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -H "Cookie: sid=3c183a30cffcda1408daf1c61d47b274"
|
||||
```
|
||||
|
||||
##### Header
|
||||
|
||||
新建路由和`Upstream`,`hash_on`类型为`header`, `key`为`content-type`:
|
||||
|
||||
```shell
|
||||
curl http://127.0.0.1:9080/apisix/admin/routes/1 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
|
||||
{
|
||||
"uri": "/hash_on_header",
|
||||
"upstream": {
|
||||
"key": "content-type",
|
||||
"type ": "chash",
|
||||
"hash_on ": "header",
|
||||
"nodes ": {
|
||||
"127.0.0.1:1980": 1,
|
||||
"127.0.0.1:1981": 1
|
||||
}
|
||||
}
|
||||
}'
|
||||
```
|
||||
|
||||
客户端请求携带`content-type`的`header`:
|
||||
|
||||
```shell
|
||||
curl http://127.0.0.1:9080/hash_on_header -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -H "Content-Type: application/json"
|
||||
```
|
@ -2,8 +2,21 @@
|
||||
"version": 2.4,
|
||||
"sidebar": [
|
||||
{
|
||||
"type": "doc",
|
||||
"id": "architecture-design"
|
||||
"type": "category",
|
||||
"label": "Architecture Design",
|
||||
"items": [
|
||||
"architecture-design/apisix",
|
||||
"architecture-design/route",
|
||||
"architecture-design/plugin",
|
||||
"architecture-design/script",
|
||||
"architecture-design/service",
|
||||
"architecture-design/consumer",
|
||||
"architecture-design/upstream",
|
||||
"architecture-design/global-rule",
|
||||
"architecture-design/plugin-config",
|
||||
"architecture-design/router",
|
||||
"architecture-design/debug-mode"
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "doc",
|
||||
@ -108,57 +121,69 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "doc",
|
||||
"id": "admin-api"
|
||||
},
|
||||
{
|
||||
"type": "doc",
|
||||
"id": "control-api"
|
||||
},
|
||||
{
|
||||
"type": "doc",
|
||||
"id": "health-check"
|
||||
},
|
||||
{
|
||||
"type": "doc",
|
||||
"id": "router-radixtree"
|
||||
},
|
||||
{
|
||||
"type": "doc",
|
||||
"id": "stand-alone"
|
||||
},
|
||||
{
|
||||
"type": "doc",
|
||||
"id": "stream-proxy"
|
||||
},
|
||||
{
|
||||
"type": "doc",
|
||||
"id": "grpc-proxy"
|
||||
},
|
||||
{
|
||||
"type": "doc",
|
||||
"id": "customize-nginx-configuration"
|
||||
},
|
||||
{
|
||||
"type": "doc",
|
||||
"id": "https"
|
||||
},
|
||||
{
|
||||
"type": "doc",
|
||||
"id": "benchmark"
|
||||
},
|
||||
{
|
||||
"type": "doc",
|
||||
"id": "CODE_STYLE"
|
||||
},
|
||||
{
|
||||
"type": "doc",
|
||||
"id": "debug-function"
|
||||
"type": "category",
|
||||
"label": "API",
|
||||
"items": [
|
||||
{
|
||||
"type": "doc",
|
||||
"id": "admin-api"
|
||||
},
|
||||
{
|
||||
"type": "doc",
|
||||
"id": "control-api"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "doc",
|
||||
"id": "FAQ"
|
||||
},
|
||||
{
|
||||
"type": "category",
|
||||
"label": "Others",
|
||||
"items": [
|
||||
{
|
||||
"type": "doc",
|
||||
"id": "health-check"
|
||||
},
|
||||
{
|
||||
"type": "doc",
|
||||
"id": "router-radixtree"
|
||||
},
|
||||
{
|
||||
"type": "doc",
|
||||
"id": "stand-alone"
|
||||
},
|
||||
{
|
||||
"type": "doc",
|
||||
"id": "stream-proxy"
|
||||
},
|
||||
{
|
||||
"type": "doc",
|
||||
"id": "grpc-proxy"
|
||||
},
|
||||
{
|
||||
"type": "doc",
|
||||
"id": "customize-nginx-configuration"
|
||||
},
|
||||
{
|
||||
"type": "doc",
|
||||
"id": "https"
|
||||
},
|
||||
{
|
||||
"type": "doc",
|
||||
"id": "benchmark"
|
||||
},
|
||||
{
|
||||
"type": "doc",
|
||||
"id": "CODE_STYLE"
|
||||
},
|
||||
{
|
||||
"type": "doc",
|
||||
"id": "debug-function"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "doc",
|
||||
"id": "CHANGELOG"
|
||||
|
Loading…
Reference in New Issue
Block a user