微服务架构中,大型复杂的系统按功能或者业务需求垂直切分成更小的子系统,这些子系统以独立部署的子进程存在,它们之间通过网络调用进行通信。这些独立部署的服务如何发现对方成为了首先要解决的问题,所以在微服务架构中往往都会存在一个中心化的注册中心。

Spring 作为 Java 生态中最核心的开发框架,从 Spring MVC 到 Spring Boot 持续不断解放着 Java 开发者的生产力,而 Spring Cloud 是 Spring 面向云原生时代微服务架构给出的答案。

在 Spring Cloud 中,Eureka 就扮演了注册中心的角色。Eureka 是一款由 Netflix 开源,使用 Java 语言编写的注册中心服务,其在 Netflix 的基础设施中扮演着重要角色。

APISIX 作为云原生微服务 API 网关,在设计之初就已经支持了 etcd 作为服务发现,同时也支持 consul 、nacos 、eureka

而 Apache APISIX 作为业界领先的微服务网关,对 Eureka 提供了原生支持。本文将会使用 Spring Cloud 演示项目作为案例,为大家展示 Apache APISIX 对接 Eureka 服务发现的主要功能及特性。

准备阶段

本次演示使用 Spring 官方提供的 spring-cloud-netflix 教程作为示例,该教程中提供了使用 SpringBoot 启动的 Eureka Server 作为 Spring Cloud 的注册中心,我们也使用相同的方式来启动用于演示的 Eureka 服务端。该项目地址请访问 spring-cloud-samples/eureka。

接下来将为您介绍相关代码和启动方式。

Eureka Server

Spring Cloud 为 Eureka 提供了一个 EnableEurekaServer 的注解,可以直接以 Spring Boot 的方式启动一个 Eureka Server。

代码示例如下:

@SpringBootApplication
@EnableEurekaServer
public class EurekaApplication {public static void main(String[] args) {SpringApplication.run(EurekaApplication.class,args);}
}

启动方式可直接参考下方代码:

git clone git@github.com:spring-cloud-samples/eureka.git
# 在项目根目录执行
./gradlew bootRun

resources目录中的 application.yml 文件定义了 Eureka Server 监听在 8761 端口。

server:port: 8761

接入 Eureka Client 的 HTTP 服务

EnableEurekaServer 对应的客户端注解是 EnableEurekaClient,使用 EnableEurekaClient 可以非常简单得将一个使用 Spring Boot 启动的 HTTP 应用注册到 Eureka 上。

以下为示例代码:

@SpringBootApplication
@EnableEurekaClient
@RestController
public class Application {@Value("${server.port}")int serverPort;@RequestMapping("/")public String home() {return String.format("server-%s",serverPort);}public static void main(String[] args) {new SpringApplicationBuilder(Application.class).web(WebApplicationType.SERVLET).run(args);}}

这里我们在 / 路径上暴露一个 HTTP 服务,返回当前 Spring Boot 使用的端口,这样我们可以使用不同的配置文件,启动多个实例,来演示 APISIX 对注册到 Eureka 的服务端实例列表进行负载均衡的效果。

配置文件如下:

spring.application.name=a-bootiful-client #将会作为注册到 Eureka 中的 application name
server.port=8080 # 修改监听端口以启动多个实例

设置监听端口为 808080818082,并启动三个 Spring Boot 实例,完成后,使用浏览器访问 Eureka Server 的 8761 端口,可以查看服务注册的结果。

您可以看到应用 A-BOOTIFUL-CLIENT (注意:spring.application.name 被全部转为大写字符)下注册了三个实例,分别暴露了 808080818082 端口,并且均处于 UP 状态。

使用 APISIX 代理 SpringCloud 应用

接下来,我们将会实现如下图所示的请求链路:

启动 Apache APISIX

首先,需要在 Apache APISIX 的配置文件 config.yaml 中找到 apisix.discovery,修改 Eureka Server 连接信息的相关配置,最后启动 APISIX。

    discovery:                       # service discovery center                                                                                                                                                                                                                                                                                                                                                                         eureka:                                                                                                                                                                                                                                                                                                                                                                                                                           host:                        # it's possible to define multiple eureka hosts addresses of the same eureka cluster.                                                                                                                                                                                                                                                                                                              - "http://172.23.79.129:8761" # 通过 Spring Boot 方式启动的 Eureka Server 的访问地址                                                                                                                                                                                                                                                                                                                                                                                             prefix: /eureka/                                                                                                                                                                                                                                                                                                                                                                                                                fetch_interval: 30           # default 30s                                                                                                                                                                                                                                                                                                                                                                                      weight: 100                  # default weight for node                                                                                                                                                                                                                                                                                                                                                                          timeout:                                                                                                                                                                                                                                                                                                                                                                                                                        connect: 2000              # default 2000ms                                                                                                                                                                                                                                                                                                                                                                                   send: 2000                 # default 2000ms                                                                                                                                                                                                                                                                                                                                                                                   read: 5000                 # default 5000ms

