? cd apisix-docker

在項目根目錄下面的?example?目錄中有啟動 APISIX 的 docker-compose 配置文件,如下所示:

version: "3"

services:
apisix-dashboard:
image: apache/apisix-dashboard:3.0.0-alpine
restart: always
volumes:
- ./dashboard_conf/conf.yaml:/usr/local/apisix-dashboard/conf/conf.yaml
ports:
- "9000:9000"
networks:
apisix:

apisix:
image: apache/apisix:3.2.0-debian
restart: always
volumes:
- ./apisix_conf/config.yaml:/usr/local/apisix/conf/config.yaml:ro
depends_on:
- etcd
ports:
- "9180:9180/tcp"
- "9080:9080/tcp"
- "9091:9091/tcp"
- "9443:9443/tcp"
- "9092:9092/tcp"
networks:
apisix:

etcd:
image: rancher/coreos-etcd:v3.4.15-arm64
user: root
restart: always
volumes:
- ./etcd_data:/etcd-data
environment:
ETCD_UNSUPPORTED_ARCH: "arm64"
ETCD_ENABLE_V2: "true"
ALLOW_NONE_AUTHENTICATION: "yes"
ETCD_ADVERTISE_CLIENT_URLS: "http://0.0.0.0:2379"
ETCD_LISTEN_CLIENT_URLS: "http://0.0.0.0:2379"
ETCD_DATA_DIR: "/etcd-data"
ports:
- "2379:2379/tcp"
networks:
apisix:

web1:
image: nginx:1.19.10-alpine
restart: always
volumes:
- ./upstream/web1.conf:/etc/nginx/nginx.conf
ports:
- "9081:80/tcp"
environment:
- NGINX_PORT=80
networks:
apisix:

web2:
image: nginx:1.19.10-alpine
restart: always
volumes:
- ./upstream/web2.conf:/etc/nginx/nginx.conf
ports:
- "9082:80/tcp"
environment:
- NGINX_PORT=80
networks:
apisix:

networks:
apisix:
driver: bridge

該 compose 里面主要包含了 APISIX 的三個容器:apisix、etcd 以及 apisix-dashboard?,F在我們就可以使用 docker-compose 來進行一鍵啟動:

? docker-compose -f docker-compose.yml up -d

另外兩個 nginx 容器是用于測試的:

docker-compose

請確保其他系統進程沒有占用 9000、9080、9091、9092、9180、9443 和 2379 端口。如果啟動有錯誤,可以嘗試為 examples 目錄設置成 777 權限,保證 etcd 數據有權限寫入。

APISIX 啟動完成后我們就可以通過 curl 來訪問正在運行的 APISIX 實例。比如,可以發(fā)送一個簡單的 HTTP 請求來驗證 APISIX 運行狀態(tài)是否正常。

? curl "http://127.0.0.1:9080" --head
HTTP/1.1 404 Not Found
Date: Tue, 21 Mar 2023 07:38:45 GMT
Content-Type: text/plain; charset=utf-8
Connection: keep-alive
Server: APISIX/3.2.0

現在,你已經成功安裝并運行了 APISIX !

功能測試

接下來我們來了解下 APISIX 的一些功能。在了解之前我們需要對 APISIX 的幾個主要概念和組件簡單了解下:

上游

Upstream 也稱為上游,上游是對虛擬主機的抽象,即應用層服務或節(jié)點的抽象。

上游的作用是按照配置規(guī)則對服務節(jié)點進行負載均衡,它的地址信息可以直接配置到路由或服務上。當多個路由或服務引用同一個上游時,可以通過創(chuàng)建上游對象,在路由或服務中使用上游的 ID 方式引用上游,減輕維護壓力。

路由

Route 也稱為路由,是 APISIX 中最基礎和最核心的資源對象。

APISIX 可以通過路由定義規(guī)則來匹配客戶端請求,根據匹配結果加載并執(zhí)行相應的插件,最后把請求轉發(fā)給到指定的上游服務。路由中主要包含三部分內容:匹配規(guī)則、插件配置和上游信息。

服務

Service 也稱為服務,是某類 API 的抽象(也可以理解為一組 Route 的抽象)。它通常與上游服務抽象是一一對應的,Route 與 Service 之間,通常是?N:1?的關系。

消費者

Consumer 是某類服務的消費者,需要與用戶認證配合才可以使用。當不同的消費者請求同一個 API 時,APISIX 會根據當前請求的用戶信息,對應不同的 Plugin 或 Upstream 配置。如果 Route、Service、Consumer 和 Plugin Config 都綁定了相同的插件,只有消費者的插件配置會生效。插件配置的優(yōu)先級由高到低的順序是:Consumer > Route > Plugin Config > Service。

