关于云计算:使用-Quarkus-和-MicroProfile-实现微服务特性

48次阅读

共计 15904 个字符,预计需要花费 40 分钟才能阅读完成。

Quarkus 的文章之前写过三篇了,讲过了 Quarkus 的小而快。

  • Hello, Quarkus
  • 应 ” 云 ” 而生的 Java 框架 Quarkus:构建本机可执行文件
  • 谁说 Java 不能用来跑 Serverless?

始终在酝酿写一篇 Quarkus 生态相干的,因为最近始终在忙 Meetup 的事件而搁浅。正好看到了这篇文章,就拿来翻译一下,补全云原生中的“微服务”这一块。

本文译自《Implementing Microservicilities with Quarkus and MicroProfile》。


为什么要应用微服务个性?

在微服务架构中,一个应用程序是由几个相互连接的服务组成的,这些服务一起工作来实现所需的业务性能。

因而,典型的企业微服务架构如下所示:

刚开始,应用微服务架构实现应用程序看起来很容易。

然而,因为有了单体架构没有一些新的挑战,因而做起来并不容器

举几个例子,比方容错、服务发现、扩展性、日志记录和跟踪。

为了解决这些挑战,每个微服务都应实现咱们在 Red Hat 所说的“微服务个性”。

  • [] 该术语是指除业务逻辑以外,服务还必须实现来解决的跨畛域关注点清单,如下图所示:

能够用任何语言(Java、Go、JavaScript)或任何框架(Spring Boot、Quarkus)实现业务逻辑,然而围绕业务逻辑,应实现以下关注点:

API:可通过一组定义的 API 操作来拜访该服务。例如,对于 RESTful Web API,HTTP 用作协定。此外,能够应用诸如 Swagger 之类的工具来记录 API。
服务发现(Discovery):服务须要发现其余服务。

调用服务(Invocation):发现服务后,须要应用一组参数对其进行调用,并选择性地返回响应。

弹性(Elasticity):微服务架构的重要特色之一是每个服务都是弹性的,这意味着能够依据零碎的要害水平或以后的工作量等参数独立地进行缩放。(译者注:这里的弹性只是资源的弹性)

弹性(Resiliency):在微服务架构中,咱们在开发时应牢记失败,尤其是在与其余服务进行通信时。在单体利用中,整个应用程序处于启动或敞开状态。然而,当此应用程序合成为微服务体系结构时,该应用程序由多个服务组成,并且所有这些服务都通过网络互连,这意味着该应用程序的某些局部可能正在运行,而其余局部可能会失败。遏制故障对防止通过其余服务流传谬误很重要。弹性(或应用程序弹性)是应用程序 / 服务对问题做出反馈并依然提供最佳后果的能力。(译者注:这里的弹性与容错相干,对失败解决的弹性)

管道(Pipeline):服务应独立部署,而无需进行任何模式的编排。因而,每个服务应具备本人的部署管道。

身份验证(Authentication):对于微服务体系结构中的安全性的要害方面之一是如何对外部服务之间的调用进行身份验证 / 受权。Web 令牌(通常是令牌)是在外部服务中平安地示意申明的首选形式。

日志记录(Logging):在单体应用程序中,日志记录很简略,因为该应用程序的所有组件都在同一节点上运行。而后当初组件以服务的模式散布在多个节点上,因而,要领有残缺的日志记录视图,须要一个对立的日志记录零碎 / 数据收集器。

监控(Monitoring):掂量零碎的性能、理解应用程序的整体运行状况,以及在呈现问题时收回警报是放弃基于微服务的应用程序正确运行的要害方面。监控是控制应用程序的要害方面。

跟踪(Tracing):跟踪用于可视化程序的流程和数据进度。作为开发人员 / 运维人员,当咱们须要检查用户在整个应用程序中的行程时,这特地有用。

Kubernetes 正在成为部署微服务的理论工具。这是一个用于自动化、编排、扩大和治理容器的开源零碎。

应用 Kubernetes 时,十个微服务个性中只有三个被涵盖。

