FabricException:分区的主要或无状态实例
FabricException: The primary or stateless instance for the partition
我正在关注 tutorial from [this book]:
我收到以下异常:
毫无疑问我的节点运行很好:
以下是我的无状态服务的设置方式:
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.
您正在尝试通过远程处理访问您的服务,但您的服务未启用远程处理。
您需要 return 来自 CreateServiceInstanceListeners
的 communication 侦听器并实施 IService
。
在创建无状态服务时,您将服务称为 MyStatelessService
而不是 CalculatorService
,并且您将应用程序称为 CalculatorService
而不是 CalculatorApplication
。正如本书在 'The first version' "Create a new Service Fabric application named CalculatorApplication with a service named CalculatorService" 下的第 1 步所述。您创建了一个名为 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)) };
}
}
但是,调用应用程序是非常规的 'service',因此我建议创建一个新项目并将您当前的实现粘贴到其中。
创建新项目时,将您的应用程序命名为 CalculatorApplication。
然后创建名为 CalculatorService 的服务。
您的 CalculatorService.cs
文件是自动生成的,因此只需将您当前的实施粘贴到其中即可。 (与上面的 MyStatelessService 相同,但名称为 CalculatorService。)
两件事:
您的 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();
}
在 try
语句之后更改 MyStatelessService
的 Program.cs
部分:
ServiceRuntime.RegisterServiceAsync("MyStatelessServiceType",
context => new CalculatorService(context)).GetAwaiter().GetResult();
ServiceEventSource.Current.ServiceTypeRegistered(Process.GetCurrentProcess().Id, typeof(CalculatorService).Name);
您引用的不是 CalculatorService
,而是 MyStatelessService
。
我正在关注 tutorial from [this book]:
我收到以下异常:
毫无疑问我的节点运行很好:
以下是我的无状态服务的设置方式:
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.
您正在尝试通过远程处理访问您的服务,但您的服务未启用远程处理。
您需要 return 来自 CreateServiceInstanceListeners
的 communication 侦听器并实施 IService
。
在创建无状态服务时,您将服务称为 MyStatelessService
而不是 CalculatorService
,并且您将应用程序称为 CalculatorService
而不是 CalculatorApplication
。正如本书在 'The first version' "Create a new Service Fabric application named CalculatorApplication with a service named CalculatorService" 下的第 1 步所述。您创建了一个名为 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)) };
}
}
但是,调用应用程序是非常规的 'service',因此我建议创建一个新项目并将您当前的实现粘贴到其中。
创建新项目时,将您的应用程序命名为 CalculatorApplication。
然后创建名为 CalculatorService 的服务。
您的 CalculatorService.cs
文件是自动生成的,因此只需将您当前的实施粘贴到其中即可。 (与上面的 MyStatelessService 相同,但名称为 CalculatorService。)
两件事:
您的
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();
}
在
try
语句之后更改MyStatelessService
的Program.cs
部分:ServiceRuntime.RegisterServiceAsync("MyStatelessServiceType", context => new CalculatorService(context)).GetAwaiter().GetResult(); ServiceEventSource.Current.ServiceTypeRegistered(Process.GetCurrentProcess().Id, typeof(CalculatorService).Name);
您引用的不是 CalculatorService
,而是 MyStatelessService
。