基于 Stork 和 Quarkus 扩展 Kubernetes 服务发现

本文涉及的产品
网络型负载均衡 NLB,每月750个小时 15LCU
应用型负载均衡 ALB,每月750个小时 15LCU
传统型负载均衡 CLB,每月750个小时 15LCU
简介: 在传统的单体架构中,应用程序已经通过静态主机名、IP 地址和端口知道后端服务的存在位置。IT运维团队为服务可靠性和系统稳定性维护静态配置。自从微服务开始在分布式网络系统中运行以来,其维护发生了显著变化。之所以发生这种变化,是因为微服务需要与多个后端服务进行通信,以提高负载均衡和服务弹性。

作者 | Daniel Oh

译者 | Luga Lee      

策划 | Luga Lee

   


Quarkus 使开发人员能够使用 Stork 和 Consul 为反应式 Java 应用程序集成基于客户端的负载均衡编程。

    在传统的单体架构中,应用程序已经通过静态主机名、IP 地址和端口知道后端服务的存在位置。IT运维团队为服务可靠性和系统稳定性维护静态配置。自从微服务开始在分布式网络系统中运行以来,其维护发生了显著变化。之所以发生这种变化,是因为微服务需要与多个后端服务进行通信,以提高负载均衡和服务弹性。

    随着服务应用程序被容器化并放置在 Kubernetes 上,微服务拓扑变得更加复杂。由于 Kubernetes 可以随时终止和重建应用程序容器,因此应用程序无法预先知道静态信息。微服务不需要配置后端应用的静态信息,因为 Kubernetes 会动态、自动地处理服务发现、负载均衡以及自愈。

    然而,Kubernetes 不支持通过集成应用程序配置进行程序化服务发现和基于客户端的负载均衡。Smallrye Stork 是一个解决这个问题的开源项目,它提供了以下好处和特性:

    1、增强服务发现能力

    2、支持 Consul 和 Kubernetes

    3、自定义客户端负载均衡功能

    4、可管理和编程的 API

    然而,Java 开发人员需要一些时间来适应 Stork 项目并将其与现有的 Java 框架集成。幸运的是,Quarkus 使开发人员能够将 Stork 的功能插入 Java 应用程序。本文演示了 Quarkus 如何允许开发人员将 Stork 的功能添加至 Java 应用程序中。

基于 CLI 创建 Quarkus 项目

    使用 Quarkus 命令行工具 (CLI),创建一个新的 Maven 项目。以下命令将搭建一个新的反应式 RESTful API 应用程序:


[leonli@192 ~] % quarkus create app quarkus-stork-example -x rest-client-reactive,resteasy-reactive

    结果如下所示:


...
[SUCCESS] ✅  quarkus project has been successfully generated in:
--> /Users/danieloh/Downloads/demo/quarkus-stork-example
...

    打开 pom.xml 文件并添加以下 Stork 依赖项:stork-service-discovery-consul 和 smallrye-mutiny-vertx-consul-client。 如下所示:


...
<dependency>
  <groupId>io.smallrye.stork</groupId>
  <artifactId>stork-service-discovery-consul</artifactId>
</dependency>
<dependency>
  <groupId>io.smallrye.reactive</groupId>
  <artifactId>smallrye-mutiny-vertx-consul-client</artifactId>
</dependency>
...

为发现创建新服务

    创建 Stork 负载均衡器将发现的两个服务( hero 和 villain )。然后在项目目录

src/main/java/org/acme 中创建一个新的服务目录。 

    接着在 src/main/java/org/acme/services 中新建一个 HeroService.java 文件。

将以下代码添加到 HeroService.java 文件中,该文件将基于 Vert.x 响应式引擎创建一个新的 HTTP 服务器:


@ApplicationScoped
public class HeroService {
    @ConfigProperty(name = "hero-service-port", defaultValue = "9000") int port;
    public void init(@Observes StartupEvent ev, Vertx vertx) {
        vertx.createHttpServer()
                .requestHandler(req -> req.response().endAndForget("Super Hero!"))
                .listenAndAwait(port);
    }
}

    接下来,通过创建 VillainService.java 文件来创建另一个服务。唯一的区别是您需要在 init() 方法中设置不同的名称、端口和返回消息,如下所示:


@ConfigProperty(name = "villain-service-port", defaultValue = "9001") int port;
public void init(@Observes StartupEvent ev, Vertx vertx) {
        vertx.createHttpServer()
                .requestHandler(req -> req.response().endAndForget("Super Villain!"))
                .listenAndAwait(port);
}

向 Consul 注册服务

    如上述所述,Stork 允许您使用基于 Vert.x Consul Client 的 Consul 进行服务注册。

    创建一个新的 ConsulRegistration.java 文件,在 src/main/java/org/acme/services 中注册两个同名的服务(my-rest-service)。

     最后,添加如下 ConfigProperty 和 init() 方法,具体如下所示:


