我正在尝试使用sentinel获取我的主服务器的连接地址,问题在于sentinel仅在故障转移时发送地址,但如果我的主服务器已宕机并且从服务器被提升为主服务器,而我的应用程序刚启动,则不会知道原始主服务器已宕机,并且无法收到消息。有没有办法使用C# ServiceStack Redis客户端与sentinel通信并询问其认为谁是主服务器?
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();
}
}
}
不得已只能用一些复杂的方法,我使用下面这段代码模仿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);
}
RedisSentinel.GetSentinelInfo()
API,可以在 MyGet 上使用。 - mythz