创建路由

创建一个 Route,并在 Upstream 中配置启用 Eureka Service Discovery 插件。

curl http://172.30.45.72:9180/apisix/admin/routes/1 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -i -d '"uri": "/*","host": "eureka-demo","upstream": {"service_name": "A-BOOTIFUL-CLIENT","type": "roundrobin","discovery_type": "eureka"}
}'

其中:

  • upstream.discovery_typeeureka
  • upstream.service_name 是应用在 Eureka 中注册的应用名 A-BOOTIFUL-CLIENT

请求路由

使用 curl 命令进行多次请求,验证负载均衡效果。

$ curl http://172.30.45.72:9080/ -H "Host: eureka-demo"
server-8081%
$ curl http://172.30.45.72:9080/ -H "Host: eureka-demo"
server-8080%
$ curl http://172.30.45.72:9080/ -H "Host: eureka-demo"
server-8082%
$ curl http://172.30.45.72:9080/ -H "Host: eureka-demo"
server-8081%
$ curl http://172.30.45.72:9080/ -H "Host: eureka-demo"
server-8080%
$ curl http://172.30.45.72:9080/ -H "Host: eureka-demo"
server-8082%

从上述返回结果可以看到,请求被依次分配到 Eureka 中注册的三个实例上,这是因为我们使用的负载均衡算法是 roundrobin,所有的后端实例会被轮流分配请求。

模拟实例宕机

关闭其中 8081 实例,模拟实例宕机场景,观察请求效果。

while true; do curl http://172.30.45.72:9080/ -H "Host: eureka-demo"; echo; sleep 1; done
server-8080
server-8082
server-8081
server-8080
server-8082
server-8081
server-8080
server-8082
server-8080
server-8082
server-8080

由上述结果可以看出,关闭 8081 实例后,Apache APISIX 会及时同步到 Eureka 的最新实例列表,然后将请求转发给正确的后端。

诊断工具

在微服务系统中,经常会遇到非预期转发的问题,这些问题的原因可能来自服务发现中的各个链路,例如: 客户端注册异常,注册中心本身数据异常,网关读取注册数据异常等等,发生异常时链路中可以使用的诊断工具将会尤为重要。

所以 APISIX 在 Service Discovery 插件中提供了一个诊断接口,可以方便的查询出当前网关正在使用的服务列表,结合注册中心的控制台,我们就对网关到注册中心这一链路做出快速诊断。

诊断接口默认暴露在回环接口的9090端口,访问方式为 GET /v1/discovery/{discovery_type}/dump,例:

curl http://localhost:9090/v1/discovery/eureka/dump{"services": {"A-BOOTIFUL-CLIENT": [{"weight": 100,"metadata": {"management.port": "8081"},"host": "192.168.50.164","port": 8081},{"weight": 100,"metadata": {"management.port": "8080"},"host": "192.168.50.164","port": 8080},{"weight": 100,"metadata": {"management.port": "8082"},"host": "192.168.50.164","port": 8082}]},"config": {"prefix": "\/eureka\/","timeout": {"connect": 2000,"send": 2000,"read": 5000},"fetch_interval": 30,"host": ["http:\/\/172.23.79.129:8761"],"weight": 100}
}

这样就查询到了 APISIX 正在使用的 Eureka 数据。

总结

Spring Cloud 是一个广受用户欢迎的微服务框架,而 Apache APISIX 通过支持 Eureka Service Discovery 提供了处理 Spring Cloud 应用流量的能力,我们可以看到这两个生态的紧密结合,让微服务架构的落地变得更加简单高效,从而让业务开发可以更加的专注于业务价值。

关于 eureka 插件的更多说明和完整配置信息,可参考Eureka 官网文档:eureka。

Apache APISIX 项目目前正在开发其他插件以支持集成更多服务,如果您对此有兴趣,您可以通过GitHub Discussions 发起讨论,或通过邮件列表进行交流。

