在本地托管时从Azure功能访问存储队列

时间:2018-03-07 18:23:41

标签: azure azure-functions

我创建了一个由定时器触发的Azure功能,该定时器连接到存储队列并抓取接下来的几条消息,它每分钟运行一次:

using System;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Host;
using Microsoft.WindowsAzure.Storage;
using Newtonsoft.Json;
using VS.Core.JobRunner;

namespace VS.JobRunner {
    public static class JobRunner {

        [FunctionName("JobRunner")]
        public static void Run([TimerTrigger("0 */1 * * * *")]TimerInfo myTimer, TraceWriter log) {

            var storageAccount = CloudStorageAccount.Parse(
                    "DefaultEndpointsProtocol=https;AccountName=xxxxxxxxx;AccountKey=xxxxxxxxxxxxxxxxxxxxxxxx;EndpointSuffix=core.windows.net");

            var queueClient = storageAccount.CreateCloudQueueClient();
            var queueWait = queueClient.GetQueueReference("jobs-waiting-uat");
            var queueProcessing = queueClient.GetQueueReference("jobs-processing-uat");

            var messages = queueWait.GetMessages(10, TimeSpan.FromSeconds(55));

            foreach (var message in messages) {

                log.Info($"Processing {message.AsString}");

                queueWait.DeleteMessage(message);

                try {
                    var jobMessage = JsonConvert.DeserializeObject<JobMessage>(message.AsString);

                    if (jobMessage.ExecuteTime <= DateTime.Now) {
                        log.Info($"Send message to processing queue.");

                        queueProcessing.AddMessage(message);

                    } else {
                        log.Info($"Requeue message.");
                        queueWait.AddMessage(message);

                    }

                } catch (Exception ex) {
                    log.Error(ex.Message);
                }
            }
        }
    }
}

它部署到Azure没有任何问题,并愉快地运行并做它的事情。但是当我尝试在本地运行它来进行一些测试时,它会失败并显示以下内容:

[07/03/2018 18:09:01] Reading host configuration file 'C:\github\vs\VS.Jobs\VS.JobRunner\bin\UAT\net462\host.json'
[07/03/2018 18:09:01] Host configuration file read:
[07/03/2018 18:09:01] {}
[07/03/2018 18:09:01] Generating 1 job function(s)
[07/03/2018 18:09:01] Starting Host (HostId=vslaptopbg2-470926380, Version=2.0.11415.0, ProcessId=26736, Debug=False, ConsecutiveErrors=0, StartupCount=1, FunctionsExtensionVersion=~1)
[07/03/2018 18:09:01] Found the following functions:
[07/03/2018 18:09:01] VS.JobRunner.JobRunner.Run
[07/03/2018 18:09:01]
Listening on http://localhost:7071/
Hit CTRL-C to exit...
[07/03/2018 18:09:02] Host lock lease acquired by instance ID '0000000000000000000000009A12D146'.
[07/03/2018 18:09:02] Function started (Id=00f03472-4bee-4fe9-a8af-29e0ea4a1e8b)
[07/03/2018 18:09:02] Executing 'JobRunner' (Reason='Timer fired at 2018-03-07T18:09:02.4920152+00:00', Id=00f03472-4bfe-4fe9-a8af-29e0ea4a1e8b)
[07/03/2018 18:09:02] A ScriptHost error has occurred
[07/03/2018 18:09:02] Exception while executing function: JobRunner. VS.JobRunner: Method not found: 'System.Collections.Generic.IEnumerable`1<Microsoft.WindowsAzure.Storage.Queue.CloudQueueMessage> Microsoft.WindowsAzure.Storage.Queue.CloudQueue.GetMessages(Int32, System.Nullable`1<System.TimeSpan>, Microsoft.WindowsAzure.Storage.Queue.QueueRequestOptions, Microsoft.WindowsAzure.Storage.OperationContext)'.
[07/03/2018 18:09:02] Exception while executing function: JobRunner
[07/03/2018 18:09:02] Exception while executing function: JobRunner. VS.JobRunner: Method not found: 'System.Collections.Generic.IEnumerable`1<Microsoft.WindowsAzure.Storage.Queue.CloudQueueMessage> Microsoft.WindowsAzure.Storage.Queue.CloudQueue.GetMessages(Int32, System.Nullable`1<System.TimeSpan>, Microsoft.WindowsAzure.Storage.Queue.QueueRequestOptions, Microsoft.WindowsAzure.Storage.OperationContext)'.
[07/03/2018 18:09:02] Function completed (Failure, Id=00f03472-4bfe-4fe9-a8af-29e0ea4a1e8b, Duration=158ms)
[07/03/2018 18:09:02]
[07/03/2018 18:09:02] Executed 'JobRunner' (Failed, Id=00f03472-4bfe-4fe9-a8af-29e0ea4a1e8b)
[07/03/2018 18:09:02] System.Private.CoreLib: Exception while executing function: JobRunner. VS.JobRunner: Method not found: 'System.Collections.Generic.IEnumerable`1<Microsoft.WindowsAzure.Storage.Queue.CloudQueueMessage> Microsoft.WindowsAzure.Storage.Queue.CloudQueue.GetMessages(Int32, System.Nullable`1<System.TimeSpan>, Microsoft.WindowsAzure.Storage.Queue.QueueRequestOptions, Microsoft.WindowsAzure.Storage.OperationContext)'.
[07/03/2018 18:09:02]   Function had errors. See Azure WebJobs SDK dashboard for details. Instance ID is '00f03472-4bfe-4fe9-a8af-29e0ea4a1e8b'
[07/03/2018 18:09:02] System.Private.CoreLib: Exception while executing function: JobRunner. VS.JobRunner: Method not found: 'System.Collections.Generic.IEnumerable`1<Microsoft.WindowsAzure.Storage.Queue.CloudQueueMessage> Microsoft.WindowsAzure.Storage.Queue.CloudQueue.GetMessages(Int32, System.Nullable`1<System.TimeSpan>, Microsoft.WindowsAzure.Storage.Queue.QueueRequestOptions, Microsoft.WindowsAzure.Storage.OperationContext)'.
[07/03/2018 18:09:02] The next 5 occurrences of the schedule will be:
[07/03/2018 18:09:02] 07/03/2018 18:10:00
[07/03/2018 18:09:02] 07/03/2018 18:11:00
[07/03/2018 18:09:02] 07/03/2018 18:12:00
[07/03/2018 18:09:02] 07/03/2018 18:13:00
[07/03/2018 18:09:02] 07/03/2018 18:14:00
[07/03/2018 18:09:02]
[07/03/2018 18:09:02] Job host started
^CTerminate batch job (Y/N)? y

