2

我正在使用 Graphite.NET 记录到 statsD。在底层,它使用 UdpClient 写入 statD 服务器。来源。我认为将其创建为单例是有意义的,因为我会经常记录,而且每次我想记录时创建这个客户端和连接似乎都会有很多开销。这样做有什么缺点吗?如果连接中断会发生什么:会抛出异常吗?下次我尝试使用记录器时,StuctureMap 会重新创建记录器吗?这是我的 SM 配置的样子:

x.For<IStatsDClientAdapter>()
                 .Singleton()
                 .Use<StatsDClientAdapter>()
                 .Ctor<string>("hostname").EqualToAppSetting("GraphiteHostname")
                 .Ctor<int>("port").EqualToAppSetting("GraphitePort")
                 .Ctor<string>("keyPrefix").EqualToAppSetting("GraphiteKeyPrefix");
4

1 回答 1

2

因为 Graphite.NET StatsDClient 在其构造函数中实例化并调用 UdpClient 上的 Connect,所以如果您只进行一次此调用(例如,在应用程序启动时通过依赖注入单例 - 正如您所做的那样) ,您从初始连接异常中恢复的能力是有限的。

使用带有此 StatsDClient 的 Singleton 意味着如果发生连接问题,您需要捕获并重新实例化 StatsDClient,以确保您的应用程序已正确初始化(即使用正常工作的 StatsDClient)......因为再次,Connect 是在构造函数中运行。

也就是说,如果 StatsDClient 初始化成功(即 Connect 没有引发异常),那么即使服务器随后出现故障,您也应该没问题,因为 UDP 是无连接的,并且 StatsDClient 正在处理/捕获 Send() 上发生的任何异常。客户端应该继续在默认连接中建立的 Ip 和端口上触发发送,而不知道服务器是好还是坏。

太糟糕了 Graphite.NETStatsDClient没有将 ip 和端口传递给UdpClient.Send()- http://msdn.microsoft.com/en-us/library/acf44a1a.aspx)而不是通过构造函数使用默认连接......因为这个将使使用静态成员成为可能(因为您可以在任何条件下构造可用的 StatsDClients)。

长话短说,为了避免让您的应用程序进入不良状态,我会在使用时实例化。如下:

using(var statsdclient = new StatsDClient("my.statsd.host", 8125, "whatever.blah"))
{
    statsdclient.Increment("asdf"); 
}

或者,或者,派生 StatsDClient 并对其进行修改以在 Send() 上传递 IP 和端口。

于 2013-06-19T00:49:12.880 回答