【API网关】APISIX介绍和安装使用

导读:本篇文章讲解 【API网关】APISIX介绍和安装使用,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com

什么是APISIX?

APISIX 是一个高性能、可扩展的微服务API网关,基于 nginx(openresty)和 Lua 实现功能,借鉴了Kong的思路,将Kong底层的关系型数据库(Postgres)替换成了NoSQL型的 etcd,这使得 APISIX 相较于 Kong 在性能上有了很大提升,在启用各类插件的情况下,Apache APISIX 的性能据说是 Kong 的 10 倍,极具吸引力。

且相较于 Kong 来说,源码更为简洁,二次开发难度更低,但是相对的,开源时间较短,在插件功能完备性上不如Kong,比如缺少关于灰度相关的插件,但是其已纳入Apache 基金会孵化,社区也较为活跃,后期的发展空间较为可观。

和传统的API网关相比,APISIX 和 Kong 一样也是通过插件的形式来提供负载均衡、日记记录、身份鉴权、流量控制等功能。

与 Kong的比较

两者优缺点:

产品/特性 优势 劣势 二次开发难度
Kong 开源社区活跃、产品思路清晰 代码量大、封装多、依赖关系型数据库、底层架构跟不上趋势 支持、难度大
APISIX 基于etcd、代码易读、插件热加载 开源时间短 支持、难度小

从 API 网关核心功能点出发:

功能 Apache APISIX Kong
动态上游 支持 支持
动态路由 支持 支持
健康检查和熔断器 支持 支持
动态SSL证书 支持 支持
七层和四层代理 支持 支持
分布式追踪 支持 支持
自定义插件 支持 支持
REST API 支持 支持
CLI 支持 支持

详细比较:

功能 Apache APISIX Kong
项目归属 Apache 软件基金会 Kong Inc.
是否开源 Apache 2.0 协议 Apache 2.0 协议(社区版)
核心技术 Nginx + Lua N ginx + Lua
数据存储 etcd Postgres、Cassandra
部署模式 单机和集群 单机和集群
支持yaml Yes Yes
交流渠道 邮件, 微信群, QQ群, GitHub, Slack, meetup GitHub, Freenode, 论坛
单核 CPU, QPS(开启限流和Prometheus 插件) 18000 1700
延迟 0.2 ms 2 ms
支持Dubbo代理 Yes No
配置回滚 Yes No
支持生命周期的路由 Yes No
插件热加载 Yes No
用户自定义负载均衡算法和路由 Yes No
REST API <–> gRPC 转码 Yes No
支持Tengine Yes No
支持MQTT协议 Yes No
配置生效时间 事件驱动, < 1ms 轮询, 5 seconds
Dashboard Yes No
IdP认证对接 Yes No
配置中心高可用(HA) Yes No
在指定的时间窗口内限速 Yes No
支持nginx变量作为路由条件 Yes No

概述

APISIX 是基于 OpenResty + etcd 实现的云原生、高性能、可扩展的微服务 API 网关。它是国人开源,目前已经进入
Apache 进行孵化。

  • OpenResty:通过 Lua 扩展 Nginx 实现的可伸缩的 Web 平台。
  • etcd:Key/Value 存储系统。

APISIX 通过插件机制,提供了动态负载平衡、身份验证、限流限速等等功能,当然我们也可以自己开发插件进行拓展。
在这里插入图片描述
整体架构

  • 动态负载均衡:跨多个上游服务的动态负载均衡,目前已支持 round-robin 轮询和一致性哈希算法。
  • 身份验证:支持 key-auth、JWT、basic-auth、wolf-rbac 等多种认证方式。
  • 限流限速:可以基于速率、请求数、并发等维度限制。

并且 APISIX 还支持 A/B 测试、金丝雀发布(灰度发布)、蓝绿部署、监控报警、服务可观测性、服务治理等等高级功能,这在作为微服务 API 网关非常重要的特性。

下面,我们正式进入 APISIX 的极简入门之旅。

