【问题标题】:WebJob SDK not working when running in a Service Fabric application在 Service Fabric 应用程序中运行时,WebJob SDK 不工作
【发布时间】:2017-01-12 21:53:41
【问题描述】:

我想在作为 Service Fabric 应用程序运行的无状态服务中使用 WebJob SDK。不幸的是,我无法让它正常运行。下面是重现问题的测试代码的一部分。 “ProcessMethod”永远不会被调用。触发的函数“ProcessNotificationsInQueue”也永远不会执行(是的,队列中有项目)。尽管应用程序仍在运行,但应用程序的“健康状况”在 Service Fabric Explorer 中设置为“错误”。

DashboardConnectionString 和 StorageConnectionString 都有正确的值。

当在控制台应用程序或 WorkerRole 中运行非常相似的代码时,我没有发现任何问题。

我错过了什么吗?是否有人已经在 Service Fabric 应用程序中成功使用过 WebJob SDK?

public sealed class TestStatelessService : StatelessService
{
    public TestStatelessService(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)
    {
        ConfigurationPackage configPackage = this.Context.CodePackageActivationContext.GetConfigurationPackageObject("Config");
        KeyedCollection<string, ConfigurationProperty> parameters = configPackage.Settings.Sections["MyConfigSection"].Parameters;

        JobHostConfiguration config = new JobHostConfiguration();
        config.DashboardConnectionString = parameters["AzureWebJobsDashboard"].Value;
        config.StorageConnectionString = parameters["AzureWebJobsStorage"].Value;
        config.Queues.BatchSize = 10;
        config.Queues.MaxDequeueCount = 8;
        config.Queues.MaxPollingInterval = TimeSpan.FromSeconds(30);
        var host = new JobHost(config);
        host.CallAsync(typeof(TestStatelessService).GetMethod("ProcessMethod"), cancellationToken);
        host.RunAndBlock();
    }

    [NoAutomaticTrigger]
    public async Task ProcessMethod(CancellationToken cancellationToken)
    {
        long iterations = 0;
        while (true)
        {
            cancellationToken.ThrowIfCancellationRequested();

            ServiceEventSource.Current.ServiceMessage(this, "Working-{0}", ++iterations);

            await Task.Delay(TimeSpan.FromSeconds(1), cancellationToken);
        }
    }

    [Timeout("00:03:00")]
    public static void ProcessNotificationsInQueue([QueueTrigger("newnotificationqueue")] Notification notification)
    {
       //Do something 
    }
}

【问题讨论】:

    标签: c# azure-service-fabric azure-webjobs


    【解决方案1】:

    host.CallAsync(typeof(TestStatelessService).GetMethod("ProcessMethod"), cancelToken)

    请注意TestStatelessService类没有定义无参数构造函数,所以你可以将ProcessMethod函数标记为静态。

    根据您的描述,我按照tutorial 创建了一个 Azure Service Fabric 应用程序。根据您的代码,我在我的 Service Fabric 应用程序中成功测试了 WebJob SDK。这是我的代码示例,请尝试找出是否适合您。

    TestStatelessService.cs

    /// <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)
    {
        ConfigurationPackage configPackage = this.Context.CodePackageActivationContext.GetConfigurationPackageObject("Config");
        KeyedCollection<string, ConfigurationProperty> parameters = configPackage.Settings.Sections["MyConfigSection"].Parameters;
    
        JobHostConfiguration config = new JobHostConfiguration();
        config.DashboardConnectionString = parameters["AzureWebJobsDashboard"].Value;
        config.StorageConnectionString = parameters["AzureWebJobsStorage"].Value;
        config.Queues.BatchSize = 10;
        config.Queues.MaxDequeueCount = 8;
        config.Queues.MaxPollingInterval = TimeSpan.FromSeconds(30);
        var host = new JobHost(config);
        host.CallAsync(typeof(TestStatelessService).GetMethod("ProcessMethod"),cancellationToken);
        host.RunAndBlock();
    }
    
    [NoAutomaticTrigger]
    public static async Task ProcessMethod(CancellationToken cancellationToken)
    {
        long iterations = 0;
        while (true)
        {
            cancellationToken.ThrowIfCancellationRequested();
            //log
            Trace.TraceInformation(">>[{0}]ProcessMethod Working-{1}",DateTime.UtcNow.ToString("yyyy-MM-dd HH:mm:ss"),++iterations);
            //sleep for 5s
            await Task.Delay(TimeSpan.FromSeconds(5), cancellationToken);
        }
    }
    
    [Timeout("00:03:00")]
    public static void ProcessNotificationsInQueue([QueueTrigger("newnotificationqueue")] CloudQueueMessage notification)
    {
        Trace.TraceInformation(">ProcessNotificationsInQueue invoked with notification:{0}", notification.AsString);
    }
    

    结果

    尽管应用程序仍在运行,但应用程序的“健康状况”在 Service Fabric Explorer 中设置为“错误”。

    请尝试调试你这边的代码,找出详细的错误。

    【讨论】:

    • 谢谢@布鲁斯。缺少的静态是导致崩溃的原因。将 ProcessMethod 标记为静态后,调用两个函数都没有任何问题。
    • @Bruce 我尝试了确切的解决方案,但我的控制没有转到 ProcessMethod 函数。
    • 得到了解决方案。您需要将 TestStatelessService 类声明为 public。默认情况下,创建的服务会为您提供内部类。
    猜你喜欢
    • 2016-12-08
    • 2021-09-14
    • 1970-01-01
    • 2019-06-05
    • 1970-01-01
    • 2017-02-24
    • 2016-09-01
    • 1970-01-01
    • 2020-01-29
    相关资源
    最近更新 更多