使用 Prometheus(和 grafana)在 Javalin 中设置监控

原文:https://javalin.io/tutorials/prometheus-example

依赖项

首先,我们需要创建一个带有一些依赖项的 Maven 项目:(→ 教程)

  • 我们需要 Javalin 作为服务器,并使用 Prometheus 进行监控。
  • 我们还将添加 unirest 来模拟流量:
<dependencies>
    <dependency>
        <groupId>io.javalin</groupId>
        <artifactId>javalin-bundle</artifactId>
        <version>6.6.0</version>
    </dependency>
    <dependency>
        <groupId>io.prometheus</groupId>
        <artifactId>simpleclient_httpserver</artifactId>
        <version>0.16.0</version>
    </dependency>
    <dependency>
        <groupId>com.konghq</groupId>
        <artifactId>unirest-java</artifactId>
        <version>3.13.10</version>
    </dependency>
</dependencies>

现在我们已经完成了所有设置,我们需要让 Prometheus 从我们的应用程序中收集数据。幸运的是,Jetty 中有一个名为 的处理程序StatisticsHandler。我们可以将它添加到 Javalin 的嵌入式服务器中,并使用它来向 Prometheus 公开统计数据。我们也可以使用QueuedThreadPoolJetty 使用的 来执行相同的操作:

public static void main(String[] args) throws Exception {

    StatisticsHandler statisticsHandler = new StatisticsHandler();
    QueuedThreadPool queuedThreadPool = new QueuedThreadPool(200, 8, 60_000);

    Javalin app = Javalin.create(config -> {
        config.jetty.threadPool = queuedThreadPool;
        config.jetty.modifyServer(server -> {
            server.setHandler(statisticsHandler);
        });
    }).start(7070);
    initializePrometheus(statisticsHandler, queuedThreadPool);
}

private static void initializePrometheus(StatisticsHandler statisticsHandler, QueuedThreadPool queuedThreadPool) throws IOException {
    StatisticsHandlerCollector.initialize(statisticsHandler);
    QueuedThreadPoolCollector.initialize(queuedThreadPool);
    HTTPServer prometheusServer = new HTTPServer(7080);
    LoggerFactory.getLogger("JavalinPrometheusExampleApp").info("Prometheus is listening on: http://localhost:7080");
}

在上面的代码中,我们首先创建两个想要暴露给 Prometheus 的对象:StatisticsHandler和QueuedThreadPool。然后我们调用 来initializePrometheus为这些对象注册收集器,并启动 Prometheus 服务器。

如果您熟悉 Prometheus/Grafana 的工作原理,您可以立即停止阅读本教程,并开始从运行在端口 上的服务器进行抓取7080。如果不熟悉,请继续阅读。

使用 Prometheus-client 导出统计数据

要使用 Prometheus 收集数据,您需要创建一个扩展的对象Collector。在源代码中,您会发现两个这样的对象:StatisticsHandlerCollector 和QueuedThreadPoolCollector。创建收集器时必须调用该方法.register(),并且必须重写该collect()方法。

源代码中包含的两个收集器也可以作为 Maven 依赖项包含在内,但我将它们包含在内是为了说明如何创建自定义收集器。

模拟一些交通

为了确保一切正常,最好查看一些流量。因此,我们需要声明几个端点并向它们发送请求。让我们将其添加到我们的public static void main:

router.apiBuilder(() -> { // available on config.router inside Javalin.create()
    get("/1", ctx -> ctx.result("Hello World"));
    get("/2", ctx -> {
        Thread.sleep((long) (Math.random() * 2000));
        ctx.result("Slow Hello World");
    });
    get("/3", ctx -> ctx.redirect("/2"));
    get("/4", ctx -> ctx.status(400));
    get("/5", ctx -> ctx.status(500));
});

while (true) {
    spawnRandomRequests();
}

spawnRandomRequests()尚不存在,所以我们也需要创建它:

private static void spawnRandomRequests() throws InterruptedException {
    new Thread(() -> {
        for (int i = 0; i < new Random().nextInt(50); i++) {
            Unirest.get("http://localhost:7070/1").asString(); // we want a lot more "200 - OK" traffic
            Unirest.get("http://localhost:7070/" + (1 + new Random().nextInt(5))).asString(); // hit a random (1-5) endpoint
        }
    }).start();
    Thread.sleep((int) (Math.random() * 250));
}

上述代码每隔0-250ms创建一个线程,该线程执行0-100个请求,大部分是针对/1端点的。

在 Prometheus 中查看数据

现在我们有了收集器和模拟数据,终于可以查看一些图表了。为此,你需要在本地设置 Prometheus。Prometheus 的开发者们有一个非常棒的入门指南,你可以在他们的页面上找到:https://prometheus.io/docs/prometheus/latest/getting_started/

您需要调整prometheus.yml文件以抓取我们刚刚公开的端点。这是我正在使用的 scrape-config:

scrape_configs:
  - job_name: 'javalin'
    scrape_interval: 1s
    static_configs:
      - targets: ['localhost:7080']
        labels:
          group: 'test'

然后需要使用以下配置启动 Prometheus:

prometheus --config.file=prometheus.yml

现在你可以去 localhost:9090 使用 Prometheus 了:

不过,Prometheus 不太擅长可视化数据,他们建议你使用 Grafana 来实现:https://prometheus.io/docs/visualization/grafana/

您可以按照他们的指南将 grafana 连接到 prometheus,完成后,您将能够制作如下仪表板:格拉法纳

作者:Jeebiz  创建时间:2025-05-04 00:25
最后编辑:Jeebiz  更新时间:2025-05-04 00:55