安装

在《APISIX 官方文档 —— 安装》中,介绍了源码包、RPM 包、Luarocks、Docker 四种安装方式。这里我们使用 CentOS 7.X 系统,所以采用 RPM 包。
因为 APISIX 是基于 OpenResty + etcd 来实现,所以需要安装它们两个。

1. 安装依赖

CentOS 7脚本

# 安装 epel, `luarocks` 需要它
wget http://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm
sudo rpm -ivh epel-release-latest-7.noarch.rpm

# 添加 OpenResty 源
sudo yum install yum-utils
sudo yum-config-manager --add-repo https://openresty.org/package/centos/openresty.repo

# 安装 OpenResty, etcd 和 编译工具
sudo yum install -y etcd openresty curl git gcc luarocks lua-devel

# 开启 etcd server
sudo service etcd start

2 安装 Apache APISIX

通过 RPM 包安装(CentOS 7)。

2.1 安装脚本

sudo yum install -y https://github.com/apache/incubator-apisix/releases/download/1.3/apisix-1.3-0.el7.noarch.rpm

一定要看到最后打印如下信息才安装成功,否则查看报错信息来解决。

Installed:
  apisix.noarch 0:1.3-0                                                                                                                                                                                          

Complete!

此时,APISIX 安装在/usr/local/apisix/目录,使用如下命令查看各个文件夹:

$ cd /usr/local/apisix/
$ ls -ls
total 40
4 drwxr-xr-x 8 root   root 4096 May  1 11
:40 apisix # APISIX 程序
4 drwx------ 2 nobody root 4096 May  1 20:44 client_body_temp
4 drwxr-xr-x 3 root   root 4096 May  1 20:50 conf # 配置文件
4 drwxr-xr-x 6 root   root 4096 May  1 20:40 dashboard # APISIX 控制台
4 drwxr-xr-x 5 root   root 4096 May  1 20:40 deps
4 drwx------ 2 nobody root 4096 May  1 20:44 fastcgi_temp
4 drwxrwxr-x 2 root   root 4096 May  1 20:44 logs # 日志文件
4 drwx------ 2 nobody root 4096 May  1 20:44 proxy_temp
4 drwx------ 2 nobody root 4096 May  1 20:44 scgi_temp
4 drwx------ 2 nobody root 4096 May  1 20:44 uwsgi_temp

2.2 启动 APISIX

命令:sudo apisix start
默认情况下,APISIX 启动在 9080 端口,使用如下命令测试服务是否正常启动:

$ curl http://127.0.0.1:9080/
{"error_msg":"failed to match any routes"}

APISIX 控制台

APISIX 内置控制台功能,方便我们进行 APISIX 的 Route、Consumer、Service、SSL、Upstream 的查看与维护。也就是上面看到的dashboard文件夹。
dashboard 缺陷:目前dashboard还存在一些不完善的地方,一些插件的函数配置等不可直接编辑,还是得通过apisix api进行。不过基本的一些配置直接可视化配置、查看很直观,也够用。

在/usr/local/apisix/conf/nginx.conf配置文件中,设置了 APISIX 控制台的访问路径为/apisix/dashboard。如下文所示:

location /apisix/dashboard {
        allow 127.0.0.0/24;
        deny all;

    alias dashboard/;

    try_files $uri $uri/index.html /index.html;
}

考虑到安全性,APISIX 控制台只允许本机访问,因此我们需要修改/usr/local/apisix/conf/config.yaml配置文件,增加允许访问的远程 IP 地址。如下所示:

allow_admin:                  # http://nginx.org/en/docs/http/ngx_http_access_module.html#allow
    - 127.0.0.0/24              # If we don't set any IP list, then any IP access is allowed by default.
    - 211.94.246.0/24           # 新增加的远程IP地址段。

修改完配置后,使用 apisix restart 命令,重启 APISIX 来生效配置。然后,使用浏览器访问 http://101.133.227.13:9080/apisix/dashboard地址,进入 APISIX 控制台。结果如下图所示:
在这里插入图片描述dashboard控制台页面

