@
Apache APISIX官網地址 https://apisix.apache.org/ 最新版本3.2.0
Apache APISIX官網檔案地址 https://apisix.apache.org/docs/apisix/getting-started/
Apache APISIX原始碼地址 https://github.com/apache/apisix
Apache APISIX 是一個動態、實時、高效能、可延伸的雲原生 API 閘道器,提供瞭如負載均衡、動態上游、灰度釋出(金絲雀釋出)、服務熔斷、身份認證、可觀測性等豐富的流量管理功能。可以使用APISIX API Gateway來處理傳統的南北向流量,也可以用來處理服務之間的東西向流量;還可以用作k8s入口控制器。
Apache APISIX是第一個包含內建低程式碼儀表板的開源API閘道器,它為開發人員提供了強大而靈活的UI;雲原生時代,動態和可觀測性成為衡量 API 閘道器的標準之一;Apache APISIX 自誕生之初就一直跟隨著雲原生的腳步前行。
備註:南北向流量可以簡單理解使用者端到伺服器端,也即是我們傳統上使用Nginx;東西向流量更多的是後臺微服務之間的通訊。
在單體服務時代,使用 NGINX 可以應對大多數的場景,而到了雲原生時代,NGINX 因為其自身架構的原因則會出現兩個問題:
而 Kong 的出現則解決了 NGINX 的痛點,但是又帶來了新的問題:
而 APISIX 的出現則解決了上述所有問題,成為了雲原生時代最完美的 API 閘道器。Apache APISIX 和 Kong相比在技術方面的主要優勢大部分都是在底層模組上的優化和創新;在簡單的 PoC 上並不一定能夠體現出這些技術的優勢,但在複雜的生產環境中,Apache APISIX 的這些優勢將會造成巨大的差距。
Apache APISIX的特性較多,下面只是列出部分特性和說明。
平臺支援:APISIX 提供了平臺級解決方案,不但支援裸機執行,也支援在 Kubernetes 中雲原生使用。
眾多協定支援:如TCP/UDP Proxy、Dubbo Proxy、Dynamic MQTT Proxy、gRPC proxy、HTTP(S) Forward Proxy等
全動態能力
精細化路由
安全
運維友好
高可延伸
多語言支援:Apache APISIX是一個用於外掛開發的多語言閘道器,並通過RPC和Wasm提供支援。
Serverless:支援與Lua函數、AWS Lambda、Azure Functions、Apache OpenWhisk等雲服務整合。
Apache APISIX基於NGINX和etcd。與傳統的API閘道器相比,APISIX具有動態路由、熱載入外掛等特性。
APISIX 的架構主要分成如下兩部分「
APISIX 目標是統一代理基礎設施,其核心為高效能代理服務,自身不繫結任何環境屬性。當它演變為 Ingress、服務網格等產品時,都是外部服務與 APISIX 配合,變化的是外部程式而不是 APISIX 自身。
APISIX 主要分為兩個部分:
概念/元件 | 描述 |
---|---|
Route | 通過路由定義規則來匹配使用者端請求,根據匹配結果載入並執行相應的外掛,最後把請求轉發給到指定的上游應用。 |
Upstream | 上游的作用是按照設定規則對服務節點進行負載均衡,它的地址資訊可以直接設定到路由或服務上。 |
Admin API | 使用者可以通過 Admin API 控制 APISIX 範例。 |
外掛載入流程
外掛內部結構
# quickstart 指令碼快速安裝並啟動,該命令在本地安裝並執行了基於 Docker 的 APISIX 和 etcd 容器,其中 APISIX 採用 etcd 儲存和同步設定資訊。APISIX 和 etcd 容器使用 host 的 Docker 網路模式,因此可以從本地直接存取。
curl -sL https://run.api7.ai/apisix/quickstart | sh
# 請確保其他系統程序沒有佔用 9080、9180、9443 和 2379 埠。可以通過 curl 來存取正在執行的 APISIX 範例。比如,你可以傳送一個簡單的 HTTP 請求來驗證 APISIX 執行狀態是否正常。
curl "http://127.0.0.1:9080" --head | grep Server
# 以httpbin.org這個簡單的HTTP請求和響應服務作為演示,詳細可以直接查閱http://httpbin.org/,使用httpbin.org測試介面來體驗下,如果希望這個介面在本地執行,可採用docker部署,docker Run -p 80:80 kennethreitz/httpbin
curl --location --request GET "http://httpbin.org/get?param1=value1¶m2=value2"
curl "http://127.0.0.1:9180/apisix/admin/routes/1" -X PUT -d '
{
"methods": ["GET"],
"host": "mytest.com",
"uri": "/anything/*",
"upstream": {
"type": "roundrobin",
"nodes": {
"httpbin.org:80": 1
}
}
}'
# 當路由建立完成後,可以通過以下命令存取上游服務,該請求將被 APISIX 轉發到 http://httpbin.org:80/anything/foo?arg=10
curl -i -X GET "http://127.0.0.1:9080/anything/foo?arg=10" -H "Host: mytest.com"
也可以設定hosts對映,然後在瀏覽器直接存取http://mytest.com:9080/anything/foo?arg=10
curl "http://127.0.0.1:9180/apisix/admin/upstreams/1" -X PUT -d '
{
"type": "roundrobin",
"nodes": {
"httpbin.org:80": 1
}
}'
然後在通過以下命令繫結到指定路由
curl "http://127.0.0.1:9180/apisix/admin/routes/1" -X PUT -d '
{
"uri": "/get",
"host": "httpbin.org",
"upstream_id": "1"
}'
可以通過下面命令存取上游服務,該請求將被 APISIX 轉發到 http://httpbin.org:80/anything/foo?arg=10
。
curl -i -X GET "http://127.0.0.1:9080/get?foo1=bar1&foo2=bar2" -H "Host: httpbin.org"
APISIX使用etcd儲存和同步設定,在安裝APISIX之前需要安裝etcd。
ETCD_VERSION='3.5.7'
wget https://github.com/etcd-io/etcd/releases/download/v${ETCD_VERSION}/etcd-v${ETCD_VERSION}-linux-amd64.tar.gz
tar -xvf etcd-v${ETCD_VERSION}-linux-amd64.tar.gz
cd etcd-v${ETCD_VERSION}-linux-amd64
cp -a etcd etcdctl /usr/bin/
nohup etcd >/tmp/etcd.log 2>&1 &
APISIX RPM安裝適用於CentOS 7和CentOS 8
# 如果沒有安裝OpenResty,可執行以下命令同時安裝OpenResty和APISI倉庫yum install -y https://repos.apiseven.com/packages/centos/apache-apisix-repo-1.0-1.noarch.rpm# 如果安裝了OpenResty,下面的命令將安裝APISIX儲存庫:yum-config-manager --add-repo https://repos.apiseven.com/packages/centos/apache-apisix.repo# 安裝APISIXyum install apisix# 還可以通過指定APISIX來安裝特定版本的APISIXyum install apisix-3.1.0# 管理APISIX伺服器,安裝APISIX後,可以通過以下命令初始化組態檔和etcdapisix init# 檢查組態檔是否爭取apisix test
# 啟動apisixapisix start# 正常關閉apisix,確保停止之前完成所有收到的請求apisix quit# 強制關閉apisix並丟棄所有請求apisix stop
更改組態檔,路徑在/usr/local/apisix/conf/config.yaml
# 在啟動APISIX時,通過使用--config或-c標誌將路徑傳遞給組態檔,APISIX將使用此組態檔中新增的設定,如果沒有設定任何內容,則將退回到預設設定。apisix start -c <path to config file>
警告注意:
建議修改Admin API金鑰以保證安全性,修改conf/config.yaml,修改後重啟apisix
deployment: admin: admin_key - name: "admin" key: edd1c9f034335f136f87ad84b625c123 role: admin
# 存取Admin API,你可以使用新的密碼curl http://127.0.0.1:9180/apisix/admin/routes?api_key=edd1c9f034335f136f87ad84b625c123 -i
# docker
git clone https://github.com/apache/apisix-docker.git
# 進入目錄
cd apisix-docker/example
# 可以檢視和修改檔案,這裡將apisix-dashboard暴露本機埠改為19000
vim docker-compose.yml
# 使用docker-compose啟動APISIX
docker-compose -p docker-apisix up -d
存取http://hadoop2:19000,輸入使用者名稱密碼admin/admin即可登入成功(密碼設定在docker-compose指定的組態檔dashboard_conf/conf.yaml中)
dashboard 視覺化 WEB 控制檯,可以很直觀的進行 router 、upstream 等設定。登入後的首頁即為儀表板,這是通過在iframe中參照監視器頁面來支援它可以設定grafana的地址,比如設定http://grafanaip:3000,快捷操作grafana
# 現在本地搭建httpbin服務
docker run -p 5080:80 kennethreitz/httpbin
點選上游選單,點選建立按鈕,目標節點新增httpbin.org和上面我們剛部署內網httpbin,其他暫時預設,點選下一步然後提交。
點選路由選單,點選建立按鈕,目標節點新增httpbin.org和上面我們剛部署內網httpbin,其他暫時預設,點選下一步然後提交。
設定上游服務選擇前面建立的,其他先保持預設,最後提交
執行存取測試
curl -i -X GET "http://127.0.0.1:9080/anything/foo?arg=10"
discovery:
nacos:
host:
- "http://nacos:[email protected]:8848"
prefix: "/nacos/v1/"
fetch_interval: 30 # default 30 sec
weight: 100 # default 100
timeout:
connect: 2000 # default 2000 ms
send: 2000 # default 2000 ms
read: 5000 # default 5000 ms
docker-compose -p docker-apisix down
docker-compose -p docker-apisix up -d
新增order路由,輸入路徑資訊點選下一步
路由中選擇前面新增order上游,其他預設最終提交
存取apisix監聽地址,http://hadoop2:9080/order/add,最後成功返回訂單微服務的介面資料
plugins:
- skywalking # 啟用skywalking外掛
plugin_attr:
skywalking: # 設定skywalking的屬性
service_name: APISIX_GATEWAY
service_instance_name: "APISIX_INSTANCE_GATEWAY"
endpoint_addr: http://192.168.3.113:12800 # skywalking的地址,本機預設是這個,可自行修改
在彈出的頁面的外掛設定中點選啟用按鈕然後提交,然後一直下一步最後提交
返回路由列表也可以通過操作-更多-檢視,顯示資料編輯器內容
<dependency>
<groupId>org.apache.skywalking</groupId>
<artifactId>apm-toolkit-trace</artifactId>
<version>8.14.0</version>
</dependency>
<dependency>
<groupId>org.apache.skywalking</groupId>
<artifactId>apm-toolkit-logback-1.x</artifactId>
<version>8.14.0</version>
</dependency>
在logback-spring.xml新增列印skywalking鏈路紀錄檔資訊
<configuration debug="false" scan="false">
<springProperty scop="context" name="spring.application.name" source="spring.application.name" defaultValue=""/>
<property name="log.path" value="logs/${spring.application.name}"/>
<!-- 彩色紀錄檔格式 -->
<property name="CONSOLE_LOG_PATTERN"
value="${CONSOLE_LOG_PATTERN:-%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}"/>
<!-- 彩色紀錄檔依賴的渲染類 -->
<conversionRule conversionWord="clr" converterClass="org.springframework.boot.logging.logback.ColorConverter"/>
<conversionRule conversionWord="wex"
converterClass="org.springframework.boot.logging.logback.WhitespaceThrowableProxyConverter"/>
<conversionRule conversionWord="wEx"
converterClass="org.springframework.boot.logging.logback.ExtendedWhitespaceThrowableProxyConverter"/>
<!-- Console log output -->
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>${CONSOLE_LOG_PATTERN}</pattern>
</encoder>
</appender>
<!-- Log file debug output -->
<appender name="debug" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${log.path}/debug.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>${log.path}/%d{yyyy-MM, aux}/debug.%d{yyyy-MM-dd}.%i.log.gz</fileNamePattern>
<maxFileSize>50MB</maxFileSize>
<maxHistory>30</maxHistory>
</rollingPolicy>
<encoder>
<pattern>%date [%thread] %-5level [%logger{50}] %file:%line - %msg%n</pattern>
</encoder>
</appender>
<!-- Log file error output -->
<appender name="error" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${log.path}/error.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>${log.path}/%d{yyyy-MM}/error.%d{yyyy-MM-dd}.%i.log.gz</fileNamePattern>
<maxFileSize>50MB</maxFileSize>
<maxHistory>30</maxHistory>
</rollingPolicy>
<encoder>
<pattern>%date [%thread] %-5level [%logger{50}] %file:%line - %msg%n</pattern>
</encoder>
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>ERROR</level>
</filter>
</appender>
<appender name="stdout" class="ch.qos.logback.core.ConsoleAppender">
<encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
<layout class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.TraceIdPatternLogbackLayout">
<Pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%tid] [%thread] %-5level %logger{36} -%msg%n</Pattern>
</layout>
</encoder>
</appender>
<appender name="grpc" class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.log.GRPCLogClientAppender">
<encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
<layout class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.mdc.TraceIdMDCPatternLogbackLayout">
<Pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%X{tid}] [%thread] %-5level %logger{36} -%msg%n</Pattern>
</layout>
</encoder>
</appender>
<!--nacos 心跳 INFO 遮蔽-->
<logger name="com.alibaba.nacos" level="OFF">
<appender-ref ref="error"/>
</logger>
<!-- Level: FATAL 0 ERROR 3 WARN 4 INFO 6 DEBUG 7 -->
<root level="INFO">
<!-- <appender-ref ref="console"/>-->
<appender-ref ref="debug"/>
<appender-ref ref="error"/>
<appender-ref ref="stdout"/>
<appender-ref ref="grpc"/>
</root>
</configuration>
將agent.config 拷貝到訂單微服務的resources目錄下,庫存微服務修改agent.config下面兩個設定,詳細查閱skywalking前面的文章
agent.service_name=${SW_AGENT_NAME:ecom-storage-service}
collector.backend_service=${SW_AGENT_COLLECTOR_BACKEND_SERVICES:192.168.3.113:11800}
# 啟動jvm引數增加
-javaagent:F:\commoms\skywalking-agent\skywalking-agent.jar
-Dskywalking_config=F:\dev\simple-ecommerce\ecom-storage-service\src\main\resources\agent.config
存取http://hadoop2:9080/order/add多次看下,在普通服務就可以看到訂單微服務和APISIX_GATEWAY。
通過Trace可以看到紀錄檔鏈路經過了APISIX_GATEWAY和訂單微服務,至此基本整合演示完畢