从Sentinel C#获取Redis主节点地址

3
我正在尝试使用sentinel获取我的主服务器的连接地址,问题在于sentinel仅在故障转移时发送地址,但如果我的主服务器已宕机并且从服务器被提升为主服务器,而我的应用程序刚启动,则不会知道原始主服务器已宕机,并且无法收到消息。有没有办法使用C# ServiceStack Redis客户端与sentinel通信并询问其认为谁是主服务器?
2个回答

2
我写了一些测试代码来获取主服务器的IP和端口,可以通过哨兵(从服务器或主服务器均可)的IP和端口来实现。 这段代码使用了StackExchange.Redis的NuGet包。原始回答为"Original Answer"。
using StackExchange.Redis;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace Test
{
    public class Sentinel
    {
        private ConnectionMultiplexer Conn { get; }
        private IServer Server { get; }
        protected StringWriter ConnectionLog { get; }

        public Sentinel()
        {
            var options = new ConfigurationOptions()
            {
                CommandMap = CommandMap.Sentinel,
                EndPoints = { { "192.168.1.64", 26379 } },  //IP and Port of Sentinel
                AllowAdmin = true,
                TieBreaker = "",
                SyncTimeout = 5000
            };
            Conn = ConnectionMultiplexer.Connect(options, ConnectionLog);
            Server = Conn.GetServer("192.168.1.64", 26379); //IP and Port of Sentinel
        }

        public void SentinelGetMasterAddressByNameTest(string nameOfMaster)
        {
            var endpoint = Server.SentinelGetMasterAddressByName(nameOfMaster); 
            var ipEndPoint = endpoint as IPEndPoint;
            Console.WriteLine("The Master's <IP:Port>: {0}:{1}", ipEndPoint.Address, ipEndPoint.Port);
        }
    }



    class Program
    {

        static void Main(string[] args)
        {
           var sentinel = new Sentinel();
           sentinel.SentinelGetMasterAddressByNameTest("redis-test"); //Passing name of the master
           Console.ReadLine();
        }
    }
}


1

不得已只能用一些复杂的方法,我使用下面这段代码模仿redis-cli命令:(剩下的就是解析响应结果了)

   public string GetMasterFromSentinel(string sentinelAddress)
    {
        TcpClient server;

        try
        {
            var splittedAddress = sentinelAddress.Split(':');
            server = new TcpClient(splittedAddress[0], splittedAddress[1].ParseInt());
        }
        catch (SocketException)
        {
            _log.Error("Unable to connect to server");
            return string.Empty;
        }
        NetworkStream ns = server.GetStream();
        var payload = new byte[] { 0x2a, 0x32, 0x0d, 0x0a, 0x24, 0x38, 0x0d, 0x0a, 0x73, 0x65, 0x6e, 0x74, 0x69, 0x6e, 0x65, 0x6c, 
                0x0d, 0x0a, 0x24, 0x37, 0x0d, 0x0a, 0x6d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x73, 0x0d, 0x0a };
        ns.Write(payload, 0, payload.Length);
        ns.Flush();
        var data = new byte[1024];
        ns.Read(data, 0, data.Length);
        var recv = ns.Read(data, 0, data.Length);

        ns.Close();
        server.Close();
        return ParseResponse(data);
    }

1
现在有一个新的 RedisSentinel.GetSentinelInfo() API,可以在 MyGet 上使用。 - mythz

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接