對于 API 網關而言,一般情況可以通過請求域名、客戶端 IP 地址等字段識別到某類請求方,然后進行插件過濾并轉發(fā)請求到指定上游。但有時候該方式達不到用戶需求,因此 APISIX 支持了 Consumer 對象。

插件

Plugin 也稱之為插件,它是擴展 APISIX 應用層能力的關鍵機制,也是在使用 APISIX 時最常用的資源對象。插件主要是在 HTTP 請求或響應生命周期期間執(zhí)行的、針對請求的個性化策略。插件可以與路由、服務或消費者綁定。

如果路由、服務、插件配置或消費者都綁定了相同的插件,則只有一份插件配置會生效,插件配置的優(yōu)先級由高到低順序是:消費者 > 路由 > 插件配置 > 服務。同時在插件執(zhí)行過程中也會涉及 6 個階段,分別是 rewrite、access、before_proxyheader_filter、body_filter 和 log。

Admin API

APISIX 提供了強大的 Admin API 和 Dashboard 供用戶使用,Admin API 是一組用于配置 Apache APISIX 路由、上游、服務、SSL 證書等功能的 RESTful API。

我們可以通過 Admin API 來獲取、創(chuàng)建、更新以及刪除資源。同時得益于 APISIX 的熱加載能力,資源配置完成后 APISIX 將會自動更新配置,無需重啟服務,具體的架構原理可以查看下面的架構圖:

APISIX 架構圖

主要分為兩個部分:

APISIX 在其核心中,提供了路由匹配、負載均衡、服務發(fā)現、API 管理等重要功能,以及配置管理等基礎性模塊。除此之外,APISIX 插件運行時也包含其中,提供原生 Lua 插件的運行框架和多語言插件的運行框架,以及實驗性的 Wasm 插件運行時等。APISIX 多語言插件運行時提供多種開發(fā)語言的支持,比如 Golang、Java、Python、JS 等。

APISIX 目前也內置了各類插件,覆蓋了 API 網關的各種領域,如認證鑒權、安全、可觀測性、流量管理、多協議接入等。當前 APISIX 內置的插件使用原生 Lua 實現,關于各個插件的介紹與使用方式,后續(xù)我們再介紹。

創(chuàng)建路由

下面的示例中我們先使用 Admin API 來創(chuàng)建一個 Route 并與 Upstream 綁定,當一個請求到達 APISIX 時,APISIX 會將請求轉發(fā)到指定的上游服務中。

以下示例代碼中,我們將為路由配置匹配規(guī)則,以便 APISIX 可以將請求轉發(fā)到對應的上游服務:

? curl "http://127.0.0.1:9180/apisix/admin/routes/1" -X PUT -d '
{
"methods": ["GET"],
"host": "youdianzhishi.com",
"uri": "/anything/*",
"upstream": {
"type": "roundrobin",
"nodes": {
"httpbin.org:80": 1
}
}
}' -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1'
# 正常會得到如下所示的結果
{"value":{"create_time":1679392758,"methods":["GET"],"host":"youdianzhishi.com","status":1,"priority":0,"update_time":1679392758,"upstream":{"pass_host":"pass","hash_on":"vars","type":"roundrobin","nodes":{"httpbin.org:80":1},"scheme":"http"},"id":"1","uri":"/anything/*"},"key":"/apisix/routes/1"}

其中的 X-API-KEY 的值在 APISIX 的配置文件中 apisix_config.yaml 中有配置,位于 deployment.admin.admin_key 下面。

該配置意味著,當請求滿足下述的所有規(guī)則時,請求將被轉發(fā)到上游服務(httpbin.org:80):

當路由創(chuàng)建完成后,現在我們就可以通過以下命令訪問上游服務了:

? curl -i -X GET "http://127.0.0.1:9080/anything/foo?arg=10" -H "Host: youdianzhishi.com"
HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 443
Connection: keep-alive
Date: Tue, 21 Mar 2023 08:25:49 GMT
Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true
Server: APISIX/3.2.0

{
"args": {
"arg": "10"
},
"data": "",
"files": {},
"form": {},
"headers": {
"Accept": "*/*",
"Host": "youdianzhishi.com",
"User-Agent": "curl/7.85.0",
"X-Amzn-Trace-Id": "Root=1-64196a0d-1d2b654b29cbed3f7a9302c7",
"X-Forwarded-Host": "youdianzhishi.com"
},
"json": null,
"method": "GET",
"origin": "172.22.0.1, 221.11.206.200",
"url": "http://youdianzhishi.com/anything/foo?arg=10"
}

該請求將被 APISIX 轉發(fā)到?http://httpbin.org:80/anything/foo?arg=10,我們可以和直接訪問上游數據進行對比。

