【问题标题】:FabricException: The primary or stateless instance for the partitionFabricException:分区的主实例或无状态实例
【发布时间】:2017-10-19 01:34:30
【问题描述】:

我正在关注来自[this book]tutorial

我收到以下异常:

毫无疑问,我的节点运行良好:

这是我的无状态服务的设置方式:

internal sealed class MyStatelessService : StatelessService
    {
        public MyStatelessService(StatelessServiceContext context)
            : base(context)
        { }

        /// <summary>
        /// Optional override to create listeners (e.g., TCP, HTTP) for this service replica to handle client or user requests.
        /// </summary>
        /// <returns>A collection of listeners.</returns>
        protected override IEnumerable<ServiceInstanceListener> CreateServiceInstanceListeners()
        {
            return new ServiceInstanceListener[0];
        }


        /// <summary>
        /// This is the main entry point for your service instance.
        /// </summary>
        /// <param name="cancellationToken">Canceled when Service Fabric needs to shut down this service instance.</param>
        protected override async Task RunAsync(CancellationToken cancellationToken)
        {
            // TODO: Replace the following sample code with your own logic 
            //       or remove this RunAsync override if it's not needed in your service.

            long iterations = 0;

            while (true)
            {
                cancellationToken.ThrowIfCancellationRequested();

                ServiceEventSource.Current.ServiceMessage(this.Context, "Working-{0}", ++iterations);

                await Task.Delay(TimeSpan.FromSeconds(1), cancellationToken);
            }
        }
    }

我部署和得到这个异常的方式:

我做错了什么?如何让我的客户端连接到我的集群?

整个解决方案可以查看here.

【问题讨论】:

    标签: c# .net azure visual-studio-2017 azure-service-fabric


    【解决方案1】:

    两件事:

    1. 您的ICalculatorService 必须在另一个库项目中定义,以便在您的无状态服务库和您的客户端项目之间共享。所以:

      • 新建库项目MyStatelessService.Interfaces
      • 添加 NuGet 包:Microsoft.ServiceFabric.Services.Remoting
      • 在这个库中定义你的ICalculatorService
      • 从您的其他两个项目中删除 ICalculatorService
      • MyStatelessService.Interfaces 的引用添加到您的客户端应用程序和无状态服务库。
      • 修复对ICalculatorService 的引用
      • 您的所有ICalculatorService 都应从同一个库中引用

    您的客户将是:

    using Microsoft.ServiceFabric.Services.Remoting.Client;
    using MyStatelessService.Interfaces;
    using System;
    
    static void Main(string[] args)
    {
        var calculatorClient = ServiceProxy.Create<ICalculatorService>
            (new Uri("fabric:/CalculatorService/MyStatelessService"));
    
        var result = calculatorClient.Add(1, 2).Result;
    
        Console.WriteLine(result);
        Console.ReadKey();
    }
    
    1. try 语句之后更改MyStatelessServiceProgram.cs 部分:

      ServiceRuntime.RegisterServiceAsync("MyStatelessServiceType",
          context => new CalculatorService(context)).GetAwaiter().GetResult();
      
      ServiceEventSource.Current.ServiceTypeRegistered(Process.GetCurrentProcess().Id, typeof(CalculatorService).Name);
      

    您引用的是MyStatelessService,而不是CalculatorService

    【讨论】:

      【解决方案2】:

      您正在尝试通过远程访问您的服务,但您的服务未启用远程处理。

      你需要从CreateServiceInstanceListeners返回一个communication监听器并实现IService

      【讨论】:

        【解决方案3】:

        在创建无状态服务时,您将服务称为 MyStatelessService 而不是 CalculatorService,并且您将应用程序称为 CalculatorService 而不是 CalculatorApplication。正如本书在“第一个版本”下的步骤 1 中所述,“使用名为 CalculatorService 的 service 创建一个名为 CalculatorApplication 的新 Service Fabric application”。您创建了一个名为 CalculatorService 的应用程序和一个名为 MyStatelessService 的服务。然后,您在无状态服务项目中创建了一个新服务文件。您应该绝不在服务中创建新服务。请改用生成的service.cs(在您的情况下为MyStatelessService.cs)文件。解决问题的一种方法是将CalculatorService 的实现复制到您的无状态服务中并删除CalculatorService.cs。您的无状态服务将是:

        internal sealed class MyStatelessService: StatelessService, ICalculatorService
        {
            public MyStatelessService(StatelessServiceContext serviceContext) : base(serviceContext)
            {
        
            }
        
            public Task<int> Add(int a, int b)
            {
                return Task.FromResult<int>(a + b);
            }
        
            public Task<int> Subtract(int a, int b)
            {
                return Task.FromResult<int>(a - b);
            }
        
            protected override IEnumerable<ServiceInstanceListener> CreateServiceInstanceListeners()
            {
                return new[] { new ServiceInstanceListener(context => this.CreateServiceRemotingListener(context)) };
            }
        }
        

        但是,将应用程序称为“服务”是非常规的,因此我建议创建一个新项目并将您当前的实现粘贴到其中。

        创建新项目时,将您的应用程序命名为 CalculatorApplication

        然后创建名为 CalculatorService 的服务。

        您的CalculatorService.cs 文件是自动生成的,因此只需将您当前的实现粘贴到其中即可。 (与上面的 MyStatelessService 相同,但名称为 CalculatorService。)

        【讨论】:

          猜你喜欢
          • 2016-10-10
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-10-06
          • 2013-11-16
          • 2017-01-17
          • 1970-01-01
          • 2013-04-15
          相关资源
          最近更新 更多