API 网关 Apache APISIX 集成 Eureka 作为服务发现相关推荐

  1. Apache APISIX 携手 CoreDNS 打开服务发现新大门

    Apache APISIX 是一个动态.实时.高性能的云原生 API 网关,提供了负载均衡.动态上游.灰度发布.服务熔断.身份认证.可观测性等丰富的流量管理功能.作为云原生 API 网关,Apache ...

  2. Api网关Kong集成Consul做服务发现及在Asp.Net Core中的使用

     1622219047536 写在前面   Api网关我们之前是用 .netcore写的 Ocelot的,使用后并没有完全达到我们的预期,花了些时间了解后觉得kong可能是个更合适的选择. 简单说下 ...

  3. 来自京东、唯品会对微服务编排、API网关、持续集成的实践分享(上)

    架构师小组交流会:每期选一个时下最热门的技术话题进行实践经验分享. 第三期:微服务.微服务架构以其高度的弹性.灵活性和效率的巨大提升,快速受到各领域架构师和技术决策者的关注.它的基本理念是将一个肥大的 ...

  4. 来自京东、宅急送对微服务编排、API网关、持续集成的实践分享(下)

    架构师小组交流会:每期选一个时下最热门的技术话题进行实践经验分享. 第三期:微服务.微服务架构以其高度的弹性.灵活性和效率的巨大提升,快速受到各领域架构师和技术决策者的关注.它的基本理念是将一个肥大的 ...

  5. 国产微服务网关Apache APISIX安装

    一.需求环境 1.openresty 版本大于 1.15.8.1 2.etcd  -- yum安装即可 3.luarocks  --源码安装 4.nodejs 版本大于10 5.Apache APIS ...

  6. 网关 Apache APISIX 在 360 基础运维平台项目中的实践

    女主宣言 今天小编为大家分享一篇关于Apache APISIX的文章,文章从开发者的角度讲述了 Apache APISIX 网关在 360 基础运维平台的落地实践,希望能对大家有所帮助. PS:丰富的 ...

  7. Apache APISIX 集成 HashiCorp Vault,生态系统再添一员

    随着微服务架构的兴起,保持服务安全变得比以前更有挑战性.多个后端 server 实例使用单一的静态密钥凭访问数据库 server 会带来巨大的风险.如果发生密钥凭证泄露,整个系统都会受到影响.为了解决 ...

  8. 10分钟上线 - API网关 + 函数计算实现图片处理服务

    摘要: 阿里云函数计算服务(FunctionCompute,FC)是一个事件驱动的全托管计算服务.通过函数计算与云端各个服务的广泛集成,开发者只需要编写函数代码,就能够快速地开发出弹性高可用的后端系统 ...

  9. 使用Apache Zookeeper进行协调和服务发现

    面向服务的设计已被证明是针对各种不同的分布式系统的成功解决方案. 如果使用得当,它会带来很多好处. 但是随着服务数量的增加,了解部署什么以及部署在何处变得更加困难. 而且,由于我们正在构建可靠且高度可 ...

最新文章

  1. linux串口工具 SRT,汇编语言实现串口通信(PC和单片机间).doc
  2. Java基础-四要素之一《封装》
  3. C++ string源码
  4. Java设计模式-工厂模式(3)抽象工厂模式
  5. (五)Vue 面试真题演练
  6. 复习Javascript专题(一):基本概念部分
  7. Re:从零开始的Vue项目搭建
  8. 数字拆分为斐波那契数列_检查数字是否为斐波那契
  9. 计算机的复数英语怎么读,英语的复数怎么读
  10. 如何导出微信聊天记录
  11. 如何备份博客:利用博客备份工具BlogDown
  12. Win2019 ServerManager.exe 0xc0000135 应用程序错误
  13. J语言初步,绝妙的符号系统,神的计算器
  14. Windows监控——性能指标详解
  15. Win10安装过程中如何跳过创建Microsoft账户
  16. Jetson嵌入式系列模型部署-1
  17. Gitee 自已提交的代码提交人头像却为他人
  18. windows照片查看器没了_Secondary Display Photo Viewer(图片查看器)下载
  19. Linux大家族的血缘关系
  20. Python中变量名后加冒号“:”以及函数后面的箭头“->”含义

热门文章

  1. linux 星际争霸,Linux模拟器完美兼容星际2 或将开启星际2新领域
  2. Ubuntu搭建web服务
  3. Vuex中的mapGetters
  4. 检测浏览器最小化或窗口隐藏的方法
  5. MacBook 电池电量未达到 100%?如何关闭电池健康管理
  6. windows笔记本电脑查看电池循环次数
  7. linux下如何使用 tcpdump 进行抓包详细教程
  8. php yaf 2.3.5,Yaf 3.2.0发布
  9. SolidUI的发展:不要身背历史包袱
  10. win2012配置pptp_windows server 2008 R2 单网卡静态地址搭建pptp服务器