api网关(kong&apisix)对比

目录

  • 网关是什么?
  • api网关
  • api网关的作用
  • 常见api网关
    • OpenResty
    • Kong
    • ApiSix
  • Kong的使用
    • 安装配置
    • Kong配置
      • 名词解析
      • kong的内部流程
      • 配置service
      • 配置route
  • APISIX的使用
    • [Deploy Apache APISIX with Docker](https://apisix.apache.org/docs/docker/manual/)
    • dockerCompose一波带走
    • 动态负载均衡
      • 创建 APISIX Upstream(上游,后端 API 服务)
      • 创建 APISIX Route
      • 尝试访问
    • 限流限速
      • 配置 limit-req 插件
      • limit-conn
    • 身份验证
      • [配置 JWT-auth 插件](https://apisix.apache.org/docs/apisix/plugins/jwt-auth/)
      • consumer使用 JWT-auth 插件
      • Route使用 JWT-auth 插件
      • 测试
    • 健康检查
  • 总结

网关是什么?

  1. 网关,可以将网关比作“门”,但是需要区分网关与网桥的区别;

    1. 网桥工作在数据链路层,在不同或相同类型的LAN之间存储并转发数据帧,必要时进行链路层上的协议转换。可连接两个或多个网络,在其中传送信息包。

    2. 网关是一个大概念,不具体特指一类产品,只要连接两个不同的网络都可以叫网关,网桥一般只转发信息,而网关可能进行包装。

  2. 通俗的例子:

    1. 假如你要去找集团老板
    2. 所有想见老板的人都得从公司大门进入(统一入口)(这个门相当于将办公室和外界隔离了,主要为了保护里面的安全以及正常工作)。
    3. 门卫肯定会让你出示相关证件(鉴权检验)。
    4. 如果鉴权之后, 发现你找老板其实只是为了和他谈谈两元店的生意, 门卫会跟你说这个用不着找老板, 你去集团投资部就行了(动态路由, 将请求路由到不同的后端集群中), 此时会对你进行一些包装,例如给你出具一个访问证类似的,然后告诉你路该怎么走…

api网关

对应过来,api网关就是:

  1. API网关是一个服务器,是系统的唯一入口。(“门”)
  2. API网关封装了系统内部架构,为每个客户端提供一个定制的API。(隔离)
  3. 可能还具有其它职责,如身份验证、监控、负载均衡、缓存、协议转换、限流熔断、静态响应处理。(鉴权,负载,动态路由)
  4. API网关方式的核心要点是,所有的客户端和消费端都通过统一的网关接入微服务。

api网关(kong&apisix)对比_第1张图片

api网关的作用

微服务网关作为微服务后端服务的统一入口,它可以统筹管理后端服务,主要分为数据平面和控制平面:

  • 数据平面主要功能是接入用户的HTTP请求和微服务被拆分后的聚合。使用微服务网关统一对外暴露后端服务的API和契约,路由和过滤功能正是网关的核心能力模块。另外,微服务网关可以实现拦截机制和专注跨横切面的功能,包括协议转换、安全认证、熔断限流、灰度发布、日志管理、流量监控等。

  • 控制平面主要功能是对后端服务做统一的管控和配置管理。例如,可以控制网关的弹性伸缩;可以统一下发配置;可以对网关服务添加标签;可以在微服务网关上通过配置Swagger功能统一将后端服务的API契约暴露给使用方,完成文档服务,提高工作效率和降低沟通成本

  • 路由功能:路由是微服务网关的核心能力。通过路由功能微服务网关可以将请求转发到目标微服务。在微服务架构中,网关可以结合注册中心的动态服务发现,实现对后端服务的发现,调用方只需要知道网关对外暴露的服务API就可以透明地访问后端微服务。

  • 负载均衡:API网关结合负载均衡技术,利用Eureka或者Consul等服务发现工具,通过轮询、指定权重、IP地址哈希等机制实现下游服务的负载均衡。

  • 统一鉴权:一般而言,无论对内网还是外网的接口都需要做用户身份认证,而用户认证在一些规模较大的系统中都会采用统一的单点登录(Single Sign On)系统,如果每个微服务都要对接单点登录系统,那么显然比较浪费资源且开发效率低。API网关是统一管理安全性的绝佳场所,可以将认证的部分抽取到网关层,微服务系统无须关注认证的逻辑,只关注自身业务即可。

  • 协议转换:API网关的一大作用在于构建异构系统,API网关作为单一入口,通过协议转换整合后台基于REST、AMQP、Dubbo等不同风格和实现技术的微服务,面向Web Mobile、开放平台等特定客户端提供统一服务。

  • 指标监控:网关可以统计后端服务的请求次数,并且可以实时地更新当前的流量健康状态,可以对URL粒度的服务进行延迟统计,也可以使用Hystrix Dashboard查看后端服务的流量状态及是否有熔断发生。

  • 限流熔断:在某些场景下需要控制客户端的访问次数和访问频率,一些高并发系统有时还会有限流的需求。在网关上可以配置一个阈值,当请求数超过阈值时就直接返回错误而不继续访问后台服务。当出现流量洪峰或者后端服务出现延迟或故障时,网关能够主动进行熔断,保护后端服务,并保持前端用户体验良好。

  • 黑白名单:微服务网关可以使用系统黑名单,过滤HTTP请求特征,拦截异常客户端的请求,例如DDoS攻击等侵蚀带宽或资源迫使服务中断等行为,可以在网关层面进行拦截过滤。比较常见的拦截策略是根据IP地址增加黑名单。在存在鉴权管理的路由服务中可以通过设置白名单跳过鉴权管理而直接访问后端服务资源。

  • 灰度发布:微服务网关可以根据HTTP请求中的特殊标记和后端服务列表元数据标识进行流量控制,实现在用户无感知的情况下完成灰度发布。

  • 流量染色:和灰度发布的原理相似,网关可以根据HTTP请求的Host、Head、Agent等标识对请求进行染色,有了网关的流量染色功能,我们可以对服务后续的调用链路进行跟踪,对服务延迟及服务运行状况进行进一步的链路分析。

  • 文档中心:网关结合Swagger,可以将后端的微服务暴露给网关,网关作为统一的入口给接口的使用方提供查看后端服务的API规范,不需要知道每一个后端微服务的Swagger地址,这样网关起到了对后端API聚合的效果。

  • 日志审计:微服务网关可以作为统一的日志记录和收集器,对服务URL粒度的日志请求信息和响应信息进行拦截

常见api网关

  1. Nginx+lua:OpenRestyKong、Orange、Abtesting gateway 等
  2. Java:Zuul/Zuul2、Spring Cloud Gateway、Kaazing KWG、gravitee、Dromara soul 等
  3. Go:Janus、fagongzi、Grpc-gateway
  4. Dotnet:Ocelot
  5. NodeJS:Express Gateway、Micro Gateway

按照使用数量、成熟度等来划分,主流的有 4 个:

  1. OpenResty
  2. Kong
  3. Zuul/Zuul2
  4. Spring Cloud Gateway

c++的水太深,小伙子们把握不住,java太复杂繁琐,因此可以选择的api网关有:OpenResty,Kong,Grpc-Gateway.

Kong Traefik Ambassador Tyk Zuul
基本
主要用途 企业级API管理 微服务网关 微服务网关 微服务网关 微服务网关
学习曲线 适中 simple simple 适中 simple
成本 开源/企业版 开源 开源/pro 开源/企业版 开源
社区star 20742 21194 1719 4299 7186
配置
配置语言 Admin Rest api, Text file(nginx.conf 等) TOML YAML(kubernetes annotation) Tyk REST API REST API,YAML静态配置
配置端点类型 命令式 声明式 声明式 命令式 命令式
拖拽配置 yes no no no no
管理模式 configurable decentralised, self-service decentralised, self-service decentralised, self-service decentralised, self-service
部署
kubernetes 适中(k8s yaml,helm chart) easy easy 适中(k8s yaml,helm chart) 适中(k8s yaml,helm chart)
Cloud IAAS high easy N/A easy easy
Private Data Center high easy N/A easy easy
部署模式 金丝雀(企业版) 金丝雀 金丝雀,shadow 金丝雀 金丝雀
state postgres,cassandra kubernetes kubernetes redis 内存文件
可扩展性
扩展功能 插件 自己实现 插件 插件 自己实现
扩展方法 水平 水平 水平 水平 水平
功能
服务发现 动态 动态 动态 动态 动态
协议 http,https,websocket http,https,grpc,websocket http,https,grpc,websocket http,https,grpc,websocket http,https
基于 kong+nginx traefik envoy tyk zuul
ssl 终止 yes yes yes yes no
websocket yes yes yes yes no
routing host,path,method host,path host,path,header host,path
限流 yes no yes yes 需要开发
熔断 yes yes no yes 需要其他组件
重试 yes yes no yes yes
健康检查 yes no no yes yes
负载均衡算法 轮询,哈希 轮询,加权轮询 加权轮询 轮询 轮询,随机,加权轮询,自定义
权限 Basic Auth, HMAC, JWT, Key, LDAP, OAuth 2.0, PASETO, plus paid Kong Enterprise options like OpenID Connect basic yes HMAC,JWT,Mutual TLS,OpenID Connect,基本身份验证,LDAP,社交OAuth(例如GPlus,Twitter,Github)和传统基本身份验证提供程序 开发实现
tracing yes yes yes yes 需要其他组件
istio集成 no no yes no no
dashboard yes yes grafana,Prometheus yes

OpenResty

  1. OpenResty基于 Nginx 与 Lua 的高性能 Web 平台,其内部集成了大量精良的 Lua 库、第三方模块以及大多数的依赖项。用于方便地搭建能够处理超高并发、扩展性极高的动态 Web 应用、Web 服务和动态网关。

  2. 通过揉和众多设计良好的 Nginx 模块,OpenResty 有效地把 Nginx 服务器转变为一个强大的 Web 应用服务器,基于它开发人员可以使用 Lua 编程语言对 Nginx 核心以及现有的各种 Nginx C 模块进行脚本编程,构建出可以处理一万以上并发请求的极端高性能的 Web 应用

Kong

  1. kong是一款基于OpenResty(Nginx + Lua模块)编写的高可用、易扩展的,由Mashape公司开源的API Gateway项目。
  2. Kong是基于NGINX和Apache Cassandra或PostgreSQL构建的,能提供易于使用的RESTful API来操作和配置API管理系统,所以它可以水平扩展多个Kong服务器,通过前置的负载均衡配置把请求均匀地分发到各个Server,来应对大批量的网络请求。
  3. 中文文档:https://github.com/qianyugang/kong-docs-cn

ApiSix

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

APISIX 通过插件机制,提供了动态负载平衡、身份验证、限流限速等等功能,当然我们也可以自己开发插件进行拓展。

api网关(kong&apisix)对比_第2张图片

Kong的使用

安装配置

  1. docker安装kong:安装文档

  2. 使用docker安装postgresql:

    docker run -d --name kong-database \
               --network=kong-net \
               -p 5432:5432 \
               -e "POSTGRES_USER=kong" \
               -e "POSTGRES_DB=kong" \
               -e "POSTGRES_PASSWORD=Passw0rd" \
               -e "POSTGRES_HOST_AUTH_METHOD=trust" \
               postgres:9.6
    
  3. 使用临时Kong容器运行迁移:

    docker run --rm \
        --network=kong-net \
        -e "KONG_LOG_LEVEL=debug" \
        -e "KONG_DATABASE=postgres" \
        -e "KONG_PG_HOST=kong-database" \
        -e "KONG_PG_PASSWORD=Passw0rd" \
        -e "KONG_CASSANDRA_CONTACT_POINTS=kong-database" \
        kong:latest kong migrations bootstrap
    
  4. 启动Kong

    docker run -d --name kong \
     --network=kong-net \
     -e "KONG_DATABASE=postgres" \
     -e "KONG_PG_HOST=kong-database" \
     -e "KONG_PG_PASSWORD=Passw0rd" \
     -e "KONG_CASSANDRA_CONTACT_POINTS=kong-database" \
     -e "KONG_PROXY_ACCESS_LOG=/dev/stdout" \
     -e "KONG_ADMIN_ACCESS_LOG=/dev/stdout" \
     -e "KONG_PROXY_ERROR_LOG=/dev/stderr" \
     -e "KONG_ADMIN_ERROR_LOG=/dev/stderr" \
     -e "KONG_ADMIN_LISTEN=0.0.0.0:8001, 0.0.0.0:8444 ssl" \
     -p 8000:8000 \
     -p 8443:8443 \
     -p 8001:8001 \
     -p 8444:8444 \
     kong:latest
    
  5. 安装图形化界面

    docker run -d -p 1337:1337 --name konga pantsel/konga
    

    api网关(kong&apisix)对比_第3张图片

  6. 配置kong地址
    api网关(kong&apisix)对比_第4张图片

Kong配置

名词解析

kong作为网关基本功能是路由转发,konga提供图形化界面来配置kong。首先如果需要配置kong第一步需要理解konga的几个术语。

  • route
     route是所有请求的入口,也就是kong会根据route的不同来转发到不同的service,一个route只能对应一个service,但是一个service可以有多个route,并且route不能单独存在,必须是先建立service后才能建立route。
  • service
     service其实可以理解为一个微服务,konga通过service桥接route和upstream,一个service只能有一个upstream。
  • upstream
     upstream其实就是一个上游地址,upstream可以有多个target,target就是真实的目标地址,target可以是一个ip地址或者是一个域名

kong的内部流程

api网关(kong&apisix)对比_第5张图片

配置service

首先需要创建一个service,service作为route和upstream的桥梁,所以第一步先创建一个service。

api网关(kong&apisix)对比_第6张图片

  1. Name:可以随便填,但是建议填某个有意义的名称比如为某个微服务的名称。
  2. Description:就是一个描述信息,可以不填,建议填微服务的中文描述。
  3. Tags:标签,可以填多个,填一个需要按一个回车确定,这个可以不填。
  4. Url:这个需要注意一下,因为这个比较重要,这个其实是下面四个的合体,填了这个,下面的四个不需要填,也就是Protocol,Host,Port,Path这四个的合体,这个值不会保存,提交后konga会自动拆成下面四个,其实就是一个访问的完整URL,对应的目标地址。
  5. Protocol:请求协议,可选值:http,https。
  6. Host:目标域名,这里可以是一个内部域名或者直接可以访问的地址,如果是内部域名,则需要匹配有相关的upstream,若是外部可以访问的地址,则不需要配置upstream。
  7. Port:端口
  8. Path:访问路径,也就是若匹配upstream后自动添加的路径

配置route

api网关(kong&apisix)对比_第7张图片

  1. Name:这个可以不填,若不填,konga会默认生成一个随机字符串。
    重点关注Hosts,Paths,Methods这三个属性,这三个是主要的属性。这三个属性必须三选一,也就是路由匹配规则。
  2. Hosts这个是匹配访问的域名,这一般是配置为二级域名,比如配置为 blog.github.com ,若在以这个域名访问,则匹配成功,可以填多个,这里注意填完一个后需要按回车键确定。
  3. Paths属性,这个用的最多,就是根据路径匹配,比如配置为/konga,则访问如 www.xxxx.com/konga 则匹配成功。
  4. Methods换个就是http请求方法,比如get,post这些。
  5. Strip Path:这个属性也需要注意一下,就是当path匹配时,是否去掉,如果打开,则去掉,比如上面所说的/konga,访问后面的host时,则不会带上/konga。
  6. Preserve Host:这个选项的意思是真是请求host时是否保留,如果保留,则请求的的header里面的来源为原始来源,否则为service中定义的host

APISIX的使用

Deploy Apache APISIX with Docker

  1. 创建APISIX网络

    docker network create \
     --driver=bridge \
     --subnet=172.18.0.0/16 \
     --ip-range=172.18.5.0/24 \
     --gateway=172.18.5.254 \
     apisix
     或
    docker network create apisix
    
  2. 创建目录:
    在这里插入图片描述

  3. 编写apisix和etcd的配置文件,参考官方文档:https://github.com/apache/apisix-docker/blob/master/example/apisix_conf/config.yaml

    apisix:
      node_listen: 9080              # APISIX listening port
      enable_ipv6: false
    
      enable_control: true
      control:
        ip: "0.0.0.0"
        port: 9092
    
    deployment:
      admin:
        allow_admin:               # https://nginx.org/en/docs/http/ngx_http_access_module.html#allow
          - 0.0.0.0/0              # We need to restrict ip access rules for security. 0.0.0.0/0 is for test.
    
        admin_key:
          - name: "admin"
            key: edd1c9f034335f136f87ad84b625c8f1
            role: admin                 # admin: manage all configuration data
    
          - name: "viewer"
            key: 4054f7cf07e344346cd3f287985e76a2
            role: viewer
    
      etcd:
        host:                           # it's possible to define multiple etcd hosts addresses of the same etcd cluster.
          - "http://etcd:2379"          # multiple etcd address
        prefix: "/apisix"               # apisix configurations prefix
        timeout: 30                     # 30 seconds
    
    plugin_attr:
      prometheus:
        export_addr:
          ip: "0.0.0.0"
          port: 9091
    

    etcd:

    # Human-readable name for this member.
    name: 'default'
    
    # Path to the data directory.
    data-dir:
    
    # Path to the dedicated wal directory.
    wal-dir:
    
    # Number of committed transactions to trigger a snapshot to disk.
    snapshot-count: 10000
    
    # Time (in milliseconds) of a heartbeat interval.
    heartbeat-interval: 100
    
    # Time (in milliseconds) for an election to timeout.
    election-timeout: 1000
    
    # Raise alarms when backend size exceeds the given quota. 0 means use the
    # default quota.
    quota-backend-bytes: 0
    
    # List of comma separated URLs to listen on for peer traffic.
    listen-peer-urls: http://0.0.0.0:2380
    
    # List of comma separated URLs to listen on for client traffic.
    listen-client-urls: http://0.0.0.0:2379
    
    # Maximum number of snapshot files to retain (0 is unlimited).
    max-snapshots: 5
    
    # Maximum number of wal files to retain (0 is unlimited).
    max-wals: 5
    
    # Comma-separated white list of origins for CORS (cross-origin resource sharing).
    cors:
    
    # List of this member's peer URLs to advertise to the rest of the cluster.
    # The URLs needed to be a comma-separated list.
    initial-advertise-peer-urls: http://localhost:2380
    
    # List of this member's client URLs to advertise to the public.
    # The URLs needed to be a comma-separated list.
    advertise-client-urls: http://localhost:2379
    
    # Discovery URL used to bootstrap the cluster.
    discovery:
    
    # Valid values include 'exit', 'proxy'
    discovery-fallback: 'proxy'
    
    # HTTP proxy to use for traffic to discovery service.
    discovery-proxy:
    
    # DNS domain used to bootstrap initial cluster.
    discovery-srv:
    
    # Initial cluster configuration for bootstrapping.
    initial-cluster:
    
    # Initial cluster token for the etcd cluster during bootstrap.
    initial-cluster-token: 'etcd-cluster'
    
    # Initial cluster state ('new' or 'existing').
    initial-cluster-state: 'new'
    
    # Reject reconfiguration requests that would cause quorum loss.
    strict-reconfig-check: false
    
    # Accept etcd V2 client requests
    enable-v2: true
    
    # Enable runtime profiling data via HTTP server
    enable-pprof: true
    
    # Valid values include 'on', 'readonly', 'off'
    proxy: 'off'
    
    # Time (in milliseconds) an endpoint will be held in a failed state.
    proxy-failure-wait: 5000
    
    # Time (in milliseconds) of the endpoints refresh interval.
    proxy-refresh-interval: 30000
    
    # Time (in milliseconds) for a dial to timeout.
    proxy-dial-timeout: 1000
    
    # Time (in milliseconds) for a write to timeout.
    proxy-write-timeout: 5000
    
    # Time (in milliseconds) for a read to timeout.
    proxy-read-timeout: 0
    
    client-transport-security:
      # Path to the client server TLS cert file.
      cert-file:
    
      # Path to the client server TLS key file.
      key-file:
    
      # Enable client cert authentication.
      client-cert-auth: false
    
      # Path to the client server TLS trusted CA cert file.
      trusted-ca-file:
    
      # Client TLS using generated certificates
      auto-tls: false
    
    peer-transport-security:
      # Path to the peer server TLS cert file.
      cert-file:
    
      # Path to the peer server TLS key file.
      key-file:
    
      # Enable peer client cert authentication.
      client-cert-auth: false
    
      # Path to the peer server TLS trusted CA cert file.
      trusted-ca-file:
    
      # Peer TLS using generated certificates.
      auto-tls: false
    
    # Enable debug-level logging for etcd.
    debug: false
    
    logger: zap
    
    # Specify 'stdout' or 'stderr' to skip journald logging even when running under systemd.
    log-outputs: [stderr]
    
    # Force to create a new one member cluster.
    force-new-cluster: false
    
    auto-compaction-mode: periodic
    auto-compaction-retention: "1"
    
  4. 启动etcd服务(apisix不支持etcdv3)

    docker run -it --name etcd-server -d \
    -v `pwd`/example/etcd_conf/etcd.conf.yml:/opt/bitnami/etcd/conf/etcd.conf.yml \
    -p 2379:2379 \
    -p 2380:2380  \
    --network apisix \
    --ip 172.18.5.10 \
    --env ALLOW_NONE_AUTHENTICATION=yes ETCD_ENABLE_V2: "true"\
    bitnami/etcd:3.4.9
    或
    docker run -it --name etcd-server \
    -v `pwd`/example/etcd_conf/etcd.conf.yml:/opt/bitnami/etcd/conf/etcd.conf.yml \
    -p 2379:2379 \
    -p 2380:2380  \
    --network apisix \
    --env ALLOW_NONE_AUTHENTICATION=yes bitnami/etcd:3.4.9
    
  5. 启动ApiSix服务

    docker run --name test-api-gateway \
     -v `pwd`/example/apisix_conf/config.yaml:/usr/local/apisix/conf/config.yaml \
     -v `pwd`/example/apisix_log:/usr/local/apisix/logs  \
     --privileged=true \
     -p 9080:9080 \
     -p 9091:9091  \
     -p 9443:9443 \
     --network apisix \
     --ip 172.18.5.11 \
     -d apache/apisix
     或
     docker run --name test-api-gateway \
     -v `pwd`/example/apisix_conf/config.yaml:/usr/local/apisix/conf/config.yaml \
     -v `pwd`/example/apisix_log:/usr/local/apisix/logs  \
     --privileged=true \
     -p 9080:9080 \
     -p 9091:9091  \
     -p 9443:9443 \
     --network apisix \
     -d apache/apisix
    

dockerCompose一波带走

手动部署动不动出错,可以直接下载官方案例:

git clone https://github.com/apache/apisix-docker.git

在这里插入图片描述
然后进入example目录:
在这里插入图片描述
执行docker compose up,所有服务就都启动了:

api网关(kong&apisix)对比_第8张图片

进入登录页面:

api网关(kong&apisix)对比_第9张图片
账号密码都在配置文件里面保存了,默认是admin/adminuser/user

动态负载均衡

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

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

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

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

在 APISIX 控制台的「Upstream」菜单中,创建一个 APISIX Upstream。如下图所示:

api网关(kong&apisix)对比_第11张图片
由于官方example自动启动了两个nginx,
在这里插入图片描述
就以这两个nginx作为服务。

创建 APISIX Route

APISIX Route,字面意思就是路由,通过定义一些规则来匹配客户端的请求,然后根据匹配结果加载并执行相应的 插件,并把请求转发给到指定 Upstream。
api网关(kong&apisix)对比_第12张图片
选择上一步创建的上游:
api网关(kong&apisix)对比_第13张图片

尝试访问

访问http://192.168.71.151:9080/,apisix会将/这个请求路径的请求发到nginx1/nginx2/上。

api网关(kong&apisix)对比_第14张图片
api网关(kong&apisix)对比_第15张图片

注意9080是网关的端口,9000是apisix的端口,不要带入错了。

限流限速

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

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

配置 limit-req 插件

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

编辑上文创建的路由:
api网关(kong&apisix)对比_第16张图片
选择limit-req
api网关(kong&apisix)对比_第17张图片
属性说明:

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

api网关(kong&apisix)对比_第18张图片
上述截图配置含义:限制了每秒请求速率为 1,大于 1 小于 2的会被加上延时,速率超过 2就会被拒绝。

然后用go模仿高并发:

const limit = 100

func request(wg *sync.WaitGroup, number int) {
	defer wg.Done()

	resp, err := http.Get("http://192.168.71.151:9080/")
	if err != nil {
		log.Println(err)
		return
	}

	body := resp.Body
	defer body.Close()

	content, _ := io.ReadAll(body)
	fmt.Println("第", number, "次请求", "状态码", resp.StatusCode, "响应body", string(content))
}

func main() {
	wg := new(sync.WaitGroup)
	defer wg.Wait()

	wg.Add(limit)
	for i := 0; i < limit; i++ {
		go request(wg, i)
	}
}

请求结果:
api网关(kong&apisix)对比_第19张图片

limit-conn

Apisix 的限制或并发连接插件。

属性:

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

区别与limit-req,limit-conn是用户请求过来,服务端拒绝服务,所以应该返回5xx状态码。而limit-req是客户请求数量超过限制了,服务端运行相关逻辑,已经提供服务了(哪怕返回403也是提供服务了)。

api网关(kong&apisix)对比_第20张图片
上面启用的插件的参数表示只允许两个并发请求。 当收到多个并发请求时,将直接返回 503 拒绝请求。

api网关(kong&apisix)对比_第21张图片

身份验证

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

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

配置 JWT-auth 插件

属性:

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

consumer使用 JWT-auth 插件

名称 类型 必选项 默认值 有效值 描述
key string Consumer 的 access_key 必须是唯一的。如果不同 Consumer 使用了相同的 access_key ,将会出现请求匹配异常。
secret string 加密秘钥。如果未指定,后台将会自动生成。该字段支持使用 APISIX Secret 资源,将值保存在 Secret Manager 中。
public_key string RSA 或 ECDSA 公钥, algorithm 属性选择 RS256ES256 算法时必选。该字段支持使用 APISIX Secret 资源,将值保存在 Secret Manager 中。
private_key string RSA 或 ECDSA 私钥, algorithm 属性选择 RS256ES256 算法时必选。该字段支持使用 APISIX Secret 资源,将值保存在 Secret Manager 中。
algorithm string "HS256" ["HS256", "HS512", "RS256", "ES256"] 加密算法。
exp integer 86400 [1,...] token 的超时时间。
base64_secret boolean false 当设置为 true 时,密钥为 base64 编码。
lifetime_grace_period integer 0 [0,...] 定义生成 JWT 的服务器和验证 JWT 的服务器之间的时钟偏移。该值应该是零(0)或一个正整数。

api网关(kong&apisix)对比_第22张图片

Route使用 JWT-auth 插件

我已经创建了一个 APISIX Route:/。这里,我们给该 Route 配置下 JWT-auth 插件。如下图所示:
api网关(kong&apisix)对比_第23张图片

测试

  1. 首先,你需要为签发 token 的 API 配置一个 Route,该路由将使用 public-api 插件。(必须用命令,因为页面配置需要上游)

    curl http://127.0.0.1:9180/apisix/admin/routes/jas \
    -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
    {
        "uri": "/apisix/plugin/jwt/sign",
        "plugins": {
            "public-api": {}
        }
    }'
    

api网关(kong&apisix)对比_第24张图片

  1. 获取token

api网关(kong&apisix)对比_第25张图片
也可以加入payload:
api网关(kong&apisix)对比_第26张图片

  1. 不携带token直接访问:
    api网关(kong&apisix)对比_第27张图片

  2. 携带token访问:
    api网关(kong&apisix)对比_第28张图片
    将代码修改为:

    func request(wg *sync.WaitGroup, number int) {
    	defer wg.Done()
    
    	req, _ := http.NewRequest(http.MethodGet, "http://192.168.71.151:9080/", nil)
    	req.Header.Set("Authorization", "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9.eyJrZXkiOiJnZW5lcmFsenkiLCJleHAiOjE2OTMxMTYzMTB9.smOD99jrHfuUjJiHuhhVrd8VZxiafp9j6uLvLol0uW5ZSdJ135gI6dVvhAnoaVGQYNwje19kEBW4W76w-_saRw")
    
    	resp, _ := http.DefaultClient.Do(req)
    
    	body := resp.Body
    	defer body.Close()
    
    	content, _ := io.ReadAll(body)
    	fmt.Println("第", number, "次请求", "状态码", resp.StatusCode, "响应body", string(content))
    }
    
    func main() {
    	wg := new(sync.WaitGroup)
    	defer wg.Wait()
    
    	wg.Add(limit)
    	for i := 0; i < limit; i++ {
    		go request(wg, i)
    	}
    }
    

    api网关(kong&apisix)对比_第29张图片

健康检查

支持对上游节点的主动和被动健康检查,在负载均衡时自动过滤掉不健康的节点。

由于控制台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 字段,来保证安全。

generalzy:服务deploy于k8s一般都会配置存活探针,个人感觉没必要细读apisix的健康检查模块。

总结

APISIX 和 Kong 都是流行的开源API网关项目,它们在功能、架构和生态系统等方面有一些区别。下面是一个对比它们的优劣势的概览,但需要注意的是,这些优劣势在不同的使用情境下可能会有所不同。

APISIX 的优劣势:

优势:

  1. 高性能: APISIX使用Nginx作为底层引擎,因此具有卓越的性能和吞吐量,适用于高流量环境。

  2. 动态配置: APISIX支持动态配置,可以实时更改路由、插件和策略,无需重启网关。

  3. 插件系统: APISIX提供了丰富的插件系统,允许用户根据需要轻松地添加和定制功能,如认证、限流、监控等。

  4. 灰度发布: APISIX支持灰度发布,使您可以逐步将流量引导到新版本的API,降低发布风险。

  5. 易于扩展: 作为Apache基金会项目,APISIX的开发和社区支持都是稳定和活跃的,有助于项目的长期发展。

劣势:

  1. 生态系统相对较小: 相对于Kong,APISIX的生态系统可能较小,可能缺乏一些现成的插件和解决方案。

  2. 学习曲线: 对于不熟悉Nginx配置的开发者来说,学习APISIX可能需要一些时间。

Kong 的优劣势:

优势:

  1. 丰富的插件生态: Kong拥有丰富的插件,可以轻松地添加认证、安全性、监控等功能。

  2. 易用性: Kong提供了用户友好的管理界面和REST API,使得配置和管理变得相对容易。

  3. 多种部署方式: Kong支持多种部署方式,从单节点到集群,适用于不同规模和需求。

  4. 社区和商业支持: Kong有活跃的开源社区,同时还提供商业支持和企业版,有助于满足不同层次的需求。

  5. 可扩展性: Kong的架构设计允许在需要时进行水平扩展,以应对高流量和大规模应用。

劣势:

  1. 性能相对较低: 相对于APISIX使用Nginx引擎,Kong的性能可能稍逊一筹,特别是在高负载情况下。

  2. 复杂的配置: 一些高级配置可能相对复杂,需要更深入地了解Kong的架构和配置。

总体而言,选择APISIX还是Kong取决于具体需求、团队技术能力和项目规模。如果更关注性能和动态配置,APISIX可能更适合。如果需要丰富的插件生态、易用性和多种部署方式,Kong可能是更好的选择。

你可能感兴趣的:(微服务,http,网络,java)