Apache APISIX 集成 Consul KV,服务发现能力再升级

背景信息

Consul 是一个服务网格解决方案,其核心之一的 Consul KV 是一个分布式键值数据库,主要用途是存储配置参数和元数据,同时也允许用户存储索引对象。

在微服务架构模式下,当扩容、硬件故障等导致上游服务发生变动的情况出现时,通过手动撰写配置,维护上游服务信息的方式,会导致维护成本陡增。对此,Apache APISIX 提供了服务发现注册中心的功能,实现动态获取最新的服务实例信息,以降低用户的维护成本。

目前,Apache APISIX 借由社区贡献的 consul_kv 模块,支持了基于 Consul KV 的服务发现注册中心。

插件工作原理

Apache APISIX 利用 Consul KV 分布式键值存储能力的 consul_kv 模块,解耦了服务的提供者和消费者,实现了服务发现注册中心的两大核心功能。

  1. 服务注册:服务提供者向注册中心注册服务。
  2. 服务发现:服务消费者通过注册中心查找服务提供者的路由信息。

在此基础上构建的 Apache APISIX 将更灵活地适应现有的微服务架构,更好地满足用户需求。

img

如何使用

本文中的测试环境均使用 docker-compose 在 Docker 中搭建。

  1. 下载 Apache APISIX。
# 拉取 apisix-docker 的 Git 仓库
git clone https://github.com/apache/apisix-docker.git 
  1. 创建 Consul 文件夹和配置文件。
# 创建 consul 文件夹
mkdir -p ~/docker-things/consul/ && cd "$_" 
# 创建配置文件
touch docker-compose.yml server1.json
  1. 修改 docker-compose.yml 文件。
version: '3.8'

services:
  consul-server1:
    image: consul:1.9.3
    container_name: consul-server1
    restart: always
    volumes:
      - ./server1.json:/consul/config/server1.json:ro
    networks:
      - apisix
    ports:
      - '8500:8500'
    command: 'agent -bootstrap-expect=1'

networks:
  apisix:
    external: true
    name: example_apisix
  1. 修改 server1.json 文件。
{
  "node_name": "consul-server1",
  "server": true,
  "addresses": {
    "http": "0.0.0.0"
  }
}
  1. 在 Apache APISIX 中的配置文件 apisix_conf/config.yaml 添加 Consul 的相关配置信息。
# config.yml
# ...other config
discovery:
  consul_kv:
    servers:
      - "http://consul-server1:8500"
    prefix: "upstreams"
  1. 启动 Apache APISIX 和 Consul。
# 进入 example、consul 文件夹,依次启动 APISIX、Consul
docker-compose up -d
  1. 将测试服务注册到 Consul。example 包含了两个 Web 服务,你可以直接使用这两个服务进行测试。
# 检查 example 的 docker-compose.yml 就可以看到两个 Web 服务
$ cat docker-compose.yml | grep web
# 输出
web1:
  - ./upstream/web1.conf:/etc/nginx/nginx.conf
web2:
  - ./upstream/web2.conf:/etc/nginx/nginx.conf
  1. 确认 Web 服务的 IP 地址。
$ sudo docker inspect -f='{{.Name}} - {{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' $(sudo docker ps -aq) | grep web
# 输出
/example-web1-1 - 172.26.0.7
/example-web2-1 - 172.26.0.2
  1. 在终端中对 Consul 的 HTTP API 进行请求以注册测试服务。
# 使用对应的 IP 进行注册
curl \
  -X PUT \
  -d ' {"weight": 1, "max_fails": 2, "fail_timeout": 1}' \
  http://127.0.0.1:8500/v1/kv/upstreams/webpages/172.26.0.7:80
  
curl \
  -X PUT \
  -d ' {"weight": 1, "max_fails": 2, "fail_timeout": 1}' \
  http://127.0.0.1:8500/v1/kv/upstreams/webpages/172.26.0.2:80

其中,/v1/kv/ 后的路径按照 {Prefix}/{Service Name}/{IP}:{Port} 的格式构成。

{Prefix} 是在 APISIX 中配置 Consul 时写入的 prefix{Service Name}{IP}:{Port} 则需要根据上游服务,由用户自行确定。

而数据的格式则为 {"weight": <Num>, "max_fails": <Num>, "fail_timeout": <Num>}

  1. 查看测试服务是否注册成功。
$ curl "http://127.0.0.1:8500/v1/kv/upstreams/webpages?keys"

返回消息如下则表示注册成功。

# 注册成功的输出
["upstreams/webpages/172.26.0.2:80","upstreams/webpages/172.26.0.7:80"]% 

创建路由并为其启用 Consul

使用 Apache APISIX 提供的 Admin API 将 Consul 添加到路由中。

在添加之前需要先确定 X-API-KEYupstream.service_name 两个数据。

  • X-API-KEY:Admin API 的访问 Token,在此示例中,我们使用默认的 edd1c9f034335f136f87ad84b625c8f1 即可。
  • upstream.service_name:上游服务的名称,它指定了将与某个路由绑定的某个注册中心中的服务(Service),使用 Consul 时需要设置为注册测试服务时的 URL,并去掉最后的 {IP}:{Port} 部分。我们也可以通过 Apache APISIX 提供的 Memory Dump API 获取服务的 URL,同时确认是否能正常发现上游服务。
