将IService作为启用了持久性的群集单例时,Ignite节点会挂起

时间:2018-04-09 19:59:11

标签: .net ignite

我无法创建具有启用持久性的群集singleton IService的示例。我尝试在点火版本2.4的Win 10计算机上运行以下c#代码。一旦启动应用程序并产生以下输出(如预期的那样):

  • 节点= 1
  • 已部署=
  • 服务初始
  • 服务执行
  • 部署了服务..

第二次启动同一个应用程序会使它挂在&service; DisployClusterSingleton'中。输出是:

  • 节点= 2
  • 已部署=

更改' PersistenceEnabled'为false,使两个(甚至两个以上)应用程序按预期运行。

我不需要服务本身的持久性,而是需要缓存(不是示例代码的一部分)。我没有找到配置服务的方法,无论是否使用持久性。

[Serializable]
public class CounterService : IService
{
    public void Init(IServiceContext context)
    {
        Console.WriteLine("Service Init");
    }

    public void Execute(IServiceContext context)
    {
        Console.WriteLine("Service Execute");
    }

    public void Cancel(IServiceContext context)
    {
        Console.WriteLine("Service Cancel");
    }
}

static void Main(string[] args)
{
    var config = new IgniteConfiguration()
    {
        DataStorageConfiguration = new DataStorageConfiguration()
        {
            DefaultDataRegionConfiguration = new DataRegionConfiguration()
            {
                Name = "PersistentDefaultRegion",
                PersistenceEnabled = true,
            },
        },
    };

    using (var ignite = Ignition.Start(config))
    {
        ignite.GetCluster().SetActive(true);
        Console.WriteLine("Nodes = " + ignite.GetCluster().GetNodes().Count);

        var services = ignite.GetServices();
        var deployed = services.GetServiceDescriptors().Select(m => ", " + m.Name).ToArray();
        Console.WriteLine("Deployed = " + string.Join("\n", deployed));

        services.DeployClusterSingleton("test-service", new CounterService());
        Console.WriteLine("Service is deployed..");

        Console.ReadLine();
    }
}

1 个答案:

答案 0 :(得分:2)

这是众所周知的问题:https://issues.apache.org/jira/browse/IGNITE-8134

如果节点不是基线拓扑的一部分,则永远不会在其上部署服务。特别是,如果该节点调用同步部署方法,则该方法将挂起。

最好的方法是:

  • 启动所有服务器节点
  • 设置基线拓扑
  • 激活群集
  • 部署服务

此外,您可以使用群集激活工具https://apacheignite.readme.io/docs/cluster-activation#section-cluster-activation-tool

在您的情况下,还可以在使用以下代码部署服务之前向拓扑添加节点:

var baselineTopology = ignite.GetCluster().GetBaselineTopology();
var localNode = ignite.GetCluster().GetLocalNode();

if (baselineTopology.Count(n => n.ConsistentId.ToString() == localNode.ConsistentId.ToString()) == 0)
{
    baselineTopology.Add(localNode);
    ignite.GetCluster().SetBaselineTopology(baselineTopology);
}

只需确保在更新Baseline Topology时没有竞争条件,并且节点逐个启动。