在Service Fabric中,似乎只是常见的做法是错误的。我怀疑下面的代码将stateManager保存为本地缓存,当在“ SomeService”状态服务的“ CreateServiceReplicaListeners()”方法的返回语句中实例化“启动”类时,可能导致潜在的问题。
可能发生的情况是当状态管理器以某种方式重新实例化时。对于下面的做法是否正确,我需要更多的解释。如果没有,那么最好的做法是什么?
internal class SomeService : StatefulService
{
protected override IEnumerable<ServiceReplicaListener> CreateServiceReplicaListeners()
{
return new[]{
new ServiceReplicaListener(
initParams =>
new OwinCommunicationListener("SomeService", new Startup(this.StateManager), initParams))
};
}
}
}
public class Startup : IOwinAppBuilder
{
private readonly IReliableStateManager stateManager;
public Startup(IReliableStateManager stateManager)
{
this.stateManager = stateManager;
}
public void Configuration(IAppBuilder appBuilder)
{
// other initialization codes..
...
...
UnityConfig.RegisterComponents(config, this.stateManager);
appBuilder.UseWebApi(config);
}
}
答案 0 :(得分:2)
每当状态服务更改角色时,都会触发 IStatefulServiceReplica.ChangeRoleAsync(ReplicaRole newRole, CancellationToken cancellationToken)
。
ChangeRoleAsync(..)
确保新角色使用正确的通信执行以下操作:
CloseCommunicationListenersAsync(CancellationToken cancellationToken)
关闭所有打开的监听器OpenCommunicationListenersAsync(newRole, cancellationToken)
担任主要或 ActiveSecondary 角色OpenCommunicationListenersAsync()
将调用 CreateServiceReplicaListeners()
以获取侦听器,并为每个返回的侦听器调用CreateCommunicationListener(serviceContext)
以打开相关的侦听器端点。角色更改在升级和负载平衡过程中很常见,因此这是很常见的事件。
总结
每次发生角色更改时,都会调用CreateServiceReplicaListeners()
, ChangeRole 不会关闭服务,因此可能会有副作用,例如,如果您在DI中注册依赖项容器,您可能会面临重复的注册。