httpbin數據

使用上游服務創(chuàng)建路由

我們還可以通過以下命令創(chuàng)建一個上游,并在路由中使用它,而不是直接將其配置在路由中:

? curl "http://127.0.0.1:9180/apisix/admin/upstreams/1" -X PUT -d '
{
"type": "roundrobin",
"nodes": {
"httpbin.org:80": 1
}
}' -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1'
# 正常會得到如下所示的輸出
{"value":{"type":"roundrobin","create_time":1679392818,"pass_host":"pass","hash_on":"vars","update_time":1679392818,"nodes":{"httpbin.org:80":1},"id":"1","scheme":"http"},"key":"/apisix/upstreams/1"}

該上游配置與上一節(jié)配置在路由中的上游相同。同樣使用了 roundrobin 作為負載均衡機制,并設置了 httpbin.org:80 為上游服務。為了將該上游綁定到路由,此處需要把 upstream_id 設置為 “1”。

上游服務創(chuàng)建完成后,現在我們可以通過以下命令將其綁定到指定的 /get 路由:

? curl "http://127.0.0.1:9180/apisix/admin/routes/1" -X PUT -d '
{
"uri": "/get",
"host": "httpbin.org",
"upstream_id": "1"
}' -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1'
# 正常會得到如下所示的輸出
{"value":{"upstream_id":"1","status":1,"create_time":1679392758,"host":"httpbin.org","update_time":1679392834,"priority":0,"id":"1","uri":"/get"},"key":"/apisix/routes/1"}

我們已經創(chuàng)建了路由與上游服務,現在可以通過以下命令訪問上游服務:

? curl -i -X GET "http://127.0.0.1:9080/get?foo1=bar1&foo2=bar2" -H "Host: httpbin.org"
HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 370
Connection: keep-alive
Date: Tue, 21 Mar 2023 08:40:19 GMT
Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true
Server: APISIX/3.2.0

{
"args": {
"foo1": "bar1",
"foo2": "bar2"
},
"headers": {
"Accept": "*/*",
"Host": "httpbin.org",
"User-Agent": "curl/7.85.0",
"X-Amzn-Trace-Id": "Root=1-64196d73-165daa124c362e5d4c6bb79d",
"X-Forwarded-Host": "httpbin.org"
},
"origin": "172.22.0.1, 221.11.206.200",
"url": "http://httpbin.org/get?foo1=bar1&foo2=bar2"
}

同樣該請求也會被 APISIX 轉發(fā)到 http://httpbin.org:80/anything/foo?arg=10

使用 Dashboard

同樣我們還可以使用 APISIX Dashboard 創(chuàng)建和配置類似于上述步驟中所創(chuàng)建的路由。

如果你已經完成上述操作步驟,正常現在我們已經可以通過 localhost:9000 來訪問 APISIX Dashboard 了。

dashboard

默認的用戶名和密碼均為 admin,在 examples 目錄中 dashboard_conf 下面的 conf.yaml 進行配置:

authentication:
secret: secret
expire_time: 3600
users:
- username: admin
password: admin
- username: user
password: user

上面我們的 docker-compose 中也已經啟動了 Grafana,所以登錄后我們也可以在首頁儀表盤上配置 Grafana,地址為 http://localhost:3000。

Grafana

登錄后單擊側邊欄中的路由,可以查看已經配置的路由列表,可以看到在上述步驟中使用 Admin API 創(chuàng)建的路由。

路由列表

你也可以通過單擊創(chuàng)建按鈕并按照提示創(chuàng)建新路由:

如果想利用 APISIX 實現身份驗證、安全性、限流限速和可觀測性等功能,可通過添加插件實現。

限流限速和安全插件

在很多時候,我們的 API 并不是處于一個非常安全的狀態(tài),它隨時會收到不正常的訪問,一旦訪問流量突增,可能就會導致你的 API 發(fā)生故障,這個時候我們就可以通過速率限制來保護 API 服務,限制非正常的訪問請求。對此,我們可以使用如下方式進行:

APISIX 提供了多個內置的限流限速的插件,包括?limit-connlimit-count?和?limit-req。

這里我們就以?limit-count?插件為例,來說明如何通過限流限速插件保護我們的 API 服務。如下所示。

使用下面的命令首先創(chuàng)建一條路由:

? curl -i http://127.0.0.1:9180/apisix/admin/routes/1 -X PUT -d '
{
"uri": "/index.html",
"plugins": {
"limit-count": {
"count": 2,
"time_window": 60,
"rejected_code": 503,
"key_type": "var",
"key": "remote_addr"
}
},
"upstream_id": "1"
}' -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1'