服务发现 是通过 Kubernetes 服务 的概念实现的。它提供了一种应用稳固的虚构 IP 和 DNS 名称将 Kubernetes Pod 分组(作为一个整体)的办法。发现服务只是应用 Kubernetes 的服务名作为 hostname 进行申请。

应用 Kubernetes 能够很容易地 调用服务,因为平台自身提供了调用任何服务所需的网络。

从一开始,Kubernetes 就始终在思考 弹性(或可伸缩性),例如运行时kubectl scale deployment myservice --replicas=5 command,myservice deployment 可伸缩至五个正本或实例。Kubernetes 平台负责寻找适合的节点,部署服务并始终保持所需数量的正本并失常运行。

然而其余的微服务个性又如何呢?Kubernetes 仅涵盖其中的三个,那么咱们如何实现剩下的呢?

依据所应用的语言或框架,能够遵循的策略很多。然而在本文中,咱们将理解如何应用 Quarkus 实现其中的一些策略。

什么是 Quarkus?

Quarkus 是针对 Java 虚拟机(JVM)和本机编译的全栈 Kubernetes 本地 Java 框架,专门针对容器优化 Java,使其成为无服务器(Serverless)、云和 Kubernetes 环境的高效平台。

Instead of reinventing the wheel, Quarkus uses well-known enterprise-grade frameworks backed by standards/specifications and makes them compilable to a binary using GraalVM.
Quarkus 不必从新创造轮子,而是应用以规范 / 标准为后盾的出名企业级框架,并应用 GraalVM 将其编译为二进制文件。

什么是 MicroProfile?

Quarkus 与 MicroProfile 标准集成,从而将企业 Java 生态系统迁徙到微服务体系结构中。

在下图中,咱们看到了形成 MicroProfile 标准的所有 API。某些 API(例如 CDI、JSON-P 和 JAX-RS)基于 Jakarta EE(以前的 Java EE)标准。其余的由 Java 社区开发。

Let’s implement API, invocation, resilience, authentication, logging, monitoring, and tracing microservicilities using Quarkus.
让咱们应用 Quarkus 实现 API、调用、弹性、身份验证、日志记录、监督和跟踪微服务个性。

如何应用 Quarkus 实现微服务个性

入门

开始应用 Quarkus 的最快办法是通过在开始页面中抉择所需的依赖。对于以后示例,抉择如下依赖关系以满足微服务需要:

API:RESTEasy JAX-RS、RESTEasy JSON-B、OpenAPI
调用:REST Client JSON-B
弹性:Fault Tolerance
认证:JWT
记录:GELF
监控:Micrometer metrics
跟踪:OpenTracing

咱们能够手动抉择各自的依赖关系,或浏览以下链接 Quarkus 微服务个性生成器,所有这些都会被选中。而后按“生成应用程序”按钮以下载蕴含支架应用程序的 zip 文件。

服务

对于以后示例,仅应用两个服务生成了一个非常简单的应用程序。一个名为“评级服务 rating service”的服务返回给定书籍的评级,而另一个名为“书籍服务 book service”的服务则返回一本书的信息及其评级。服务之间的所有调用都必须通过身份验证。

在下图中,咱们看到了整个零碎的概述:

评级服务 曾经开发并作为 Linux 容器提供。通过运行以下命令,在端口 9090 上启动服务:

docker run --rm -ti -p 9090:8080 
quay.io/lordofthejars/rating-service:1.0.0

要验证服务,请向 http://localhost:9090/rate/1 发出请求

curl localhost:8080/rate/1 -vv