使用默认的“admin/123456”账号,登录 APISIX 控制台。

动态负载均衡

对后端服务提供的 API 接口进行负载均衡。我们启动同一个springboot服务在2个不同端口18080 和 28080。
在这里插入图片描述

网络架构

1. 启动2个微服务命令

java -jar vue-springboot-0.0.1-SNAPSHOT-exec.jar --server.port=18080
java -jar vue-springboot-0.0.1-SNAPSHOT-exec.jar --server.port=28080

2.验证服务是否正常

curl -k --tlsv1 https://localhost:18080/v2/vue/api/programLanguage/getAll
curl -k --tlsv1 https://localhost:28080/v2/vue/api/programLanguage/getAll

返回:

["C","vue","java","PHP","Python","C++"]

如果正常返回数据即可。

3. 重要概念

一个微服务可以通过 APISIX 的路由、服务、上游和插件等多个实体之间的关系进行配置。 Route(路由)与客户端请求匹配,并指定它们到达 APISIX 后如何发送到 Upstream(上游,后端 API 服务)。 Service(服务)为上游服务提供了抽象。因此,您可以创建单个 Service 并在多个 Route 中引用它。

4.创建 APISIX Upstream(上游,后端 API 服务)

APISIX Upstream,是虚拟主机抽象,对给定的多个服务节点按照配置规则进行负载均衡。它根据配置规则在给定的一组服务节点上执行负载平衡。 因此,单个上游配置可以由提供相同服务的多个服务器组成。每个节点将包括一个 key(地址/ip:port)和一个 value (节点的权重)。 服务可以通过轮询或一致哈希(cHash)机制进行负载平衡。

配置路由时,可以直接设置 Upstream 信息,也可以使用服务抽象来引用 Upstream 信息。

在 APISIX 控制台的「Upstream」菜单中,创建一个 APISIX Upstream。如下图所示:
在这里插入图片描述

新建upstream

5. 创建 APISIX Route

APISIX Route,字面意思就是路由,通过定义一些规则来匹配客户端的请求,然后根据匹配结果加载并执行相应的 插件,并把请求转发给到指定 Upstream。
在这里插入图片描述

Routes配置

6. 测试

我们来请求 APISIX 网关地址+url,转发请求到后端服务。

6.1 浏览器访问

地址:http://101.133.227.13:9080/v2/vue/api/programLanguage/getAll,注意:101.133.227.13:9080是APISIX 网关IP和端口号,不是Springboot微服务的。
返回错误:

Bad Request
This combination of host and port requires TLS.

默认情况下,Apache APISIX 通过 HTTP 协议代理请求。如果我们的后端托管在 HTTPS 环境中,让我们使用proxy-rewrite插件将方案更改为 HTTPS,记得点击页面下方保存 按钮才能生效。
在这里插入图片描述

proxy-rewrite

6.2 浏览器再次访问

http://101.133.227.13:9080/v2/vue/api/programLanguage/getAll,
或者命令行方式访问curl -i -X GET “http://101.133.227.13:9080/v2/vue/api/programLanguage/getAll”。
正常返回结果:[“C”,“vue”,“java”,“PHP”,“Python”,“C++”]。

API 也可以通过 HTTPs(9443)端口服务访问。如果您使用的是自签名证书,那么通过 curl 命令使用 -k 参数忽略自签名证书错误。注意:使用了https和9443端口。

curl -i -k -X GET "https://101.133.227.13:9443/v2/vue/api/programLanguage/getAll"

在这里插入图片描述

https访问

限流限速

APISIX 内置了三个限流限速插件:

  • limit-count:基于“固定窗口”的限速实现。
  • limit-req:基于漏桶原理的请求限速实现。
  • limit-conn:限制并发请求(或并发连接)。

1. 配置 limit-req 插件