這里我們直接使用前面已經創(chuàng)建的上游(ID 為 1)來創(chuàng)建/更新一條路由,并且在 plugins 中啟用了 limit-count 插件,該插件僅允許客戶端在 60 秒內,訪問上游服務 2 次,超過兩次,就會返回 503 錯誤碼。

上面的指令執(zhí)行成功后,接下來我們連續(xù)使用下面的命令訪問三次后,則會出現如下錯誤。

? curl http://127.0.0.1:9080/index.html
? curl http://127.0.0.1:9080/index.html
? curl http://127.0.0.1:9080/index.html

正常情況下就會出現如下所示的 503 錯誤,則表示 limit-count 插件已經配置成功。

<html>
<head>
<title>503 Service Temporarily Unavailable</title>
</head>
<body>
<center><h1>503 Service Temporarily Unavailable</h1></center>
<hr />
<center>openresty</center>
<p>
<em>Powered by <a >APISIX</a>.</em>
</p>
</body>
</html>

緩存響應

當我們在構建一個 API 時,肯定希望他能夠盡量保持簡單和快速,一旦讀取相同數據的并發(fā)需求增加,可能會面臨一些問題,一般我們直接的辦法就是引入緩存,當然我們可以在不同層面去進行緩存的。

反向代理緩存是另一種緩存機制,通常在 API 網關內實現。它可以減少對你的端點的調用次數,也可以通過緩存上游的響應來改善對你的 API 請求的延遲。如果 API Gateway 的緩存中有所請求資源的新鮮副本,它就會使用該副本直接滿足請求,而不是向端點發(fā)出請求。如果沒有找到緩存的數據,請求就會轉到預定的上游服務(后端服務)。

我們這里主要了解的是 API 網關層的緩存,也就是 APISIX 提供的 API 緩存,它也可以和其他插件一起使用,目前支持基于磁盤的緩存,也可以在插件配置中指定緩存過期時間或內存容量等。

比如我們現在有一個 /products 的 API 接口,通常每天只更新一次,而該端點每天都會收到重復的數十億次請求,以獲取產品列表數據,現在我們就可以使用 APISIX 提供的一個名為 proxy-cache 的插件來緩存該接口的響應。

這里我們還是使用前面 ID 為 1 的上游對象,使用 /anything/products 來模擬產品接口,直接執(zhí)行下面的命令來更新路由的插件:

? curl "http://127.0.0.1:9180/apisix/admin/routes/1" -H "X-API-KEY: edd1c9f034335f136f87ad84b625c8f1" -X PUT -d '{
"name": "Route for API Caching",
"methods": [
"GET"
],
"uri": "/anything/*",
"plugins": {
"proxy-cache": {
"cache_key": [
"$uri",
"-cache-id"
],
"cache_bypass": [
"$arg_bypass"
],
"cache_method": [
"GET"
],
"cache_http_status": [
200
],
"hide_cache_headers": true,
"no_cache": [
"$arg_test"
]
}
},
"upstream_id": "1"
}'

更新完成后現在我們來對該接口發(fā)起幾次請求:

? curl http://localhost:9080/anything/products -i

HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 398
Connection: keep-alive
Date: Tue, 21 Mar 2023 10:48:42 GMT
Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true
Server: APISIX/3.2.0
Apisix-Cache-Status: MISS

? curl http://localhost:9080/anything/products -i

HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 398
Connection: keep-alive
Date: Tue, 21 Mar 2023 10:48:42 GMT
Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true
Server: APISIX/3.2.0
Apisix-Cache-Status: HIT

正常每次都應該收到 HTTP 200 OK 響應,但是第一次響應中的 Apisix-Cache-Status 顯示為 MISS,這意味著當請求第一次進入路由時,響應還沒有被緩存。而后面的幾次請求會得到一個緩存的響應,緩存指標變?yōu)榱?nbsp;HIT,表示我們的響應緩存成功了。

本文章轉載微信公眾號@k8s技術圈

上一篇:

HapiJS 身份驗證 : 使用 JWT 保護您的 API

下一篇:

PyJWT:輕松搞定Token認證,讓你的API更安全!
#你可能也喜歡這些API文章!

我們有何不同?

API服務商零注冊

多API并行試用

數據驅動選型,提升決策效率

查看全部API→
??

熱門場景實測,選對API

#AI文本生成大模型API

對比大模型API的內容創(chuàng)意新穎性、情感共鳴力、商業(yè)轉化潛力

25個渠道
一鍵對比試用API 限時免費

#AI深度推理大模型API

對比大模型API的邏輯推理準確性、分析深度、可視化建議合理性

10個渠道
一鍵對比試用API 限時免費