? 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(xiàn)在我們就可以使用 docker-compose 來進行一鍵啟動:

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

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

docker-compose

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

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

現(xiàn)在,你已經(jīng)成功安裝并運行了 APISIX !

功能測試

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

上游

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

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

路由

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

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

服務(wù)

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

消費者

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

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

插件

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

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

Admin API

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

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

APISIX 架構(gòu)圖

主要分為兩個部分:

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

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

創(chuàng)建路由

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

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

? 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'
# 正常會得到如下所示的結(jié)果
{"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ī)則時,請求將被轉(zhuǎn)發(fā)到上游服務(wù)(httpbin.org:80):

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

? 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 轉(zhuǎn)發(fā)到?http://httpbin.org:80/anything/foo?arg=10,我們可以和直接訪問上游數(shù)據(jù)進行對比。

httpbin數(shù)據(jù)

使用上游服務(wù)創(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 作為負載均衡機制,并設(shè)置了 httpbin.org:80 為上游服務(wù)。為了將該上游綁定到路由,此處需要把 upstream_id 設(shè)置為 “1”。

上游服務(wù)創(chuàng)建完成后,現(xiàn)在我們可以通過以下命令將其綁定到指定的 /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"}

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

? 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 轉(zhuǎn)發(fā)到 http://httpbin.org:80/anything/foo?arg=10。

使用 Dashboard

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

如果你已經(jīng)完成上述操作步驟,正常現(xiàn)在我們已經(jī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 中也已經(jīng)啟動了 Grafana,所以登錄后我們也可以在首頁儀表盤上配置 Grafana,地址為 http://localhost:3000

Grafana

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

路由列表

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

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

限流限速和安全插件

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

APISIX 提供了多個內(nèi)置的限流限速的插件,包括?limit-conn、limit-count?和?limit-req

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

使用下面的命令首先創(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'

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

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

? 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

正常情況下就會出現(xiàn)如下所示的 503 錯誤,則表示 limit-count 插件已經(jīng)配置成功。

<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>

緩存響應(yīng)

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

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

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

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

這里我們還是使用前面 ID 為 1 的上游對象,使用 /anything/products 來模擬產(chǎn)品接口,直接執(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"
}'

更新完成后現(xiàn)在我們來對該接口發(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

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

本文章轉(zhuǎn)載微信公眾號@k8s技術(shù)圈

上一篇:

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

下一篇:

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

我們有何不同?

API服務(wù)商零注冊

多API并行試用

數(shù)據(jù)驅(qū)動選型,提升決策效率

查看全部API→
??

熱門場景實測,選對API

#AI文本生成大模型API

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

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

#AI深度推理大模型API

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

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