本小节,我们来演示使用 limit-req 插件,毕竟基于漏桶的限流算法,是目前较为常用的限流方式。

漏桶算法(Leaky Bucket)是网络世界中流量整形(Traffic Shaping)或速率限制(Rate Limiting)时经常使用的一种算法,它的主要目的是控制数据注入到网络的速率,平滑网络上的突发流量。
漏桶算法提供了一种机制,通过它,突发流量可以被整形以便为网络提供一个稳定的流量。

我们已经创建了一个 APISIX Route。这里,我们给该 Route 配置下 limit-req 插件。如下图所示:
在这里插入图片描述

限流插件

1.1 属性说明

rate:指定的请求速率(以秒为单位),请求速率超过 rate 但没有超过 (rate + brust)的请求会被加上延时
burst:请求速率超过 (rate + brust)的请求会被直接拒绝
rejected_code:当请求超过阈值被拒绝时,返回的 HTTP 状态码
key:是用来做请求计数的依据,当前接受的 key 有:“remote_addr”(客户端 IP 地址), “server_addr”(服务端 IP 地址), 请求头中的”X-Forwarded-For” 或 “X-Real-IP”。
上述截图配置含义:限制了每秒请求速率为 1,大于 1 小于 3的会被加上延时,速率超过 3就会被拒绝。

快速访问返回包含 503 返回码的响应头:

HTTP/1.1 503 Service Temporarily Unavailable
Content-Type: text/html
Content-Length: 194
Connection: keep-alive
Server: APISIX web server

<html>
<head><title>503 Service Temporarily Unavailable</title></head>
<body>
<center><h1>503 Service Temporarily Unavailable</h1></center>
<hr><center>openresty</center>
</body>
</html>

2. limit-conn

Apisix 的限制并发请求(或并发连接)插件。

2.1属性:

  • mconn: 允许的最大并发请求数。 超过这个比率的请求(低于“ conn” + “ burst”)将被延迟以符合这个阈值。
  • burst: 允许延迟的过多并发请求(或连接)的数量。
  • default_conn_delay: 默认的典型连接(或请求)的处理延迟时间。
  • key: 用户指定的限制并发级别的关键字,可以是客户端IP或服务端IP。
    例如:可以使用主机名(或服务器区域)作为关键字,以便限制每个主机名的并发性。 另外,我们也可以使用客户端地址作为关键字,这样我们就可以避免单个客户端用太多的并行连接或请求淹没我们的服务。
    现在接受以下关键字: “remote_addr”(客户端的 IP),“server_addr”(服务器的 IP),请* 求头中的“ X-Forwarded-For/X-Real-IP”。
  • rejected_code: 当请求超过阈值时返回的 HTTP状态码, 默认值是503。

2.2 在 route 页面中添加 limit-conn 插件

在这里插入图片描述

限制并发配置

上面启用的插件的参数表示只允许一个并发请求。 当收到多个并发请求时,将直接返回 503 拒绝请求。

2.3 测试

为了区别limit-req返回的503错误,可以返回码临时改成504。
访问不同的url模拟并发:

https://101.133.227.13:9443/v2/vue/api/programLanguage/getAll

https://101.133.227.13:9443/v2/vue/api/programLanguage/getAll?param=value

返回:

504 Gateway Time-out

身份验证

APISIX 内置了四个身份验证插件:

  • key-auth:基于 Key Authentication 的用户认证。
  • JWT-auth:基于 JWT (JSON Web Tokens) Authentication 的用户认证。
  • basic-auth:基于 basic auth 的用户认证。
  • wolf-rbac:基于 RBAC 的用户认证及授权。需要额外搭建 wolf 服务,提供用户、角色、资源等信息。

本小节,我们来演示使用 JWT-auth 插件。

1. 配置 JWT-auth 插件

在 APISIX 控制台的「Consumer」菜单中,创建一个 APISIX Consumer,Consumer 是某类服务的消费者,需与用户认证体系配合才能使用。添加 JWT Authentication 到一个 service 或 route。 然后 consumer 将其密钥添加到查询字符串参数、请求头或 cookie 中以验证其请求。

