我一直在开发一个大量使用无状态服务结构服务的系统。我以为我很清楚事情是如何运作的,但是我现在做的事情略有不同,很明显我的理解是有限的。
我有一个由 5 个节点组成的集群,为了简单起见,我所有的服务的实例数目前都是 -1。每个节点上的所有内容都意味着我可以观察单个节点的基本行为正确性。
我刚刚添加了一个需要实例计数为 1 的新服务。但是,我似乎无法正确解析此服务。相反,SF 尝试解决每台机器上的服务,该服务对所有机器都失败,但存在单个服务的机器除外。
我的假设是 SF 会自动解析对集群中任何位置的服务的引用。如果该引用失败,那么它将自动解析一个新的引用,依此类推。至少对于我目前做事的方式来说,这似乎是不正确的。
我可以使用与此类似的代码找到一个实例,但是如果该实例失败会发生什么。我如何获得另一个参考?
我可以解决这样的每个呼叫,但是当我真的只想解决 IXyzService 并将其传递时,这似乎是一个糟糕的主意。
这就是我解决服务的方式,因为我使用的是 V2 自定义序列化。
var _proxyFactory = new ServiceProxyFactory(c =>
{
return new FabricTransportServiceRemotingClientFactory(
serializationProvider: new CustomRemotingSerializationProvider(Logger)
);
});
var location = new Uri("fabric:/xyz/abcService");
var proxy = _proxyFactory.CreateServiceProxy<TService>(location);
这确实有效,但它似乎只能解决同一台机器上的服务。所以 ServiceA 会在同一台机器上解析对 ServiceB 的引用。但是,如果出于正当的原因机器上不存在 ServiceB,则解析将失败。
概括:
ServiceA 使用 V2 自定义序列化ServiceProxyFactory来解析对 ServiceB 的接口引用的正确方法是什么,无论 ServiceA 和 ServiceB 在集群中的何处?
更新:
它不起作用的证据是解决的呼吁永远挂起。根据此链接,这是正确的行为,因为服务最终会出现。然而,只有 1 个节点正确解决了它,即单个实例处于活动状态的节点。我已经尝试了几件事,甚至等待 30 秒,以确保它不是初始化问题。
var proxy = _proxyFactory.CreateServiceProxy<TService>(location);
// Never gets here except on the one node.
SomethingElse(proxy);
监听器代码
这基本上完全遵循V2 自定义序列化教程。
var listeners = new[]
{
new ServiceInstanceListener((c) =>
{
return new FabricTransportServiceRemotingListener(c, this, null,
new CustomRemotingSerializationProvider(Logger));
})
};
public class HyperspaceRemotingSerializationProvider : IServiceRemotingMessageSerializationProvider
{
#region Private Variables
private readonly ILogger _logger;
private readonly Action<RequestInfo> _requestAction;
private readonly Action<RequestInfo> _responseAction;
#endregion Private Variables
public CustomRemotingSerializationProvider(ILogger logger, Action<RequestInfo> requestAction = null, Action<RequestInfo> responseAction = null)
{
_logger = logger;
_requestAction = requestAction;
_responseAction = responseAction;
}
public IServiceRemotingRequestMessageBodySerializer CreateRequestMessageSerializer(Type serviceInterfaceType, IEnumerable<Type> requestWrappedTypes,
IEnumerable<Type> requestBodyTypes = null)
{
return new RequestMessageBodySerializer(_requestAction);
}
public IServiceRemotingResponseMessageBodySerializer CreateResponseMessageSerializer(Type serviceInterfaceType, IEnumerable<Type> responseWrappedTypes,
IEnumerable<Type> responseBodyTypes = null)
{
return new ResponseMessageBodySerializer(_responseAction);
}
public IServiceRemotingMessageBodyFactory CreateMessageBodyFactory()
{
return new MessageBodyFactory();
}
}
连接代码
_proxyFactory = new ServiceProxyFactory(c =>
{
return new FabricTransportServiceRemotingClientFactory(
serializationProvider: new CustomRemotingSerializationProvider(Logger)
);
});
// Hangs here - tried different partition keys or not specifying one.
var proxy = _proxyFactory.CreateServiceProxy<TService>(location, ServicePartitionKey.Singleton);