工作流服务可伸缩性问题

时间:2012-08-29 10:54:39

标签: wcf workflow-foundation-4 wcf-client workflowservice wcf-configuration

我目前遇到了工作流服务的一些问题。 如果我以短序列开始4,5,它们工作正常,但如果我增加这个值(从〜10开始),那么我得到以下异常:

  

由于服务器启动的关闭,输出会话自动关闭,因此该通道不能再用于发送消息。通过将DispatchRuntime.AutomaticInputSessionShutdown设置为false来禁用自动关闭,或者考虑使用远程服务器修改关闭协议。

我认为问题在于我创建代理的方式。我使用以下代码提供代理,尝试重用现有代理:

public abstract class ProxyProvider<TService>
    where TService : class
{
    /// <summary>
    /// Static reference to the current time provider.
    /// </summary>
    private static ProxyProvider<TService> current = DefaultProxyProvider.Instance;

    private TService service;

    /// <summary>
    /// Gets or sets the current time provider.
    /// </summary>
    /// <value>
    /// The current time provider.
    /// </value>
    public static ProxyProvider<TService> Current
    {
        get
        {
            return ProxyProvider<TService>.current;
        }

        set
        {
            if (value == null)
            {
                throw new ArgumentNullException("value");
            }

            ProxyProvider<TService>.current = value;
        }
    }

    /// <summary>
    /// Resets to default.
    /// </summary>
    public static void ResetToDefault()
    {
        ProxyProvider<TService>.current = DefaultProxyProvider.Instance;
    }

    /// <summary>
    /// Loads the proxy.
    /// </summary>
    /// <param name="forceNew">if set to <c>true</c> [force new].</param>
    /// <returns>The instance of the proxy.</returns>
    public virtual TService Provide(bool forceNew = false)
    {
        if (forceNew || !this.IsInstanceValid())
        {
            this.service = this.CreateInstance();
            return this.service;
        }

        return this.service;
    }

    /// <summary>
    /// Internals the load.
    /// </summary>
    /// <returns>The new created service.</returns>
    protected abstract TService CreateInstance();

    private bool IsInstanceValid()
    {
        var instance = this.service as ICommunicationObject;
        if (instance == null)
        {
            return false;
        }

        return instance.State != CommunicationState.Faulted && instance.State != CommunicationState.Closed && instance.State != CommunicationState.Closing;
    }

    /// <summary>
    /// Defines the default <see cref="ProxyProvider&lt;TService&gt;"/> which uses the System DateTime.UtcNow value.
    /// </summary>
    private sealed class DefaultProxyProvider : ProxyProvider<TService>
    {
        /// <summary>
        /// Reference to the instance of the <see cref="ProxyProvider&lt;TService&gt;"/>.
        /// </summary>
        private static ProxyProvider<TService> instance;

        /// <summary>
        /// Gets the instance.
        /// </summary>
        public static ProxyProvider<TService> Instance
        {
            get
            {
                if (DefaultProxyProvider.instance == null)
                {
                    DefaultProxyProvider.instance = new DefaultProxyProvider();
                }

                return DefaultProxyProvider.instance;
            }
        }

        /// <summary>
        /// Loads the specified force new.
        /// </summary>
        /// <returns>A non-disposed instance of the given service.</returns>
        protected override TService CreateInstance()
        {
            var loadedService = Activator.CreateInstance<TService>();
            return loadedService;
        }
    }

使用额外的“懒惰”提供商:

public class CustomConstructorProxyProvider<TService> : ProxyProvider<TService>
    where TService : class
{
    private readonly Func<TService> constructor;

    /// <summary>
    /// Initializes a new instance of the <see cref="CustomConstructorProxyProvider&lt;TService&gt;"/> class.
    /// </summary>
    /// <param name="constructor">The constructor.</param>
    public CustomConstructorProxyProvider(Func<TService> constructor)
    {
        this.constructor = constructor;
    }

    /// <summary>
    /// Internals the load.
    /// </summary>
    /// <returns>The new created service.</returns>
    protected override TService CreateInstance()
    {
        var service = this.constructor();
        return service;
    }
}

以这种方式使用:

var proxy = ProxyProvider<IWorkflowService>.Current.Provide();
proxy.DoSomething();

初始化如下:

ProxyProvider<IWorkflowService>.Current = new CustomConstructorProxyProvider<IWorkflowService>(() => new WorkflowServiceProxy("endpoint"));

工作流服务由IIS托管,我添加了以下限制设置:

<serviceThrottling
                maxConcurrentCalls="512"
                maxConcurrentInstances="2147483647"
                maxConcurrentSessions="1024"/>

这应该足以满足我的需求。

我希望有人可以帮助我配置客户端和服务器以实现所需的可伸缩性(几百个按顺序启动并使用WorkflowInstance sql存储并行运行)。

更新: 我正在为所有服务使用NetTcpBinding。

更新2 : 现在,所有服务都在本地托管和使用。

由于 弗朗西斯

0 个答案:

没有答案