java/grails项目应该使用哪个StatsD客户机?

java/grails项目应该使用哪个StatsD客户机?,java,grails,statsd,Java,Grails,Statsd,我正在考虑将StatsD数据收集添加到我的grails应用程序中,环顾一下现有的库和代码,对于什么是一个好的可伸缩解决方案,我感到有点困惑。把这个问题放在一个小背景中,我正在从事一个在线游戏类型的项目,我将自然地监控用户与游戏引擎的交互,这些将自然地聚集在特定时刻,X用户将在一两秒钟内执行交互,然后在暂停10-20秒后重复 以下是我对目前可用的选项的分析 Etsy StatsD客户端示例 作为“可能工作的最简单的事情”的解决方案,我可以将这个类拉到我的项目中,将一个单例实例实例化为Spring

我正在考虑将StatsD数据收集添加到我的grails应用程序中,环顾一下现有的库和代码,对于什么是一个好的可伸缩解决方案,我感到有点困惑。把这个问题放在一个小背景中,我正在从事一个在线游戏类型的项目,我将自然地监控用户与游戏引擎的交互,这些将自然地聚集在特定时刻,X用户将在一两秒钟内执行交互,然后在暂停10-20秒后重复

以下是我对目前可用的选项的分析

Etsy StatsD客户端示例

作为“可能工作的最简单的事情”的解决方案,我可以将这个类拉到我的项目中,将一个单例实例实例化为Springbean并直接使用它。然而,在注意到grailsstatsd插件创建了一个客户机实例池之后,我开始怀疑这种方法的可伸缩性

如果多个线程试图同时发送事件,
doSend
方法似乎会成为一个瓶颈,但是据我所知,由于发送UDP数据包的火灾和遗忘特性,这应该很快发生,避免了我们通常与网络连接相关联的巨大开销

grailsstatsd插件

有人已经为grails创建了一个StatsD插件,其中包含一些不错的特性,比如注释和
withTimer
方法。但是,我看到那里的实现缺少示例实现中的一些错误修复,例如在调用
String.format
时指定区域设置。我也不太喜欢仅仅为了这个而引入ApacheCommons池,因为标准执行器可以实现类似的效果

java statsd客户端

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

播放statsd插件

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

问题
  • 从所有其他实现似乎都实现了另一种处理并发性的策略这一事实来看,我是否可以假设Etsy示例对于生产使用来说有点太幼稚了
  • 我在这里的分析正确吗
  • 其他人在java/groovy中使用什么来表示statsd

  • 到目前为止,最好的解决方案似乎是grails插件,只要我能接受commons池依赖,但现在,我正在认真考虑花周日的时间编写我自己的版本,将每个实现的最佳部分结合起来。

    在沉睡了一周之后,我想我将继续使用现有的grails StatsD插件。这样做的基本原理是,尽管我可以使用执行器处理并发性,但不使用对象池,这仍然会绑定到单个客户机/套接字实例,这在理论上是应用程序中相当明显的瓶颈。因此,如果我需要一个池,我也可以使用一个其他人已经完成了所有艰苦工作的池:)

    我在一次类似的纯Java StatsD客户端搜索过程中遇到了这个池,并将它与之进行了比较,您提到的有几个问题。就在阅读资料的基础上,我提出了与这些问题相关的分类

    编辑:下表已针对java statsd client的3.0.1版进行了更新,其中解决了许多原始问题

    | java-statsd-client | statsd-over-slf4j ——————————————————————————+————————————————————————+———————————————————— messages support sampling | yes | yes ——————————————————————————+————————————————————————+———————————————————— actual sampling performed | no, left to caller | yes, using java.util.Random ——————————————————————————+————————————————————————+———————————————————— nonblocking impl worker | single daemon thread | single daemon thread ——————————————————————————+————————————————————————+———————————————————— nonblocking impl queue | unbounded | caller-specified bound ——————————————————————————+————————————————————————+———————————————————— String.format locale | none* | Locale.US ——————————————————————————+————————————————————————+———————————————————— charset for message bytes | UTF-8** | default, can be overridden * no localisation is applied ** this is the charset that StatsD reads with |java statsd客户端| statsd-over-slf4j ——————————————————————————+————————————————————————+———————————————————— 消息支持采样|是|是 ——————————————————————————+————————————————————————+———————————————————— 使用java.util.Random执行的实际采样|否,留给调用方|是 ——————————————————————————+————————————————————————+———————————————————— 非阻塞impl worker |单守护进程线程|单守护进程线程 ——————————————————————————+————————————————————————+———————————————————— 非阻塞impl队列|无界|调用方指定绑定 ——————————————————————————+————————————————————————+———————————————————— 一串