我需要获取我目前所连接的所有主人的列表。这应该很简单:
private IEnumerable<IServer> Masters => connection
.GetEndPoints()
.Select(e => connection.GetServer(e))
.Where(s => !s.IsSlave);
这在本地工作,但在我们连接群集的生产中,它会返回重复的主人并搞砸我的代码。原因是我们的连接字符串是&#34; RedisServer1:7000,RedisServer2:7000&#34;所以我们得到一个EndPoint,它是带有RedisServer1的DnsEndPoint,还有一个EndPoint是一个IPEndPoint,它是10.0.0.15(或者一些IP),因为它使用集群中的所有东西。这两个端点指向字面上相同的框。所以,我以为我可以做到这一点:
private IEnumerable<IServer> Masters => connection
.GetEndPoints()
.Where(e => e is IPEndPoint)
.Select(e => connection.GetServer(e))
.Where(s => !s.IsSlave);
这修复了生产,所以我不再有欺骗。但是,我们的功能测试会中断,因为他们使用的是非群集的单个Redis实例,它只是&#34; localhost&#34;的DnsEndpoint。
我可能会使用某些&#34; group by&#34;并过滤掉dupes,但DnsEndpoints有主机名,IPEndPoints有IP地址,因此 我一直在寻找某种全球独一无二的&#34; Redis实例ID&#34;或某事,但似乎并不是这样的事情。也许我可以以某种方式判断我是否已连接到群集并根据它改变我的逻辑?
解决此问题的最佳方法是什么?
更新:为了澄清我的意思,如果我在Localhost上运行了6个节点的群集,GetEndPoints()
将返回7个内容:
(数组元素0和4是相同的)
答案 0 :(得分:0)
我不认为这是一个完美的答案,但这就是我想出的:
private IEnumerable<EndPoint> Endpoints
{
get
{
EndPoint[] endpoints = connection.GetEndPoints();
IServer firstServer = connection.GetServer(endpoints.FirstOrDefault());
return firstServer?.ServerType == ServerType.Cluster ? firstServer.ClusterConfiguration.Nodes.Select(n => n.EndPoint) : endpoints;
}
}
private IEnumerable<IServer> Masters => Endpoints
.Select(e => connection.GetServer(e))
.Where(s => !s.IsSlave);
基本上,我在第一个端点查看服务器。如果该服务器是群集的一部分,则返回群集中的所有节点。否则,我只返回所有端点。
如果您的端点指向多个群集,或指向群集和独立实例的混合,则此解决方案存在理论缺陷。我真的希望没有人这样做。
如果你的端点为零,它也可能会使用更多的空值。