Spring 提示:Wavefront 可观测性平台

工程 | Josh Long | 2020 年 4 月 29 日 | ...

演讲者:Josh Long (@starbuxman)

嗨,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 版本。选择 R2DBCPostgreSQLReactive WebSpring Cloud SleuthLombok。单击 生成,解压缩生成的文件。当我编写本文时,使用 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/reservationshttps://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。更快、更安全地进入生产环境。

获取 Spring 时事通讯

与 Spring 时事通讯保持联系

订阅

领先一步

VMware 提供培训和认证,以加速您的进步。

了解更多

获取支持

Tanzu Spring 在一个简单的订阅中提供 OpenJDK™、Spring 和 Apache Tomcat® 的支持和二进制文件。

了解更多

即将举行的活动

查看 Spring 社区中所有即将举行的活动。

查看全部