@ApplicationScoped
public class ConsulRegistration {
    @ConfigProperty(name = "consul.host") String host;
    @ConfigProperty(name = "consul.port") int port;
    @ConfigProperty(name = "hero-service-port", defaultValue = "9000") int hero;
    @ConfigProperty(name = "villain-service-port", defaultValue = "9001") int villain;
    public void init(@Observes StartupEvent ev, Vertx vertx) {
        ConsulClient client = ConsulClient.create(vertx, new ConsulClientOptions().setHost(host).setPort(port));
        client.registerServiceAndAwait(
                new ServiceOptions().setPort(hero).setAddress("localhost").setName("my-rest-service").setId("hero"));
        client.registerServiceAndAwait(
                new ServiceOptions().setPort(villain).setAddress("localhost").setName("my-rest-service").setId("villain"));
    }
}

将反应式 REST 客户端委托给 Stork

    hero 和 villain 服务是普通的反应式 RESTful 服务,可以通过可公开的 API 直接访问。 需要将这些服务委托给 Stork 以进行服务发现、选择和调用。

    在 src/main/java 目录下新建一个接口 MyRestClient.java 文件。然后添加以下代码:


@RegisterRestClient(baseUri = "stork://my-rest-service")
public interface MyRestClient {
    @GET
    @Produces(MediaType.TEXT_PLAIN)
    String get();
}

    以 stork:// 开头的 baseUri 使 Stork 能够发现服务并根据负载均衡类型选择服务。

    接下来,修改现有资源文件或创建新资源文件 (MyRestClientResource) 以注入 RestClient (MyRestClient) 以及端点 (/api),如下所示:


@Path("/api")
public class MyRestClientResource {
    @RestClient MyRestClient myRestClient;
    @GET
    @Produces(MediaType.TEXT_PLAIN)
    public String invoke() {
        return myRestClient.get();
    }
}

    在运行应用程序之前,将 Stork 配置为使用 application.properties 中的 Consul 服务器,如下所示:


consul.host=localhost
consul.port=8500
stork.my-rest-service.service-discovery=consul
stork.my-rest-service.service-discovery.consul-host=localhost
stork.my-rest-service.service-discovery.consul-port=8500
stork.my-rest-service.load-balancer=round-robin

测试应用程序

    通常有多种方法来运行本地 Consul 服务,对于此示例,使用容器运行。这种方法可能比安装或引用外部服务更为简单。


[leonli@192 ~] % docker run --rm --name consul -p 8500:8500 -p 8501:8501 consul:1.7 agent -dev -ui -client=0.0.0.0 -bind=0.0.0.0 --https-port=8501

    接下来,使用开发模式运行我们的 Quarkus 应用程序:


[leonli@192 ~] % cd quarkus-stork-example
[leonli@192 ~] % quarkus dev

    运行结果如下所示:


...
INFO  [io.quarkus] (Quarkus Main Thread) Profile dev activated. Live Coding activated.
INFO  [io.quarkus] (Quarkus Main Thread) Installed features: [cdi, jaxrs-client-reactive, rest-client-reactive, resteasy-reactive, smallrye-context-propagation, vertx]
--
Tests paused
Press [r] to resume testing, [o] Toggle test output, [:] for the terminal, [h] for more options>
Access the RESTful API (/api) to retrieve available services based on the round-robin load balancing mechanism. Execute the following curl command-line in your local terminal:
& while true; do curl localhost:8080/api ; echo ''; sleep 1; done
Super Villain!
Super Hero!
Super Villain!
Super Hero!
Super Villain!
...

    总结:

    您了解了 Quarkus 如何使开发人员能够使用 Stork 和 Consul 为反应式 Java 应用程序集成基于客户端的负载均衡编程。开发人员在继续在 Quarkus 中开发反应式编程的同时,还可以使用实时编码获得更好的开发人员体验。

    有关 Quarkus 的更多信息,大家可访问 Quarkus 指南和实践。