$ curl http://127.0.0.1:9092/v1/discovery/consul_kv/dump | jq
# 输出
{
  "services": {
    # 这个 key 就是需要的 URL
    "http://consul-server1:8500/v1/kv/upstreams/webpages/": [
      {
        "port": 80,
        "host": "172.26.0.7",
        "weight": 1
      },
      {
        "port": 80,
        "host": "172.26.0.2",
        "weight": 1
      }
    ]
  },
  "config": {
    # ...configs
  }
}

添加路由

这里将 URL 为 /consul/* 的请求路由分配到 http://consul-server1:8500/v1/kv/upstreams/webpages/。同时, discovery_type 必须设置为 consul_kv 以启动对应模块。

curl http://127.0.0.1:9080/apisix/admin/routes -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X POST -d '
{    
    "uri": "/consul/*",    
    "upstream": {        
        "service_name": "http://consul-server1:8500/v1/kv/upstreams/webpages/",        
        "type": "roundrobin",
        "discovery_type": "consul_kv"    
    }
}'

测试配置结果

通过请求结果可以看到, Apache APISIX 中新增的路由已经可以通过 Consul 找到正确的服务地址,并根据负载均衡策略请求到两个节点上。

# 第一次请求
curl -s http://127.0.0.1:9080/consul/
# 输出
hello web1%

# 第二次请求
curl -s http://127.0.0.1:9080/consul/
# 输出
hello web2%

# 注意:也有可能两次请求获取的都是 web1 或者 web2。
#      这是由负载均衡的特性造成的,您可以尝试进行更多次请求。
#      如果对负载均衡感兴趣可以在 https://en.wikipedia.org/wiki/Load_balancing_(computing) 
#      中了解更多。

总结

本文的前半部分介绍了 Apache APISIX 如何配合 Consul 实现基于 Consul KV 的服务发现注册中心,解决服务信息管理维护的问题。

而在后半部分则着重介绍了如何在 Docker 中搭配 Consul 使用 Apache APISIX 的操作流程。当然,在实际场景中的应用,还需要各位读者根据业务使用场景和已有的系统架构具体分析。

关于在 Apache APISIX 中使用 Consul 注册中心的更多说明,可以在官方文档中找到。如有其他疑问,可以在 Discussions 中发起讨论,或通过邮件列表进行交流。


Apache APISIX 是一个动态、实时、高性能的云原生 API 网关,提供了负载均衡、动态上游、灰度发布、服务...

96 声望
33 粉丝
0 条评论
推荐阅读
服务网格领域的百花齐放,是否存在一个更优解?
作者@lingsamuel,API7.ai 云原生技术专家,Apache APISIX Committer。作者@林志煌,API7.ai 技术工程师,Apache APISIX contributor。

Apache_APISIX阅读 176

最新出炉!开源 API 网关的性能对比:APISIX 3.0 和 Kong 3.0
云原生时代下,企业逐渐向云上迁移,越来越多的应用和服务都在进行容器化改造,服务之间的流量也开始爆发性的增长。为了能高效地管理这些规模庞大的 API,API 网关开始在技术领域大展身手。

Apache_APISIX1阅读 594

马斯克都不懂的 GraphQL,API 网关又能对其如何理解?
上个月马斯克评论 Twitter App 滥用 RPC 后,与一些 Twitter 的技术主管发生了矛盾 —— 直言马斯克不懂技术。那这个马斯克都不懂的 GraphQL 到底是什么?

Apache_APISIX1阅读 608

APISIX Ingress 对 Gateway API 的支持和应用
本文介绍了 Gateway API 这个将服务暴露到集群之外的全新规范,并且介绍了如何在 APISIX Ingress Controller 中使用它。

Apache_APISIX阅读 735

Spring Cloud中MyBatis-Plus动态数据源刷新问题
在使用MyBatis-Plus的DynamicRoutingDataSource时遇到的问题,当我在配置中心动态增加或者删除了一个数据源,他并不会自动同步最新的数据源,导致我用DynamicDataSourceContextHolder.push(ds)方法的时候拿不到刚...

Pursuer丶阅读 668

封面图
APISIX Ingress 如何支持自定义插件
作者:张晋涛,API7.ai 云原生技术专家,Apache APISIX PMC 成员,Apache APISIX Ingress Controller 项目维护者。

Apache_APISIX阅读 557

API 全生命周期管理,如何解决企业 API 安全问题
Eotalk 是由 Eolink 和各合作方一起发起的泛技术聊天活动,每期我们会邀请一些技术圈内的大牛聊聊天,聊一下关于技术、创业工作、投融资等热点话题。

Eolink阅读 557

Apache APISIX 是一个动态、实时、高性能的云原生 API 网关,提供了负载均衡、动态上游、灰度发布、服务...

96 声望
33 粉丝
宣传栏