> GET /rate/1 HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.64.1
> Accept: */*
>
< HTTP/1.1 401 Unauthorized
< www-authenticate: Bearer {token}
< Content-Length: 0

返回的状态码是 401 Unauthorized 因为没有在申请中携带令牌(JWT)提供受权信息。只有带有 group Echoer 无效令牌能力拜访评级服务。

API

Quarkus 应用家喻户晓的 JAX-RS 标准来定义 RESTful Web API。在幕后,Quarkus 应用 RESTEasy 实现间接与 Vert.X 框架一起应用,而无需应用 Servlet 技术。

让咱们为实现最常见操作的图书服务定义一个 API:

import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriBuilder;

@Path("/book")
public class BookResource {

   @GET
   @Path("/{bookId}")
   @Produces(MediaType.APPLICATION_JSON)
   public Book book(@PathParam("bookId") Long bookId) {// logic}

   @POST
   @Consumes(MediaType.APPLICATION_JSON)
   public Response getBook(Book book) {
       // logic

       return Response.created(UriBuilder.fromResource(BookResource.class)
                     .path(Long.toString(book.bookId))
                     .build())
               .build();}

   @DELETE
   @Path("/{bookId}")
   public Response delete(@PathParam("bookId") Long bookId) {
       // logic

       return Response.noContent().build();
   }

   @GET
   @Produces(MediaType.APPLICATION_JSON)
   @Path("search")
   public Response searchBook(@QueryParam("description") String description) {       
       // logic

       return Response.ok(books).build();}
}

首先要留神的是,定义了四个不同的端点:

  • GET /book/{bookId} 应用 GET HTTP 办法返回带有其评级的图书信息。return 元素会主动解编为 JSON。
  • POST /book 应用 POST HTTP 办法插入一本书作为注释内容。注释内容会主动从 JSON 编组到 Java 对象。
  • DELETE /book/{bookId} 应用 DELETE HTTP 办法通过书的 ID 删除书。
  • GET /book/search?description={description} 按书名搜寻书籍。

留神的第二件事是返回类型,有时是 Java 对象,有时是 Java 实例 javax.ws.rs.core.Response。应用 Java 对象时,会将其从 Java 对象序列化为 @Produces 注解中设置的媒体类型。在此特定服务中,输入为 JSON 文档。通过该 Response 对象,咱们能够对返回给调用方的内容进行细粒度的管制。能够设置 HTTP 状态代码、标头或返回给调用方的内容。取决于应用场景,是偏爱一种办法而不是另一种办法。

调用

在定义了用于拜访 图书服务 的 API 之后,是时候开发一段代码来调用 评级服务 以检索图书的评级了。

Quarkus 应用 MicroProfile Rest Client 标准来拜访内部(HTTP)服务。它提供了一种类型平安的办法,以通过某些 JAX-RS 2.0 API 通过 HTTP 调用 RESTful 服务,以实现一致性和更易于重用。

要创立的第一个元素是一个应用 JAX-RS 批注示意近程服务的接口。

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

import org.eclipse.microprofile.rest.client.inject.RegisterRestClient;

@Path("/rate")
@RegisterRestClient
public interface RatingService {
 
   @GET
   @Path("/{bookId}")
   @Produces(MediaType.APPLICATION_JSON)
   Rate getRate(@PathParam("bookId") Long bookId);

}

When the getRate() method is called, a remote HTTP call is invoked at /rate/{bookId} replacing the bookId with the value set in the method parameter. It is important to annotate the interface with the @RegisterRestClient annotation.
Then the RatingService interface needs to be injected into BookResource to execute the remote calls.
getRate() 办法被调用时,近程 HTTP 申请在调用 /rate/{bookId} 替换 bookId 用在该办法中的参数值汇合。用 @RegisterRestClient 注解对接口进行注解很重要。

而后 RatingService 须要将接口注入 BookResource 以执行近程调用。

import org.eclipse.microprofile.rest.client.inject.RestClient;

@RestClient
RatingService ratingService;

@GET
@Path("/{bookId}")
@Produces(MediaType.APPLICATION_JSON)
public Book book(@PathParam("bookId") Long bookId) {final Rate rate = ratingService.getRate(bookId);

    Book book = findBook(bookId);
    return book;
}

The @RestClient annotation injects a proxied instance of the interface, providing the implementation of the client.
The last thing is to configure the service location (the hostname part). In Quarkus, the configuration properties are set in src/main/resources/application.properties file. To configure the location of the service, we need to use the fully qualified name of the Rest Client interface with URL as key, and the location as a value:
@RestClient 注解注入界面的代理实例,提供客户端的实现。

最初一件事是配置服务地位(hostname 局部)。在 Quarkus 中,配置属性在 src/main/resources/application.properties 文件中设置。要配置服务的地位,咱们须要应用 Rest Client 接口的规范名称,其中 URL 作为键,而 location 作为值:

org.acme.RatingService/mp-rest/url=http://localhost:9090

在正确拜访 评估服务 而没有 401 Unauthorized 问题之前,必须解决互相认证问题。

身份验证

基于令牌的身份验证机制容许零碎基于平安令牌对身份进行身份验证、受权和验证。Quarkus 与 MicroProfile JWT RBAC 平安标准集成在一起,以应用 JWT 令牌爱护服务。

要应用 MicroProfile JWT RBAC 安全性爱护端点,咱们只须要应用批注对办法进行 @RolesAllowed 注解。

@GET
@Path("/{bookId}")
@RolesAllowed("Echoer")
@Produces(MediaType.APPLICATION_JSON)
public Book book(@PathParam("bookId") Long bookId)

而后,咱们配置令牌的发行方和公钥的地位,以验证令牌在 application.properties 文件中的签名:

mp.jwt.verify.publickey.location=https://raw.githubusercontent.com/redhat-developer-demos/quarkus-tutorial/master/jwt-token/quarkus.jwt.pub
mp.jwt.verify.issuer=https://quarkus.io/using-jwt-rbac

此扩展名主动验证:令牌无效;发行方是正确的;令牌尚未批改;签名无效;没有过期。

这两种 图书服务 评级服务 当初是由同一 JWT 发行方和密钥爱护,因而服务之间的通信要求验证提供在令牌的无效承载用户 Authentication 头部。

评级服务 启动和运行,让咱们开始用上面的命令 图书服务

./mvnw compile quarkus:dev

Finally, we can make a request to get book information providing a valid JSON Web Token as a bearer token.
The generation of the token is out of the scope of this article, and a token has been already generated:
最初,咱们能够申请获取提供无效 JSON Web 令牌作为承载令牌的图书信息。

令牌的生成不在本文的探讨范畴之内,并且曾经生成了令牌:

curl -H "Authorization: Bearer eyJraWQiOiJcL3ByaXZhdGVLZXkucGVtIiwidHlwIjoiSldUIiwiYWxnIjoiUlMyNTYifQ.eyJzdWIiOiJqZG9lLXVzaW5nLWp3dC1yYmFjIiwiYXVkIjoidXNpbmctand0LXJiYWMiLCJ1cG4iOiJqZG9lQHF1YXJrdXMuaW8iLCJiaXJ0aGRhdGUiOiIyMDAxLTA3LTEzIiwiYXV0aF90aW1lIjoxNTcwMDk0MTcxLCJpc3MiOiJodHRwczpcL1wvcXVhcmt1cy5pb1wvdXNpbmctand0LXJiYWMiLCJyb2xlTWFwcGluZ3MiOnsiZ3JvdXAyIjoiR3JvdXAyTWFwcGVkUm9sZSIsImdyb3VwMSI6Ikdyb3VwMU1hcHBlZFJvbGUifSwiZ3JvdXBzIjpbIkVjaG9lciIsIlRlc3RlciIsIlN1YnNjcmliZXIiLCJncm91cDIiXSwicHJlZmVycmVkX3VzZXJuYW1lIjoiamRvZSIsImV4cCI6MjIwMDgxNDE3MSwiaWF0IjoxNTcwMDk0MTcxLCJqdGkiOiJhLTEyMyJ9.Hzr41h3_uewy-g2B-sonOiBObtcpkgzqmF4bT3cO58v45AIOiegl7HIx7QgEZHRO4PdUtR34x9W23VJY7NJ545ucpCuKnEV1uRlspJyQevfI-mSRg1bHlMmdDt661-V3KmQES8WX2B2uqirykO5fCeCp3womboilzCq4VtxbmM2qgf6ag8rUNnTCLuCgEoulGwTn0F5lCrom-7dJOTryW1KI0qUWHMMwl4TX5cLmqJLgBzJapzc5_yEfgQZ9qXzvsT8zeOWSKKPLm7LFVt2YihkXa80lWcjewwt61rfQkpmqSzAHL0QIs7CsM9GfnoYc0j9po83-P3GJiBMMFmn-vg" localhost:8080/book/1 -v

响应又是 forbidden 谬误:

< HTTP/1.1 401 Unauthorized
< Content-Length: 0

你可能想晓得为什么在提供无效令牌后依然呈现此谬误。如果咱们查看图书服务的控制台,就会发现抛出了以下异样:

org.jboss.resteasy.client.exception.ResteasyWebApplicationException: Unknown error, status code 401
    at org.jboss.resteasy.client.exception.WebApplicationExceptionWrapper.wrap(WebApplicationExceptionWrapper.java:107)
    at org.jboss.resteasy.microprofile.client.DefaultResponseExceptionMapper.toThrowable(DefaultResponseExceptionMapper.java:21)

产生此异样的起因是,咱们已取得身份验证并有权拜访 图书服务 ,但承载令牌尚未流传到 评级服务

为了主动将 Authorization 标头从传入申请流传到其余客户端申请,须要进行两次批改。

第一个批改是批改 Rest Client 界面,并应用对其进行注解 org.eclipse.microprofile.rest.client.inject.RegisterClientHeaders

@Path("/rate")
@RegisterRestClient
@RegisterClientHeaders
public interface RatingService {}

第二个批改是配置在申请之间流传哪些标头。这是在 application.properties 文件中设置的:

    org.eclipse.microprofile.rest.client.propagateHeaders=Authorization

执行与之前雷同的 curl 命令,咱们将取得正确的输入:

< HTTP/1.1 200 OK
< Content-Length: 39
< Content-Type: application/json
<
* Connection #0 to host localhost left intact
{"bookId":2,"name":"Book 2","rating":1}* Closing connection 0

弹性

在微服务架构中,具备容错能力很重要,这样能够防止故障从一个服务流传到该服务的所有间接和间接调用方。Quarkus 将 MicroProfile Fault Tolerance 标准与以下用于解决故障的正文集成在一起:

●    @Timeout:定义抛出异样之前执行的最长工夫。
●    @Retry:如果调用失败,请再次重试执行。
●    @Bulkhead:限度并发执行,以使该区域中的故障不会使整个零碎过载。
●    @CircuitBreaker:执行重复失败时,将主动进行疾速故障切换。
●    @Fallback:执行失败时,提供备用解决方案 / 默认值。

让咱们增加三次重试,其中重试之间的提早计时器为一秒,以防拜访 评级服务 时产生谬误。

@Retry(maxRetries = 3, delay = 1000)
Rate getRate(@PathParam("bookId") Long bookId);

当初,进行 评级服务 并执行申请。引发以下异样:

org.jboss.resteasy.spi.UnhandledException: javax.ws.rs.ProcessingException: RESTEASY004655: Unable to invoke request: 
org.apache.http.conn.HttpHostConnectException: Connect to localhost:9090 [localhost/127.0.0.1, localhost/0:0:0:0:0:0:0:1] failed: Connection refused

显然,这里存在谬误,然而请留神,因为执行了三次重试(提早一秒),因而引发异样之前,通过了三秒钟。

在这种状况下,评级服务 已敞开,因而无奈进行复原,然而在一个理论示例中,评级服务 可能仅在短时间内就复原了,或者部署了该服务的多个正本,因而能够简略地重试操作可能足以复原并提供无效的响应。

然而,当引发异样时重试次数不够时,咱们能够将谬误流传给调用方,也能够为调用提供代替值。这种抉择能够是对另一个零碎的调用(即分布式缓存)或动态值。

对于此用例,当与评级服务的连贯失败时,将返回评级值 0。

要实现回退逻辑,首先要做的是实现将 org.eclipse.microprofile.faulttolerance.FallbackHandler 返回类型设置为与回退策略办法提供的代替类型雷同的接口。对于这种状况,将 Rate 返回默认对象。

import org.eclipse.microprofile.faulttolerance.ExecutionContext;
import org.eclipse.microprofile.faulttolerance.FallbackHandler;

public class RatingServiceFallback implements FallbackHandler<Rate> {

   @Override
   public Rate handle(ExecutionContext context) {Rate rate = new Rate();
       rate.rate = 0;
       return rate;
   }
 
}

最初要做的是用注解对 getRating() 办法进行 @org.eclipse.microprofile.faulttolerance.Fallback 注解,以配置无奈复原时要执行的回退类。

@Retry(maxRetries = 3, delay = 1000)
@Fallback(RatingServiceFallback.class)
Rate getRate(@PathParam("bookId") Long bookId);

如果反复与以前雷同的申请,则不会引发任何异样,然而有效值的输入将 rating 字段设置为 0。

* Connection #0 to host localhost left intact
{"bookId":2,"name":"Book 2","rating":0}* Closing connection 0

标准提供的任何其余策略都能够应用雷同的办法。例如,对于断路器模式:

@CircuitBreaker(requestVolumeThreshold = 4,
               failureRatio=0.75,
               delay = 1000)

如果在四个间断调用的滚动窗口中产生了三个(4 x 0.75)故障,则电路将断开 1000 ms,而后复原到半断开状态。如果在半开时调用胜利,则将其再次敞开。否则,它将放弃关上状态

日志记录

在微服务架构中,倡议将所有服务的日志收集在一个对立的日志中,以更无效地应用和了解。

一种解决方案是应用 Fluentd,它是 Kubernetes 中用于对立日志记录层的开源数据收集器。Quarkus 应用 Graylog 扩大日志格局(GELF)与 Fluentd 集成。

集成真的很简略。首先,与其余任何 Quarkus 应用程序一样应用日志逻辑:

import org.jboss.logging.Logger;

private static final Logger LOG = Logger.getLogger(BookResource.class);

@GET
@Path("/{bookId}")
@RolesAllowed("Echoer")
@Produces(MediaType.APPLICATION_JSON)
public Book book(@PathParam("bookId") Long bookId) {LOG.info("Get Book");

接下来,启用 GELF 格局并设置 Fluentd 服务器地位:

quarkus.log.handler.gelf.enabled=true
quarkus.log.handler.gelf.host=localhost
quarkus.log.handler.gelf.port=12201

最初,咱们能够向记录的端点发出请求:

curl -H "Authorization: Bearer ..." localhost:8080/book/1

{"bookId":1,"name":"Book 1","rating":3}

输入方面没有任何变动,然而日志行已传输到 Fluentd。如果应用 Kibana 可视化数据,咱们将看到存储的日志行:

监控

Monitoring is another “microservicilitie” that needs to be implemented in our microservice architecture. Quarkus integrates with Micrometer for application monitoring. Micrometer provides a single entry point to the most popular monitoring systems, allowing you to instrument your JVM-based application code without vendor lock-in.

For this example, Prometheus format is used as monitoring output but Micrometer (and Quarkus) also supports other formats like Azure Monitor, Stackdriver, SignalFx, StatsD, and DataDog.

You can register the following Maven dependency to provide Prometheus output:
监控是另一个须要在咱们的微服务架构中实现的“微服务个性”。Quarkus 与 Micrometer 集成在一起以进行应用程序监控。Micrometer 提供了最风行的监控零碎的单个入口点,使你无需供应商锁定即可检测基于 JVM 的利用程序代码。

对于此示例,监控输入采纳 Prometheus 格局,但 Micrometer(和 Quarkus)还反对其余格局,例如 Azure Monitor、Stackdriver、SignalFx、StatsD 和 DataDog。

你能够注册以下 Maven 依赖项以提供 Prometheus 输入:

<dependency>
  <groupId>io.quarkus</groupId>
  <artifactId>quarkus-micrometer-registry-prometheus</artifactId>
</dependency>

默认状况下,Micrometer 扩大注册了一些与零碎,JVM 或 HTTP 相干的度量。收集的指标的一个子集在 /q/metrics 端点处可用,如下所示:

curl localhost:8080/q/metrics

jvm_threads_states_threads{state="runnable",} 22.0
jvm_threads_states_threads{state="blocked",} 0.0
jvm_threads_states_threads{state="waiting",} 10.0
http_server_bytes_read_count 1.0
http_server_bytes_read_sum 0.0

然而,也能够应用 Micrometer API 来实现特定于应用程序的指标。
让咱们实现一个自定义指标,该指标用于掂量评估最高的图书。

应用 io.micrometer.core.instrument.MeterRegistry 该类能够实现指标(在这种状况下为量规)的注册。

private final MeterRegistry registry;
private final LongAccumulator highestRating = new LongAccumulator(Long::max, 0);
 
public BookResource(MeterRegistry registry) {
    this.registry = registry;
    registry.gauge("book.rating.max", this,
               BookResource::highestRatingBook);
}

申请一下,并验证量规是否正确更新。

curl -H "Authorization: Bearer ..." localhost:8080/book/1

{"bookId":1,"name":"Book 1","rating":3}

curl localhost:8080/q/metrics

# HELP book_rating_max
# TYPE book_rating_max gauge
book_rating_max 3.0

咱们还能够设置一个计时器来记录从 评级服务 获取评级信息所破费的工夫。

Supplier<Rate> rateSupplier = () -> {return ratingService.getRate(bookId);
};
      
final Rate rate = registry.timer("book.rating.test").wrap(rateSupplier).get();

申请一下,并验证收集评估​​所破费的工夫。

# HELP book_rating_test_seconds
# TYPE book_rating_test_seconds summary
book_rating_test_seconds_count 4.0
book_rating_test_seconds_sum 1.05489108
# HELP book_rating_test_seconds_max
# TYPE book_rating_test_seconds_max gauge
book_rating_test_seconds_max 1.018622001

Micrometer 应用 MeterFilter 实例来自定义 MeterRegistry 实例收回的度量。Micrometer 扩大将检测 MeterFilter CDI bean,并在初始化 MeterRegistry 实例时应用它们。

例如,咱们能够定义一个通用标签来设置运行应用程序的环境(产品、测试、预公布等)。

@Singleton
public class MicrometerCustomConfiguration {
 
   @Produces
   @Singleton
   public MeterFilter configureAllRegistries() {
       return MeterFilter.commonTags(Arrays.asList(Tag.of("env", "prod")));
   }

}

发送新申请并验证指标是否已标记。

http_client_requests_seconds_max{clientName="localhost",env="prod",method="GET",outcome="SUCCESS",status="200",uri="/rate/2",} 0.0

请留神 env 蕴含值为 prod 的标签。

跟踪

Quarkus 应用程序利用 OpenTracing 标准为交互式 Web 应用程序提供分布式跟踪。

让咱们配置 OpenTracing 以连贯到 Jaeger 服务器,将 book-service 设置为服务名称以标识跟踪:

quarkus.jaeger.enabled=true
quarkus.jaeger.endpoint=http://localhost:14268/api/traces
quarkus.jaeger.service-name=book-service
quarkus.jaeger.sampler-type=const
quarkus.jaeger.sampler-param=1

当初发一个申请:

curl -H "Authorization: Bearer ..." localhost:8080/book/1 {"bookId":1,"name":"Book 1","rating":3}

拜访 Jaeger UI 以验证是否跟踪了该调用:

总结

与开发整体应用程序相比,开发和实现微服务体系结构更具挑战性。咱们认为,微服务能够驱动你依据应用程序根底构造正确地开发服务。

此处介绍的大多数微服务(API 和管道除外)是新的,或者在整体利用中实现形式有所不同。起因是当初应用程序被分解成几局部,所有局部都在网络中互连。

如果你 May 26, 2021 打算开发微服务并将其部署到 Kubernetes,那么 Quarkus 是一个很好的解决方案,因为它能够与 Kubernetes 顺利集成。施行大多数微服务很简略,只须要几行代码。

本文演示的源代码能够在 github 上找到。

对于作者

Alex Soto 是 Red Hat 开发人员教训总监。他对 Java 世界,软件自动化充满热情,并且他置信开源软件模型。Soto 是 Manning 的合著者 | 测试 Java 微服务和 O’Reilly Quarkus Cookbook 和几个开源我的项目的贡献者。自 2017 年以来始终是 Java 冠军,他还是 Salle URL University 的国内演讲者和老师。你能够在 Twitter(Alex Soto)上关注他,以随时理解 Kubernetes 和 Java 世界中正在产生的事件。

文章对立公布在公众号 云原生指北

正文完
 0