相关实践学习
通过Ingress进行灰度发布
本场景您将运行一个简单的应用,部署一个新的应用用于新的发布,并通过Ingress能力实现灰度发布。
容器应用与集群管理
欢迎来到《容器应用与集群管理》课程,本课程是“云原生容器Clouder认证“系列中的第二阶段。课程将向您介绍与容器集群相关的概念和技术,这些概念和技术可以帮助您了解阿里云容器服务ACK/ACK Serverless的使用。同时,本课程也会向您介绍可以采取的工具、方法和可操作步骤,以帮助您了解如何基于容器服务ACK Serverless构建和管理企业级应用。 学习完本课程后,您将能够: 掌握容器集群、容器编排的基本概念 掌握Kubernetes的基础概念及核心思想 掌握阿里云容器服务ACK/ACK Serverless概念及使用方法 基于容器服务ACK Serverless搭建和管理企业级网站应用
相关文章
|
2月前
|
弹性计算 人工智能 Serverless
阿里云ACK One:注册集群云上节点池(CPU/GPU)自动弹性伸缩,助力企业业务高效扩展
在当今数字化时代,企业业务的快速增长对IT基础设施提出了更高要求。然而,传统IDC数据中心却在业务存在扩容慢、缩容难等问题。为此,阿里云推出ACK One注册集群架构,通过云上节点池(CPU/GPU)自动弹性伸缩等特性,为企业带来全新突破。
|
18天前
|
Kubernetes 网络协议 Nacos
OpenAI 宕机思考丨Kubernetes 复杂度带来的服务发现系统的风险和应对措施
Kubernetes 体系基于 DNS 的服务发现为开发者提供了很大的便利,但其高度复杂的架构往往带来更高的稳定性风险。以 Nacos 为代表的独立服务发现系统架构简单,在 Kubernetes 中选择独立服务发现系统可以帮助增强业务可靠性、可伸缩性、性能及可维护性,对于规模大、增长快、稳定性要求高的业务来说是一个较理想的服务发现方案。希望大家都能找到适合自己业务的服务发现系统。
|
1月前
|
弹性计算 调度 数据中心
阿里云 ACK One 注册集群云上弹性:扩展业务新利器
随着企业数字化转型深入,传统IDC数据中心因物理容量限制,难以实现动态扩容,缺乏弹性能力。阿里云ACK One注册集群凭借其高度灵活性和丰富资源选择,成为解决此问题的最佳方案。通过与阿里云资源的整合,ACK One不仅实现了计算资源的按需扩展,提高了资源利用率,还通过按需付费模式降低了成本,使企业能够更高效地应对业务增长和高峰需求。
|
2月前
|
Prometheus Kubernetes 监控
深入探索Kubernetes中的Pod自动扩展(Horizontal Pod Autoscaler, HPA)
深入探索Kubernetes中的Pod自动扩展(Horizontal Pod Autoscaler, HPA)
|
4月前
|
Kubernetes Cloud Native Java
探索未来编程新纪元:Quarkus带你秒建高性能Kubernetes原生Java应用,云原生时代的技术狂欢!
Quarkus 是专为 Kubernetes 设计的全栈云原生 Java 框架,凭借其轻量级、快速启动及高效执行特性,在 Java 社区脱颖而出。通过编译时优化与原生镜像支持,Quarkus 提升了应用性能,同时保持了 Java 的熟悉度与灵活性。本文将指导你从创建项目、编写 REST 控制器到构建与部署 Kubernetes 原生镜像的全过程,让你快速上手 Quarkus,体验高效开发与部署的乐趣。
105 0
|
5月前
|
Kubernetes 负载均衡 算法
如何在kubernetes中实现分布式可扩展的WebSocket服务架构
如何在kubernetes中实现分布式可扩展的WebSocket服务架构
127 1
|
6月前
|
负载均衡 Kubernetes 算法
K8s服务发现与负载均衡的技术探索
【7月更文挑战第15天】K8s通过Service资源对象和kube-proxy组件实现了高效、灵活的服务发现和负载均衡机制。通过合理选择Service类型、优化kube-proxy配置以及使用Ingress进行高级路由,可以确保应用在K8s集群中高效、可靠地运行。随着云原生技术的不断发展,K8s的服务发现和负载均衡机制也将不断完善和优化,为更多场景提供强大的支持。
|
6月前
|
Kubernetes 持续交付 Python
Kubernetes(通常简称为K8s)是一个开源的容器编排系统,用于自动化部署、扩展和管理容器化应用程序。
Kubernetes(通常简称为K8s)是一个开源的容器编排系统,用于自动化部署、扩展和管理容器化应用程序。
|
7月前
|
Kubernetes Cloud Native Java
Java一分钟之-Quarkus:Kubernetes原生的Java框架
【6月更文挑战第12天】Quarkus是面向Kubernetes的Java框架,以其超快启动速度和低内存占用著称。核心特性包括AOT编译实现毫秒级启动、优化的运行时模型、与Kubernetes的无缝集成及丰富的扩展库。常见问题涉及Maven依赖管理、热重载机制理解和配置文件的忽视。解决这些问题的关键在于深入学习官方文档、使用Dev UI调试和参与社区交流。通过代码示例展示了如何快速创建REST服务。掌握Quarkus能提升开发效率,适应微服务架构。
103 0
|
8月前
|
Kubernetes 监控 Docker

热门文章

最新文章