0
点赞
收藏
分享

微信扫一扫

Consul.Net 的领导人选举


当我们有一个集群的应用或者要实现一个高可用的服务的时候就需要这个选举(曾经要写一个高可用服务,结果,选举算法这一块没攻克,导致项目被干掉了)。

这样的应用服务也是需要分布在多台服务器上的业务。

如下图

画的不是很好看,大致意思就是一个服务集群,然后呢,为了保证高可用,得有其中一个服务去DoWork();

但是,不能有多的服务过去,这个时候就需要选举算法了。

Consul.Net 的领导人选举_领导选举

轻量型的选举算法是Raft,有兴趣的可以去研究一下。

我这里是直接通过Consul 自身的性质来实现选举算法的

实现的结果如下,

Consul.Net 的领导人选举_System_02

去除一个工作的服务,另外一个服务,直接运行了。

Consul.Net 的领导人选举_System_03

程序如下

原理是这个样子的

var consulClient = new ConsulClient();
var session = consulClient.CreateLock(serviceKey);
await session.AcquireLock();
if (session.IsHeld)
DoWork();

实际是这个样子的

using System;
using System.Threading;
using System.Threading.Tasks;
using Consul;
using Topshelf;
using Timer = System.Timers.Timer;

namespace ClockService
{
class Program
{
static void Main(string[] args)
{
HostFactory.Run(x =>
{
x.Service(s =>
{
s.ConstructUsing(name => new Clock());
s.WhenStarted(c => c.Start());
s.WhenStopped(c => c.Stop());
});
x.RunAsLocalSystem();
x.SetDisplayName("Clock");
x.SetServiceName("Clock");
});
}
}

class Clock
{
readonly Timer _timer;
private IDistributedLock _session;

public Clock()
{
var consulClient = new ConsulClient();
_session = consulClient.CreateLock("service/clock");
_timer = new Timer(3000);
_timer.Elapsed += (sender, eventArgs) => CallTime();
}

private void CallTime()
{
Task.Run(() =>
{
_session.Acquire(CancellationToken.None);
}).GetAwaiter().GetResult();

Console.WriteLine(_session.IsHeld
? $"It is {DateTime.Now}"
: "Not the leader");
}

public void Start() { _timer.Start(); }

public void Stop()
{
_timer.Stop();
Task.WaitAll(
Task.Run(() =>
{
_session.Release();
}),
Task.Run(() =>
{
_session.Destroy();
}));
}
}
}


举报

相关推荐

0 条评论