1.1 属性

  • key: 不同的 consumer 对象应有不同的值,它应当是唯一的。不同 consumer 使用了相同的 key ,将会出现请求匹配异常。
  • secret: 可选字段,加密秘钥。如果您未指定,后台将会自动帮您生成。
  • algorithm:可选字段,加密算法。目前支持 HS256, HS384, HS512, RS256 和 ES256,如果未指定,则默认使用 HS256。
  • exp: 可选字段,token 的超时时间,以秒为单位的计时。比如有效期是 5 分钟,那么就应设置为 5 * 60 = 300。

1.2 consumer使用 JWT-auth 插件

如下图所示:
在这里插入图片描述

1.3 Route使用 JWT-auth 插件

我们已经创建了一个 APISIX Route。这里,我们给该 Route 配置下 JWT-auth 插件。如下图所示:
在这里插入图片描述

route 配置jwt插件
配置过程很奇怪,官方文档也没怎么说明。

6.1.3 测试
调用 jwt-auth 插件提供的签名接口,获取 Token。

# key 参数,为我们配置 jwt-auth 插件时,设置的 key 属性。
curl -i -k -X GET  https://101.133.227.13:9443/apisix/plugin/jwt/sign?key=erbadagang

eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJrZXkiOiJlcmJhZGFnYW5nIiwiZXhwIjoxNTk1ODQxNjM3fQ.TyTsIDMGe8bHeXBtZ_6VjnDabbVGTZ7vHGh-PwLIixFkrXkKWLGvN1v6mlKoNCm_ccfTqU9n8h7QDeWdQZMIsA

6.1.3.1 正常情况
使用 Postman 模拟调用示例 https://101.133.227.13:9443/v2/vue/api/programLanguage/getAll 接口,并附带上 JWT。如下图所示:
在这里插入图片描述

JWT测试
6.1.3.2 如果缺少token访问会返回

{"message":"Missing JWT token in request"}

6.1.3.3 token 放到请求参数中

https://101.133.227.13:9443/v2/vue/api/programLanguage/getAll?jwt=eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJrZXkiOiJlcmJhZGFnYW5nIiwiZXhwIjoxNTk1ODQyMTg3fQ.KwOVcSIbo9hOk4Kije8tSdUSZIZ8c-ceViGrZpF6pvhZ7Ky6MZYhsDvoGVWvP9TK0FB-G0TPH_ankkiFFv7htw

6.1.3…4 token过期

{"message":"'exp' claim expired at Mon, 27 Jul 2020 09:20:37 GMT"}

配置证书

健康检查

支持对上游节点的主动和被动健康检查,在负载均衡时自动过滤掉不健康的节点。
由于控制台dashboard没有健康检查的配置项,所以需要通过APISIX api方式在服务端执行如下语句。
使用 REST Admin API 来控制 Apache APISIX,默认只允许 127.0.0.1 访问,你可以修改 conf/config.yaml 中的 allow_admin 字段,指定允许调用 Admin API 的 IP 列表。同时需要注意的是,Admin API 使用 key auth 来校验调用者身份,在部署前需要修改 conf/config.yaml 中的 admin_key 字段,来保证安全。

1. Xshell登录服务器执行

# 配置上游节点负载均衡+健康检查demo


curl http://127.0.0.1:9080/apisix/admin/routes/016  -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
{
    "uris": ["/*"],
    "plugins": {
        "limit-count": {
            "count": 2,
            "time_window": 60,
            "rejected_code": 503,
            "key": "remote_addr"
        },
        "proxy-rewrite": {
            "scheme": "https"
        }       
    },
    "upstream": {
        "desc": "guoxiuzhi_upstream",
        "nodes": {
            "127.0.0.1:18080": 1,
            "127.0.0.1:28080": 2
        },
        "type": "roundrobin",
        "retries": 2,
        "checks": {
            "active": {
                "http_path": "/status",
                "healthy": {
                    "interval": 2,
                    "successes": 1
                },
                "unhealthy": {
                    "interval": 1,
                    "http_failures": 2
                },
                "req_headers": ["User-Agent: curl/7.29.0"]
            },
            "passive": {
                "healthy": {
                    "http_statuses": [200, 201],
                    "successes": 3
                },
                "unhealthy": {
                    "http_statuses": [500],
                    "http_failures": 3,
                    "tcp_failures": 3
                }
            }
        }
    }
}'

