我应该将哪个StatsD客户端用于java /grails项目?Etsy StatsD 客户端示例圣杯统计插件java-statsd-client播放统计插件问题

2022-09-02 13:58:06

我正在考虑将StatsD数据收集添加到我的grails应用程序中,并且环顾现有的库和代码,这让我对什么是一个好的可扩展解决方案感到有些困惑。为了将这个问题放在上下文中,我正在研究一个在线游戏类型的项目,我自然会监控用户与游戏引擎的交互,这些交互自然会聚集在特定的时刻,其中X用户将在一两秒的窗口内执行交互,然后在10-20秒的暂停后重复。

以下是我对今天可用选项的分析。

Etsy StatsD 客户端示例

https://github.com/etsy/statsd/blob/master/examples/StatsdClient.java

作为“最简单的可能奏效”解决方案,我可以将这个类拉入我的项目中,并将单例实例作为弹簧豆实例并直接使用它。然而,在注意到grails-statsd插件创建了一个客户端实例池之后,我开始想知道这种方法的可扩展性。

如果许多线程尝试同时发送事件,则该方法似乎可能成为瓶颈,但是据我所知,由于发送UDP数据包的火灾和忘记性质,这应该很快发生,从而避免了我们通常与网络连接关联的巨大开销。doSend

圣杯统计插件

https://github.com/charliek/grails-statsd/

有人已经为圣杯创建了一个StatsD插件,其中包括一些不错的功能,例如注释和方法。但是,我看到该实现缺少示例实现中的一些错误修复,例如在调用时指定区域设置。我也不是一个超级粉丝,只是为了这个,当一个标准的执行器可以达到类似的效果时,拉入apache commons-pool。withTimerString.format

java-statsd-client

https://github.com/tim-group/java-statsd-client/

这是一个替代的纯java库,它通过维护自己的ExecutorService来异步运行。它支持整个 StatsD API,包括集和采样,但不提供任何用于配置线程池和队列大小的挂钩。在出现问题的情况下,对于非关键的事情,例如监视,我认为我更喜欢有限队列和丢失事件,而不是有无限的队列来填满我的堆。

播放统计插件

https://github.com/vznet/play-statsd/

现在我不能在我的grails项目中直接使用这段代码,但我认为值得一看,看看事情是如何实现的。一般来说,我喜欢代码的构建方式,非常干净和可读。此外,似乎还存在区域设置错误,但其他功能与 etsy 示例一起完成。有趣的是,除非有一些我不理解的 scala 魔法,否则这似乎会为发送到 StatsD 的每个数据点创建一个新的套接字。虽然这种方法很好地避免了对象池或执行器线程的必要性,但我无法想象它非常有效,可能会在请求线程中执行DNS查找,这些请求线程应该尽快返回给用户。StatsdClient.scala

问题

  1. 从所有其他实现似乎已经实现了另一种处理并发的策略这一事实来看,我是否可以假设Etsy示例对于生产使用来说有点太天真了?
  2. 我在这里的分析似乎是正确的吗?
  3. 其他人在java/groovy中使用了什么统计数据?

到目前为止,只要我能接受commons-pool依赖性,看起来最好的现有解决方案是grails插件,但现在我正在认真考虑在周日编写自己的版本,该版本结合了每个实现的最佳部分。


答案 1

作为java-statsd-client的主要提交者,以及在生产环境中使用此库的人,我想尝试减轻您对“有一个无限的队列填满我的堆”的恐惧。

我认为你对Etsy StatsD客户端示例的分析几乎已经确定了这一点,当你说“由于发送UDP数据包的火灾和忘记性质,这应该很快发生,避免我们通常与网络连接相关的巨大开销。

我的理解是,java-statsd-client目前实现的方式,建立大量出站消息队列的约束是发送即发即忘UDP数据包的速度。我不是这方面的专家,但我不知道这有什么办法可以阻止,以至于无限的队列可能会建立起来。

当您最初进行评估时,java-statsd-client存在许多悬而未决的问题(例如,Locale/字符编码的歧义,以及缺乏采样支持),但这些问题最近已经得到解决。剩下的问题是,是否存在填满堆的真正风险。我很想听听社区对这个问题的看法,如果大家一致认为存在问题,我会很乐意探索在图书馆引入限制队列的问题。


答案 2

在睡了一个星期之后,我想我将继续使用现有的grails StatsD插件。这样做的理由是,尽管我可以使用执行器来处理并发性来实现类似的效果,但在不使用对象池的情况下,这仍然会绑定到单个客户端/套接字实例,从理论上讲,这是应用程序中相当明显的瓶颈。因此,如果我无论如何都需要一个游泳池,我也可以使用一个其他人已经完成了所有辛勤工作:)


推荐