前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >基于 Stork 和 Quarkus 扩展 Kubernetes 服务发现

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

作者头像
Luga Lee
发布2022-04-20 08:27:39
2.1K0
发布2022-04-20 08:27:39
举报
文章被收录于专栏:架构驿站架构驿站

作者 | Daniel Oh 译者 | Luga Lee 策划 | Luga Lee

代码语言:javascript
复制
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 应用程序:

代码语言:javascript
复制
[leonli@192 ~] % quarkus create app quarkus-stork-example -x rest-client-reactive,resteasy-reactive

结果如下所示:

代码语言:javascript
复制
...
[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。 如下所示:

代码语言:javascript
复制
...
<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 服务器:

代码语言:javascript
复制
@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() 方法中设置不同的名称、端口和返回消息,如下所示:

代码语言:javascript
复制
@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() 方法,具体如下所示:

代码语言:javascript
复制
@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 文件。然后添加以下代码:

代码语言:javascript
复制
@RegisterRestClient(baseUri = "stork://my-rest-service")
public interface MyRestClient {

    @GET
    @Produces(MediaType.TEXT_PLAIN)
    String get();
}

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

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

代码语言:javascript
复制
@Path("/api")
public class MyRestClientResource {
   
    @RestClient MyRestClient myRestClient;

    @GET
    @Produces(MediaType.TEXT_PLAIN)
    public String invoke() {
        return myRestClient.get();
    }

}

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

代码语言:javascript
复制
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 服务,对于此示例,使用容器运行。这种方法可能比安装或引用外部服务更为简单。

代码语言:javascript
复制
[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 应用程序:

代码语言:javascript
复制
[leonli@192 ~] % cd quarkus-stork-example
[leonli@192 ~] % quarkus dev

运行结果如下所示:

代码语言:javascript
复制
...
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
代码语言:javascript
复制
Super Villain!
Super Hero!
Super Villain!
Super Hero!
Super Villain!
...

总结:

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

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

- EOF -

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2022-04-18,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 架构驿站 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
负载均衡
负载均衡(Cloud Load Balancer,CLB)提供安全快捷的流量分发服务,访问流量经由 CLB 可以自动分配到云中的多台后端服务器上,扩展系统的服务能力并消除单点故障。负载均衡支持亿级连接和千万级并发,可轻松应对大流量访问,满足业务需求。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档