领先一步
VMware 提供培训和认证,以加速您的进步。
了解更多嗨,Spring 粉丝!欢迎来到 Spring 提示的另一期!在本期中,我们将从优秀的 Tanzu Wavefront 可观测性 平台的角度重新讨论我们在之前两个视频中讨论过的两个主题(分布式追踪和指标收集)。
如上所述,这两个视频中的第一个视频可以追溯到 2017 年初,它探讨了使用 Spring Cloud Sleuth 和 OpenZipkin 进行分布式追踪。Spring Cloud Sleuth 是一个用于捕获消息从一个节点流向另一个节点的抽象。它有助于了解消息在系统中的移动方式。Spring Cloud Sleuth 集成了 Spring Boot 应用程序中所有常用的入口和出口点。使用 RestTemplate
或响应式 WebClient
或 Spring Cloud Feign 发出 HTTP 请求?它可以工作。接收使用 Spring 构建的传统(基于 Servlet)或响应式 HTTP 端点的 HTTP 请求?它可以工作。使用 Spring Cloud Stream 或 Spring Integration 发送或接收消息?是的。你猜对了。它就是可以工作。你什么都不需要做。
只需将 Spring Cloud Sleuth 启动器添加到类路径中,Spring Cloud Sleuth 就会完成剩下的工作。它可以依次将捕获的信息转发到带外跟踪服务器,例如 OpenZipkin。有些甚至提供与 Zipkin 兼容的代理,例如 Google Cloud Stackdriver 跟踪。我喜欢最后一点,因为它几乎感觉我们已经走了一个完整的循环。请记住,Zipkin 的灵感来源于 Google 的 Dapper 白皮书等。很高兴我们能够依次使用 Zipkin 与 Google Cloud 的跟踪基础设施进行通信。当您想要深入了解单个请求进入或离开系统的详细信息时,分布式跟踪非常理想。
第二个视频来自 2018 年初,它探讨了使用 Micrometer 收集指标。
Micrometer 是一个用于捕获指标(统计数据)的抽象,这些指标关于您的应用程序,然后可以从 Spring Boot Actuator 的 /actuator/metrics
端点获取或转发到时间序列数据库(如 Wavefront)。Micrometer 还可以与其他时间序列数据库进行通信,例如 AppOptics、Azure Monitor、Netflix Atlas、CloudWatch、Datadog、Dynatrace、Elastic、Ganglia、Graphite、Humio、Influx/Telegraf、JMX、KairosDB、New Relic、Prometheus、SignalFx、Google Stackdriver、StatsD。当您想要捕获统计数据(关于给定 HTTP 端点被击中的频率、HTTP 端点返回特定状态代码或响应特定 HTTP 动词的聚合数字)时,指标非常有用。
这是一个快速的回顾。要更深入地了解这两者,我建议您参考这两个提到的 Spring 提示视频。这就是它们存在的意义!Wavefront 的优点在于,在本期中您无需与这些项目的 API 交互,因为正如我们即将看到的,Wavefront Spring Boot 集成可以正常工作。这绝非偶然:Spring Boot 团队努力使 Wavefront 集成无缝运行。Wavefront 还为大量不同的平台、运行时和项目提供了其他集成。
注意:我已经将其他支持的集成列表粘贴到一个巨大的屏幕截图中,您可以在此博客的底部找到它。这将是一张长度是博客本身十倍的图片。
让我们使用 Spring Initializr 构建一个新项目。您必须使用大于 Spring Boot 2.3.M4 的 Spring Boot 版本。选择 R2DBC
、PostgreSQL
、Reactive Web
、Spring Cloud Sleuth
和 Lombok
。单击 生成
,解压缩生成的文件。当我编写本文时,使用 Spring Cloud Hoxton SR3 运行良好。无需快照。此外,我们需要添加 Wavefront 启动器本身。将以下依赖项添加到 pom.xml
中。
<dependency>
<groupId>com.wavefront</groupId>
<artifactId>wavefront-spring-boot-starter</artifactId>
<version>2.0.0-SNAPSHOT</version>
</dependency>
Wavefront Spring Boot 启动器是一个 SNAPSHOT
依赖项——如果我们不冒险尝试一下,那它就不算 Spring 提示视频!在撰写本文时,该依赖项位于 Sonatype 快照存储库中。我需要在我的构建中包含以下 Spring 和 Sonatype 存储库。不过,谁知道呢?也许在您阅读本文时,一切都会变成 GA 版本。在这些美好的部分,事情变化很快!
<repositories>
<repository>
<id>sonatype-snapshots</id>
<name>Sonatype Snapshots</name>
<url>https://oss.sonatype.org/content/repositories/snapshots/</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
</repository>
<repository>
<id>spring-snapshots</id>
<name>Spring Snapshots</name>
<url>https://repo.spring.io/snapshot</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
</pluginRepository>
<pluginRepository>
<id>spring-snapshots</id>
<name>Spring Snapshots</name>
<url>https://repo.spring.io/snapshot</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
</pluginRepository>
</pluginRepositories>
全部完成之后,在您喜欢的 IDE 中导入项目。
该应用程序是一个典型的响应式 Spring Boot 应用程序,在观看如此多的其他 Spring 提示部分后,您无疑已经熟悉了它,例如关于功能性响应式 HTTP 端点、Spring Data R2DBC、测试响应式服务等等。以下是代码。
package com.example.wavefront;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.boot.ApplicationRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.data.annotation.Id;
import org.springframework.data.repository.reactive.ReactiveCrudRepository;
import org.springframework.web.reactive.function.server.RouterFunction;
import org.springframework.web.reactive.function.server.ServerResponse;
import reactor.core.publisher.Flux;
import static org.springframework.web.reactive.function.server.RouterFunctions.route;
import static org.springframework.web.reactive.function.server.ServerResponse.ok;
@SpringBootApplication
public class WavefrontApplication {
public static void main(String[] args) {
SpringApplication.run(WavefrontApplication.class, args);
}
@Bean
RouterFunction<ServerResponse> routes(ReservationRepository rr) {
return route()
.GET("/reservations", r -> ok().body(rr.findAll(), Reservation.class))
.GET("/hello", r -> ok().bodyValue("Hi, Spring fans!"))
.build();
}
@Bean
ApplicationRunner runner(ReservationRepository reservationRepository) {
return args -> {
var data = Flux
.just("A", "B", "C", "D")
.map(name -> new Reservation(null, name))
.flatMap(reservationRepository::save);
reservationRepository
.deleteAll()
.thenMany(data)
.thenMany(reservationRepository.findAll())
.subscribe(System.out::println);
};
}
}
interface ReservationRepository extends ReactiveCrudRepository<Reservation, String> {
}
@Data
@AllArgsConstructor
@NoArgsConstructor
class Reservation {
@Id
private String id;
private String name;
}
我们需要在 src/main/resources/application.properties
中为 PostgreSQL 数据库指定一些配置信息。
spring.r2dbc.url=r2dbc:postgresql://127.0.0.1/orders
spring.r2dbc.username=orders
spring.r2dbc.password=orders
我们还需要在 src/main/resources/application.properties
中指定我们的应用程序如何向 Wavefront 标识自己。Wavefront 可以观察多个应用程序。而一个应用程序又可以包含许多服务。应用程序名称是服务的逻辑分组。对于我们的应用程序,名称将为 spring-tips
,服务名称将为 reservations
。
wavefront.application.name=spring-tips
wavefront.application.service=reservations
就这样了!在您的 IDE 或命令行中使用 mvn spring-boot:run
启动应用程序。您将看到应用程序启动并在控制台上显示一些信息,如下所示。
...
To share this account, make sure the following is added to your configuration:
management.metrics.export.wavefront.api-token=58e749b5-ee60-4c0b-988e-458c6cb77b32
management.metrics.export.wavefront.uri=https://wavefront.surf
Connect to your Wavefront dashboard using this one-time use link:
https://wavefront.surf/us/cY69hp561D
...
是的,就是这样。当 Wavefront Spring Boot 启动器启动时,它会为您的应用程序协商一个令牌。因此,您的仪表板在应用程序启动时就已经准备就绪并等待您。Spring Boot 启动器甚至会友好地为您捕获 Wavefront 令牌,并将其存储在 ~/.wavefront_token
中。后续运行将为您读取这些数据。或者,您可以使用控制台上打印出的 Spring Boot 属性,它也会使用这些属性。
您可能不希望将令牌检入您的 Git 存储库。相反,更倾向于使用环境变量或 Spring Cloud Config Server。想要了解有关配置的更多信息?请参阅此 Spring 提示视频,了解有关配置的信息。
请注意最后面的 URL,以便稍后参考。但首先,转到您的浏览器并使用一些端点,例如 https://127.0.0.1:8080/reservations 和 https://127.0.0.1:8080/hello。在浏览器中分别调用它们六次。
现在,转到该 Wavefront URL,您应该会看到一个显示应用程序数据的仪表板。如果您没有看到,请稍等片刻。收集应用程序数据需要几分钟时间。
您会立即发现 Wavefront 已经在应用程序级别捕获了有关应用程序的指标——例如,它知道您的 HTTP 请求,以及在 JVM 级别,它知道诸如 JVM 的内存使用情况等信息。
单击其中一个 HTTP 请求或转到 应用程序
> 跟踪
,您将能够深入了解应用程序的跟踪,如下所示。这里也有大量信息。
到目前为止,我向您展示的所有内容都只是开箱即用的准备工作。真正的强大之处在于自定义和集成。您可以创建自定义仪表板来显示所有与您相关的信息。绘制有用的业务指标。使用绘图、时间序列等。而且,一旦您确定了要采取行动的正确数据,并确定了如何最好地将数据置于上下文中,那么安装集成以在需要采取行动时提醒您就变得微不足道了。
说到集成,我承诺会向您展示一些可用的其他集成。所以,这是您的禅宗时刻:对于那些不是 Spring Boot 的稀有类型(哈?),这里有一张疯狂的其他集成列表。
还在看?...为什么?快走!您还有其他事情要做,需要享受生产部署,需要衡量增长。将您今天学到的知识应用到实践中,并将 Wavefront 集成到您的应用程序中。如果您使用的是 Tanzu 企业级就绪 Kubernetes 网格(Kubernetes)、Tanzu 应用服务(Cloud Foundry) 或 Azure Spring Cloud,那么这将是一个特别诱人的机会。终于有一个可观测性平台可以像您的基于 Spring Boot 的微服务一样扩展。所以,去吧。去尝试 Wavefront。更快、更安全地进入生产环境。