我猜它错过了对某个地方的Microsoft.WindowsAzure.Storage的引用,但是我在哪里添加这个引用?我已经尝试添加WindowsAzure.Storage nuget包,但它仍然存在错误。

参考

Microsoft.NET.Sdk.Functions v1.0.6
Newtonsoft.Json v11.0.1

更新

我尝试将WindowsAzure.Storage v9.0.1添加到项目中,但这会导致不同的错误:

[08/03/2018 09:47:55] A ScriptHost error has occurred
[08/03/2018 09:47:55] Exception while executing function: JobRunner. VS.JobRunner: Could not load file or assembly 'Microsoft.WindowsAzure.Storage, Version=9.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35'. Could not find or load a specific file. (Exception from HRESULT: 0x80131621). System.Private.CoreLib: Could not load file or assembly 'Microsoft.WindowsAzure.Storage, Version=9.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35'.

2 个答案:

答案 0 :(得分:0)

您显然正在努力应对版本冲突。当引用同一库的多个版本时,Azure函数对问题很敏感。为了避免它们:

  1. Microsoft.NET.Sdk.Functions更新为最新版本。
  2. 将运行时更新为最新版本。
  3. 请勿明确引用任何版本的WindowsAzure.Storage,只应从Microsoft.NET.Sdk.Functions传递参考。

答案 1 :(得分:0)

将我的类库从.Net 2.0转换为.Net 4.6.1(长篇故事!)后,我开始在Azure函数中运行时收到上述错误 - &#34;无法加载文件或程序集&#39; Microsoft.WindowsAzure.Storage,Version = 9.1.0.0,Culture = neutral,PublicKeyToken = 31bf3856ad364e35&#39;。无法找到或加载特定文件。 (来自HRESULT的异常:0x80131621)。 System.Private.CoreLib:无法加载文件或程序集&#39; Microsoft.WindowsAzure.Storage,Version = 9.1.0.0,Culture = neutral,PublicKeyToken = 31bf3856ad364e35&#39;。&#34;

原来使用此库的Azure函数使用的是1.08的.Net SDK NuGet包,它使用的是WindowsAzure.Storage版本7.2.1。但我在我的类库中明确使用了WindowsAzure.Storage版本9.1.0.0(最新的稳定版本总是不行!!!)。

我花了一段时间但发现版本号在配置文件(func.exe.config)中引用了函数;对我来说,这是在C:\ Users \\ AppData \ Local \ Azure.Functions.Cli \ 1.0.9。这里有7.2.1,我的功能也一样,但我的类库有最新版本,所以它抱怨它。

回到我的类库中的旧版本的包,我的功能开始正常工作。希望这可以帮助!