解决对服务结构无状态服务的引用的正确方法是什么?

时间:2018-10-27 08:41:22

标签: service azure-service-fabric service-fabric-stateless

我一直在开发一个系统,该系统大量使用无状态服务结构服务。我以为自己有个好主意,但是现在我做的有些不同,很明显我的理解是有限的。

为简单起见,我有5个节点的集群,并且我所有的服务的实例计数均为-1。每个节点上的所有内容都意味着我可以观察单个节点的基本行为正确性。

我刚刚添加了一个新服务,该服务的实例计数为1。但是,似乎无法正确解析此服务。相反,SF尝试解析每台计算机上的服务,该服务对于所有计算机都失败,除了存在单个服务的计算机之外。

我认为SF会自动解析对集群中任何位置的服务的引用。如果该引用失败,则它将自动解析新的引用,依此类推。看来这至少对于我当前的工作方式是不正确的。

我可以使用类似于this的代码找到一个实例,但是如果该实例失败,会发生什么。如何获得其他参考?

我可以为this之类的每个呼叫解决,但是当我真的只想解析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和ServiceB在群集中的任何位置的对ServiceB的接口引用的正确方法是什么?

更新

解决该问题的呼声永远悬而未决。根据此link,这是正确的行为,因为该服务最终将启动。但是,只有1个节点正确解决了该问题,并且该节点是单个实例处于活动状态的节点。我尝试了几件事,甚至等待了30秒,以确保这不是一个初始化问题。

var proxy = _proxyFactory.CreateServiceProxy<TService>(location);

// Never gets here except on the one node.
SomethingElse(proxy);

收听者代码

这基本上完全遵循V2 custom serialization教程。

    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); 

0 个答案:

没有答案