注意:

由于我们的后端springboot是https访问的,所以配置了proxy-rewrite插件的schema,官方文档和api调用的单词拼写错误都是scheme,所以要将错就错。
X-API-KEY: edd1c9f034335f136f87ad84b625c8f1是admin账号的key,可以在conf\config.yaml的找到对应的值。
name: “admin”
key: edd1c9f034335f136f87ad84b625c8f1
role: admin

2. 成功执行上面语句后输出

{"node":{"value":{"priority":0,"plugins":{"limit-count":{"time_window":60,"count":2,"rejected_code":503,"key":"remote_addr","policy":"local"},"proxy-rewrite":{"scheme":"https"}},"uris":["\/*"],"upstream":{"retries":2,"hash_on":"vars","type":"roundrobin","nodes":{"127.0.0.1:18080":1,"127.0.0.1:28080":2},"desc":"guoxiuzhi_upstream","checks":{"active":{"unhealthy":{"http_statuses":[429,404,500,501,502,503,504,505],"interval":1,"timeouts":3,"http_failures":2,"tcp_failures":2},"concurrency":10,"http_path":"\/status","healthy":{"successes":1,"interval":2,"http_statuses":[200,302]},"req_headers":["User-Agent: curl\/7.29.0"],"https_verify_certificate":true,"timeout":1,"type":"http"},"passive":{"unhealthy":{"http_failures":3,"http_statuses":[500],"tcp_failures":3,"timeouts":7},"healthy":{"http_statuses":[200,201],"successes":3},"type":"http"}}}},"createdIndex":37,"key":"\/apisix\/routes\/016","modifiedIndex":37},"prevNode":{"value":"{\"priority\":0,\"plugins\":{\"limit-count\":{\"time_window\":60,\"count\":2,\"rejected_code\":503,\"key\":\"remote_addr\",\"policy\":\"local\"},\"proxy-rewrite\":{\"scheme\":\"https\"}},\"uris\":[\"\\\/*\"],\"upstream\":{\"retries\":2,\"nodes\":{\"127.0.0.1:18080\":1,\"127.0.0.1:28080\":2},\"hash_on\":\"vars\",\"checks\":{\"active\":{\"unhealthy\":{\"http_statuses\":[429,404,500,501,502,503,504,505],\"interval\":1,\"timeouts\":3,\"http_failures\":2,\"tcp_failures\":2},\"type\":\"http\",\"http_path\":\"\\\/status\",\"healthy\":{\"successes\":1,\"interval\":2,\"http_statuses\":[200,302]},\"req_headers\":[\"User-Agent: curl\\\/7.29.0\"],\"timeout\":1,\"https_verify_certificate\":true,\"concurrency\":10},\"passive\":{\"unhealthy\":{\"http_failures\":3,\"http_statuses\":[500],\"tcp_failures\":3,\"timeouts\":7},\"type\":\"http\",\"healthy\":{\"successes\":3,\"http_statuses\":[200,201]}}},\"desc\":\"guoxiuzhi_upstream\",\"type\":\"roundrobin\"}}","createdIndex":36,"key":"\/apisix\/routes\/016","modifiedIndex":36},"action":"set"}

3. 使配置热部署执行

curl http://127.0.0.1:9080/apisix/admin/plugins/reload -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT

返回:

done

4. 查看状态

http://101.133.227.13:9080/apisix/status

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/101217.html

(0)
小半的头像小半

相关推荐

极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!